1
0
mirror of https://shylinux.com/x/volcanos synced 2025-04-27 01:28:28 +08:00

Compare commits

..

No commits in common. "master" and "v0.3.9" have entirely different histories.

160 changed files with 8638 additions and 11922 deletions

2
.gitignore vendored
View File

@ -5,4 +5,4 @@ page/can.js
page/can.css page/can.css
page/cache.js page/cache.js
page/cache.css page/cache.css
node_modules/ pack/

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2017-2025 shylinux Copyright (c) 2021 码神
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,2 +1,4 @@
# Volcanos # volcanos
Volcanos 是一个前端框架,通过集群化、模块化、自动化的方式,快速的开发、创建、共享各种应用程序和数据。
volcanos是一个前端框架通过模块化、集群化、自动化快速的创建、共享应用程序和数据。

570
const.js
View File

@ -1,570 +0,0 @@
var kit = {proto: function(sub, sup) { return sub.__proto__ = sup, sub },
Dict: function() { var res = {}, arg = arguments; for (var i = 0; i < arg.length; i += 2) { var key = arg[i]
if (typeof key == "object") { i--
if (key.length == undefined) {
for (var k in key) { res[k] = key[k] }
} else {
for (var j = 0; j < key.length; j += 2) { res[key[j]] = key[j+1] }
}
} else if (typeof key == "string" && key) { res[key] = arg[i+1] }
} return res },
}
var ice = {
TB: "\t", SP: " ", DF: ":", EQ: "=", AT: "@", QS: "?", PS: "/", PT: ".", FS: ",", NL: "\n", LT: "<", GT: ">",
OK: "ok", TRUE: "true", FALSE: "false", SUCCESS: "success", PROCESS: "process", FAILURE: "failure",
CONTEXTS: "contexts",
HTTP: "http", HOME: "home",
HELP: "help", COPY: "copy",
MAIN: "main", AUTO: "auto",
LIST: "list", BACK: "back",
MODE: "mode", EXEC: "exec",
INFO: "info",
APP: "app", CAN: "can", CAN_PLUGIN: "can._plugin",
OPS: "ops", DEV: "dev", POD: "pod", CTX: "ctx", CMD: "cmd", ARG: "arg",
NFS: "nfs", USR: "usr",
MSG_FIELDS: "fields", MSG_SESSID: "sessid", MSG_METHOD: "method", MSG_DEBUG: "debug",
MSG_DETAIL: "detail", MSG_OPTION: "option", MSG_APPEND: "append", MSG_RESULT: "result",
MSG_HANDLE: "_handle", MSG_UPLOAD: "_upload",
MSG_SOURCE: "_source", MSG_TARGET: "_target",
MSG_ACTION: "_action", MSG_STATUS: "_status",
MSG_PROCESS: "_process", MSG_DISPLAY: "_display", MSG_TOOLKIT: "_toolkit",
MSG_DISPLAY_CSS: "_display_css",
MSG_USERWEB: "user.web", MSG_USERPOD: "user.pod",
MSG_USERROLE: "user.role", MSG_USERNAME: "user.name", MSG_USERNICK: "user.nick", MSG_LANGUAGE: "user.lang",
MSG_TITLE: "sess.title", MSG_THEME: "sess.theme", MSG_BG: "sess.bg", MSG_FG: "sess.fg", MSG_DAEMON: "sess.daemon",
LOG_DISABLE: "log.disable", LOG_TRACEID: "log.id",
MSG_RIVER: "sess.river", MSG_STORM: "sess.storm",
MSG_COST: "sess.cost", MSG_MODE: "sess.mode",
MSG_NODETYPE: "node.type", MSG_NODENAME: "node.name",
TABLE_CHECKBOX: "table.checkbox", FROM_DAEMON: "from.daemon",
PROCESS_REWRITE: "_rewrite",
PROCESS_FIELD: "_field",
PROCESS_AGAIN: "_again",
PROCESS_HOLD: "_hold",
FIELD_PREFIX: "_prefix",
MSG_PREFIX: "_prefix",
MSG_INDEX: "_index",
ErrWarn: "warn: ",
ErrNotLogin: "not login: ",
ErrNotRight: "not right: ",
ErrNotValid: "not valid: ",
ErrNotFound: "not found: ",
}
var ctx = {
CONTEXT: "context", COMMAND: "command", CONFIG: "config", INPUTS: "inputs", FEATURE: "feature",
INDEX: "index", ARGS: "args", STYLE: "style", DISPLAY: "display", ACTION: "action", RUN: "run", CMDS: "cmds",
EXTRA_INDEX: "extra.index", EXTRA_ARGS: "extra.args",
FEATURE_TRANS: "feature._trans",
}
var mdb = {FOREACH: "*", RANDOMS: "%",
DICT: "dict", META: "meta", HASH: "hash", LIST: "list",
SHORT: "short", FIELD: "field", COUNT: "count", TOTAL: "total", LIMIT: "limit",
TIME: "time", ZONE: "zone", ID: "id",
TYPE: "type", NAME: "name", TEXT: "text", ICON: "icon", ICONS: "icons",
KEY: "key", VALUE: "value", STATUS: "status", EXTRA: "extra",
KEYWORD: "keyword",
CURRENT: "current",
SWITCH: "switch",
NOTFOUND: "notfound",
NICK: "nick",
ENABLE: "enable", DISABLE: "disable",
INDEX: "index", ORDER: "order", WEIGHT: "weight",
DATA: "data", VIEW: "view", INFO: "info", HELP: "help",
INPUTS: "inputs", CREATE: "create", REMOVE: "remove", UPDATE: "update",
INSERT: "insert", DELETE: "delete", MODIFY: "modify", SELECT: "select",
PRUNES: "prunes", EXPORT: "export", IMPORT: "import",
SEARCH: "search", ENGINE: "engine", RENDER: "render", PLUGIN: "plugin",
DETAIL: "detail", NORMAL: "normal", PRUNE: "prune",
RENAME: "rename", CANCEL: "cancel", EXPIRE: "expire", FINISH: "finish",
BEGIN_TIME: "begin_time", END_TIME: "end_time",
CANCEL_TIME: "cancel_time", EXPIRE_TIME: "expire_time", FINISH_TIME: "finish_time",
MAIN: "main", PAGE: "page", NEXT: "next", PREV: "prev", LIMIT: "limit", OFFEND: "offend",
QS: ice.QS, AT: ice.AT,
EQ: ice.EQ, FS: ice.FS,
}
var web = {
SERVE: "serve", SPACE: "space", DREAM: "dream", ROUTE: "route",
SHARE: "share", TOKEN: "token", STATS: "stats", COUNT: "count",
SPIDE: "spide", STORE: "store", ADMIN: "admin", MATRIX: "matrix",
GRANT: "grant", CHAT_GRANT: "web.chat.grant",
WORKER: "worker", SERVER: "server", ORIGIN: "origin", VENDOR: "vendor",
GATEWAY: "gateway", ONLINE: "online", OFFLINE: "offline",
SHOW: "show",
FULL: "full", OPEN: "open", LINK: "link", HTTP: "http", DOMAIN: "domain", URL: "url",
DRAW: "draw", PLAY: "play", CLEAR: "clear", RESIZE: "resize", FILTER: "filter",
CANCEL: "cancel", SUBMIT: "submit", CONFIRM: "confirm", REFRESH: "refresh",
UPLOAD: "upload", DOWNLOAD: "download", PREVIEW: "preview", TOIMAGE: "toimage",
CLIENT_NAME: "client.name",
SHARE_CACHE: "/share/cache/", SHARE_LOCAL: "/share/local/", BASIC_LOGIN: "/basic/login",
CHAT_SSO: "/chat/sso/", CHAT_POD: "/chat/pod/", CHAT_CMD: "/chat/cmd/",
CHAT: "chat",
PORTAL: "portal", DESKTOP: "desktop",
STUDIO: "studio", SERVICE: "service",
MESSAGE: "message",
STATUS: "status",
VIMER: "vimer",
WORD: "word",
PLAN: "plan",
CODE_GIT_SEARCH: "web.code.git.search",
CODE_GIT_STATUS: "web.code.git.status",
CODE_GIT_REPOS: "web.code.git.repos",
CODE_COMPILE: "web.code.compile",
CODE_VIMER: "web.code.vimer",
CODE_INNER: "web.code.inner",
CODE_XTERM: "web.code.xterm",
WIKI_DRAW: "web.wiki.draw",
WIKI_WORD: "web.wiki.word",
WIKI_PORTAL: "web.wiki.portal",
CHAT_OAUTH_CLIENT: "web.chat.oauth.client",
CHAT_MACOS_DESKTOP: "web.chat.macos.desktop",
CHAT_MACOS_SESSION: "web.chat.macos.session",
CHAT_MESSAGE: "web.chat.message",
CHAT_HEADER: "web.chat.header",
CHAT_IFRAME: "web.chat.iframe",
CHAT_FAVOR: "web.chat.favor",
CHAT_FLOWS: "web.chat.flows",
TEAM_PLAN: "web.team.plan",
MALL_GOODS: "web.mall.goods",
AT: ice.AT, QS: ice.QS,
}
var aaa = {
USER: "user", AUTH: "auth", SESS: "sess", ROLE: "role",
EMAIL: "email", OFFER: "offer", APPLY: "apply",
LOGIN: "login", LOGOUT: "logout",
BACKGROUND: "background", AVATAR: "avatar", MOBILE: "mobile", SECRET: "secret",
LANGUAGE: "language", ENGLISH: "english", CHINESE: "chinese",
PROVINCE: "province", COUNTRY: "country", CITY: "city",
LONGITUDE: "longitude", LATITUDE: "latitude",
IP: "ip", UA: "ua",
LOCATION: "location",
USERNICK: "usernick", USERNAME: "username", PASSWORD: "password", USERROLE: "userrole", USERZONE: "userzone",
VOID: "void", TECH: "tech", ROOT: "root",
PUBLIC: "public", PRIVATE: "private",
}
var lex = {
SPLIT: "split", PARSE: "parse",
PREFIX: "prefix", SUFFIX: "suffix",
TB: ice.TB, SP: ice.SP, NL: ice.NL,
}
var yac = {
STASK: "stack",
}
var ssh = {
SHELL: "shell",
CLOUD_PROFILE: "ssh.cloud.profile",
}
var gdb = {
SIGNAL: "signal",
}
var tcp = {
CLIENT: "client", SERVER: "server",
PROTO: "proto", HOST: "host", PORT: "port",
SERVICE: "service", HOSTNAME: "hostname",
WIFI: "wifi", SSID: "ssid",
LOCALHOST: "localhost",
DIAL: "dial",
DIRECT: "direct", SEND: "send", RECV: "recv",
}
var nfs = {
DIR: "dir", CAT: "cat", DEFS: "defs", PACK: "pack", TRASH: "trash", DIR_ROOT: "dir_root",
COPY: "copy", EDIT: "edit", SAVE: "save", LOAD: "load", FIND: "find", GREP: "grep", TAGS: "tags",
PATH: "path", FILE: "file", LINE: "line", SIZE: "size",
MODULE: "module",
SOURCE: "source",
TARGET: "target",
BINARY: "binary",
SCRIPT: "script",
CLONE: "clone",
REPOS: "repos",
BRANCH: "branch",
VERSION: "version",
TEMPLATE: "template", SUBJECT: "subject", CONTENT: "content",
REPLACE: "replace", FROM: "from", TO: "to",
RECENT: "recent", PUSH: "push", PULL: "pull",
IMAGE: "image",
_JS: ".js", _CSS: ".css",
JS: "js", SVG: "svg", CSS: "css", HTML: "html",
GO: "go", SH: "sh", SHY: "shy", CSV: "csv", JSON: "json",
TXT: "txt", PNG: "png", WEBM: "webm",
PWD: "./", SRC: "src/", SRC_MAIN_ICO: "src/main.ico",
SRC_TEMPLATE: "src/template/",
SRC_DOCUMENT: "src/document/",
USR_LEARNING_PORTAL: "usr/learning/portal/",
USR: "usr/", USR_LOCAL_WORK: "usr/local/work/",
USR_WEBSOCKET: "usr/websocket/", USR_GO_QRCODE: "usr/go-qrcode/", USR_GO_GIT: "usr/go-git/",
USR_ICONS: "usr/icons/", USR_GEOAREA: "usr/geoarea/", USR_PROGRAM: "usr/program/",
USR_INTSHELL: "usr/intshell/", USR_VOLCANOS: "usr/volcanos/", USR_LEARNING: "usr/learning/",
USR_NODE_MODULES: "usr/node_modules/",
USR_ICONS_ICEBERGS: "usr/icons/icebergs.jpg",
USR_ICONS_VOLCANOS: "usr/icons/volcanos.jpg",
V: "/v/",
M: "/m/",
P: "/p/",
X: "/x/",
S: "/s/",
C: "/c/",
REQUIRE: "/require/", REQUIRE_MODULES: "/require/modules/",
SHARE_CACHE: "/share/cache/", SHARE_LOCAL: "/share/local/",
WIKI_PORTAL: "/wiki/portal/",
CHAT_RIVER: "/chat/river/", CHAT_ACTION: "/chat/action/",
DF: ice.DF, PS: ice.PS, PT: ice.PT,
BACKGROUND_JPG: "usr/icons/background.jpg",
AVATAR_JPG: "usr/icons/avatar.jpg",
}
var cli = {
RUNTIME: "runtime", SYSTEM: "system", DAEMON: "daemon",
BEGIN: "begin", END: "end", START: "start", RESTART: "restart", STOP: "stop", OPEN: "open", CLOSE: "close",
PID: "pid",
OPENS: "opens", BUILD: "build", ORDER: "order", DELAY: "delay", REBOOT: "reboot",
PLAY: "play", STEP: "step", DONE: "done", COST: "cost", FROM: "from", PWD: "pwd",
QRCODE: "qrcode", COLOR: "color", BLACK: "black", WHITE: "white", BLUE: "blue", RED: "red", GRAY: "gray", CYAN: "cyan", GREEN: "green", PURPLE: "purple", YELLOW: "yellow",
MAGENTA: "magenta", SILVER: "silver", ALICEBLUE: "aliceblue", TRANSPARENT: "transparent",
LINUX: "linux", DARWIN: "darwin", WINDOWS: "windows",
XTERM: "xterm",
SH: "sh",
}
var log = {
INFO: "info", WARN: "warn", ERROR: "error", DEBUG: "debug", TRACE: "trace",
}
var code = {
FAVOR: "favor", XTERM: "xterm", INNER: "inner", VIMER: "vimer",
WEBPACK: "webpack", BINPACK: "binpack", AUTOGEN: "autogen", COMPILE: "compile", PUBLISH: "publish", UPGRADE: "upgrade",
TEMPLATE: "template", COMPLETE: "complete", NAVIGATE: "navigate", CURRENT: "current",
STATUS: "status", PULL: "pull", PUSH: "push",
INSTALL: "install",
COMMENT: "comment", KEYWORD: "keyword", DATATYPE: "datatype", PACKAGE: "package",
FUNCTION: "function", CONSTANT: "constant", STRING: "string", NUMBER: "number", BOOLEAN: "boolean",
OBJECT: "object", ARRAY: "array", UNDEFINED: "undefined",
META: "Meta", ALT: "Alt", CONTROL: "Control", SHIFT: "Shift", TAB: "Tab", ESCAPE: "Escape", ENTER: "Enter",
CMD: "Cmd", CTRL: "Ctrl", SPACE: "Space", BACKSPACE: "Backspace", ESC: "Esc", PS: "/",
}
var wiki = {
DRAW: "draw", WORD: "word", PORTAL: "portal",
FEEL: "feel",
TITLE: "title", BRIEF: "brief", REFER: "refer", SPARK: "spark", SHELL: "shell",
ORDER: "order", TABLE: "table", CHART: "chart", IMAGE: "image", VIDEO: "video",
FIELD: "field", LOCAL: "local", PARSE: "parse",
NAVMENU: "navmenu", PREMENU: "premenu", CONTENT: "content",
STORY_ITEM: ".story", H2: "h2.story", H3: "h3.story",
}
var chat = {
LIB: "lib", PAGE: "page", PANEL: "panel", PLUGIN: "plugin", STORY: "story", PLUG: "plug",
TOAST: "toast", CARTE: "carte", INPUT: "input", UPLOAD: "upload", CONTEXTS: "contexts",
LAYOUT: "layout", PROJECT: "project", CONTENT: "content", DISPLAY: "display", PROFILE: "profile", ACTIONS: "actions",
TITLE: "title", THEME: "theme", BLACK: "black", WHITE: "white", PRINT: "print", LIGHT: "light", DARK: "dark",
SHARE: "share", RIVER: "river", STORM: "storm", FIELD: "field", TOOL: "tool",
STATE: "state", MENUS: "menus", SSO: "sso", LOCATION: "location", IFRAME: "iframe", DESKTOP: "desktop",
OUTPUT: "output", SIMPLE: "simple", FLOAT: "float", FULL: "full", CMD: "cmd",
MESSAGE: "message", REQUEST: "request", RESPONSE: "response",
MATRIX: "matrix",
TUTOR: "tutor",
FLOWS: "flows",
ADMIN: "admin",
HEADER: "Header", ACTION: "Action", FOOTER: "Footer",
libs: ["base.js", "core.js", "date.js", "misc.js", "page.js", "user.js"].map(function(p) { return "/lib/"+p }),
panel_list: [{name: "Header", style: "head"}, {name: "River", style: "left"}, {name: "Action", style: "main"}, {name: "Search", style: "auto"}, {name: "Footer", style: "foot"}],
plugin_list: ["state.js", "input.js", "table.js",
"input/key.js",
"input/date.js",
].concat(navigator.userAgent.indexOf("Mobile") > -1? []: [
"story/json.js",
"story/stats.js",
"story/spides.js",
"story/trends.js",
"local/code/xterm.js",
"local/code/vimer.js",
"local/code/inner.js",
"local/code/inner/syntax.js",
"local/wiki/draw/path.js",
"local/wiki/draw.js",
"local/wiki/feel.js",
"local/wiki/word.js",
"local/team/plan.js",
]).map(function(p) { return "/v/plugin/"+p }),
PLUGIN_LOCAL: "/plugin/local/", PLUGIN_STORY: "/plugin/story/", PLUGIN_INPUT: "/plugin/input/",
PLUGIN_INPUT_JS: "/plugin/input.js", PLUGIN_TABLE_JS: "/plugin/table.js", PLUGIN_STATE_JS: "/plugin/state.js",
FRAME_JS: "/v/frame.js",
ONENGINE: "onengine", ONDAEMON: "ondaemon", ONAPPEND: "onappend", ONLAYOUT: "onlayout", ONMOTION: "onmotion", ONKEYMAP: "onkeymap",
ONIMPORT: "onimport", ONACTION: "onaction", ONDETAIL: "ondetail", ONEXPORT: "onexport",
ONSYNTAX: "onsyntax", ONFIGURE: "onfigure", ONPLUGIN: "onplugin", ONINPUTS: "oninputs",
ONSIZE: "onsize", ONMAIN: "onmain", ONLOGIN: "onlogin", ONREMOTE: "onremote", ONSEARCH: "onsearch",
ONRESIZE: "onresize", ONKEYUP: "onkeyup", ONKEYDOWN: "onkeydown", ONMOUSEENTER: "onmouseenter", ORIENTATIONCHANGE: "orientationchange",
ONSTORM_SELECT: "onstorm_select", ONACTION_NOSTORM: "onaction_nostorm", ONACTION_NOTOOL: "onaction_notool", ONACTION_TOUCH: "onaction_touch", ONACTION_CMD: "onaction_cmd", ONACTION_REMOVE: "onaction_remove",
ONOPENSEARCH: "onopensearch", ONSEARCH_FOCUS: "onsearch_focus", ONCOMMAND_FOCUS: "oncommand_focus",
ONTHEMECHANGE: "onthemechange", ONLAYOUT: "onlayout", ONUNLOAD: "onunload", ONWEBPACK: "onwebpack",
ONTOAST: "ontoast", ONSHARE: "onshare", ONPRINT: "onprint", ONDEBUGS: "ondebugs",
_INIT: "_init", _DELAY_INIT: "_delay_init",
_TRANS: "_trans", _STYLE: "_style", _ENGINE: "_engine", _SEARCH: "_search", _NAMES: "_names", _TOAST: "_toast",
PAGES_HOME: "/pages/action/home",
PAGES_DREAM: "/pages/action/dream",
PAGES_DESKTOP: "/pages/action/desktop",
PAGES_MY: "/pages/action/my",
PAGES_SEARCH: "/pages/action/search",
PAGES_ACTION: "/pages/action/action",
PAGES_INSERT: "/pages/insert/insert",
PAGES_RIVER: "/pages/river/river",
PAGES_GRANT: "/pages/web-chat/grant",
WX_LOGIN_SESS: "/chat/wx/login/action/sess",
WX_LOGIN_USER: "/chat/wx/login/action/user",
WX_LOGIN_SCAN: "/chat/wx/login/action/scan",
API_HEADER: "/chat/header/",
API_SEARCH: "/chat/search/",
API_ACTION: "/chat/action/",
}
var team = {
TASK: "task", PLAN: "plan", ASSET: "asset",
BEGIN_TIME: "begin_time", END_TIME: "end_time",
LONG: "long", YEAR: "year", MONTH: "month", WEEK: "week", DAY: "day", HOUR: "hour",
TASK_POD: "task.pod", TASK_ZONE: "task.zone", TASK_ID: "task.id",
}
var mall = {
GOODS: "goods", PRICE: "price", COUNT: "count", UNITS: "units", AMOUNT: "amount",
ASSET: "asset", SALARY: "salary",
}
var http = {
GET: "GET", PUT: "PUT", POST: "POST", DELETE: "DELETE",
Accept: "Accept", ContentType: "Content-Type", ApplicationJSON: "application/json", ApplicationFORM: "application/x-www-form-urlencoded",
}
var html = {
value: {
PROJECT_WIDTH: 230, RIVER_WIDTH: 230,
FLOAT_HEIGHT: 480, FLOAT_WIDTH: 1200,
PLUGIN_PADDING: 0, PLUGIN_MARGIN: 0,
IFRAME_HEIGHT: 420,
HEADER_HEIGHT: 48, ACTION_HEIGHT: 32, STATUS_HEIGHT: 32,
QRCODE_HEIGHT: 363, QRCODE_WIDTH: 360,
CARD_HEIGHT: 160, CARD_WIDTH: 280,
STORY_HEIGHT: 480,
PLUG_HEIGHT: 480, PLUG_WIDTH: 800,
DESKTOP_HEIGHT: 684, DESKTOP_WIDTH: 1200,
DESKTOP_MENU_HEIGHT: 25,
ACTION_BUTTON: 3, TABLE_BUTTON: 5, CARD_BUTTON: 5,
RIVER_MARGIN: 80, ACTION_MARGIN: 200,
ORDER_SHOW_LIMIT: 30, ORDER_SHOW_DELAY: 150,
CODE_FONT_SIZE: 14, CODE_LINE_HEIGHT: 20,
},
STORY: "story",
FIELDSET: "fieldset", LEGEND: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status",
OPTION_ARGS: "select.args,input.args,textarea.args", INPUT_ARGS: "input.args,textarea.args", INPUT_BUTTON: "input[type=button]", INPUT_FILE: "input[type=file]",
FORM_OPTION: "form.option", DIV_ACTION: "div.action", DIV_OUTPUT: "div.output", DIV_STATUS: "div.status",
FIELDSET_HEAD: "fieldset.head", FIELDSET_FOOT: "fieldset.foot", FIELDSET_LEFT: "fieldset.left", FIELDSET_MAIN: "fieldset.main",
FIELDSET_PANEL: "fieldset.panel", FIELDSET_PLUGIN: "fieldset.plugin", FIELDSET_STORY: "fieldset.story", FIELDSET_PLUG: "fieldset.plug",
FIELDSET_FLOAT: "fieldset.float", FIELDSET_INPUT: "fieldset.input",
FIELDSET_OUTPUT: "fieldset.output",
H1: "h1", H2: "h2", H3: "h3", UL: "ul", OL: "ol", LI: "li", BR: "br", HR: "hr",
A: "a", SPAN: "span", CODE: "code", DIV: "div",
SVG: "svg", IMG: "img", IMAGE: "image", VIDEO: "video", AUDIO: "audio", CANVAS: "canvas", IFRAME: "iframe",
WSS: "wss", WEBVIEW: "webview", CHROME: "chrome", WINDOWS: "windows", MOBILE: "mobile", LANDSCAPE: "landscape",
BODY: "body", FORM: "form", LABEL: "label", TITLE: "title", INNER: "inner", SPACE: "space", CLICK: "click",
SELECT: "select", INPUT: "input", TEXT: "text", FILE: "file", TEXTAREA: "textarea", BUTTON: "button", CHECKBOX: "checkbox", MULTIPLE: "multiple",
CANCEL: "cancel", SUBMIT: "submit", UPLOAD: "upload", USERNAME: "username", PASSWORD: "password",
CONFIRM: "confirm", CLOSE: "close", CLICK: "click", FOCUS: "focus", BLUR: "blur",
TABLE: "table", THEAD: "thead", TBODY: "tbody", TR: "tr", TH: "th", TD: "td",
HEADER: "header", NAV: "nav", MAIN: "main", ASIDE: "aside", FOOTER: "footer",
NEED: "need", MUST: "must",
TAIL: "tail",
FAVICON: "favicon",
BACKGROUND_COLOR: "background-color", COLOR: "color",
PADDING: "padding", BORDER: "border", MARGIN: "margin", MARGIN_TOP: "margin-top", MARGIN_X: "margin-x", MARGIN_Y: "margin-y",
HEIGHT: "height", WIDTH: "width", MIN_HEIGHT: "min-height", MAX_HEIGHT: "max-height", MIN_WIDTH: "min-width", MAX_WIDTH: "max-width",
DISPLAY: "display", BLOCK: "block", NONE: "none", OVERFLOW: "overflow", HIDDEN: "hidden", SCROLL: "scroll", FLOAT: "float", CLEAR: "clear", BOTH: "both",
LEFT: "left", TOP: "top", RIGHT: "right", BOTTOM: "bottom",
SCROLLBAR: "scrollbar", VERTICAL: "vertical", HORIZON: "horizon",
VISIBILITY: "visibility", TRANSPARENT: "transparent",
NOTICE: "notice", DANGER: "danger", PICKER: "picker",
CURSOR: "cursor", POINTER: "pointer", CROSSHAIR: "crosshair", MOVE: "move", RESIZE: "resize",
SIZE: "size", OPACITY: "opacity", VISIBLE: "visible",
CLASS: "class", DARK: "dark", LIGHT: "light", WHITE: "white", BLACK: "black",
FILTER: "filter", TOGGLE: "toggle", EXPAND: "expand", SPEED: "speed", HOVER: "hover", HOVER_SELECT: "hover,select",
ICONS: "icons",
FULL: "full",
ICON: "icon",
VALUE: "value",
PROCESS: "process",
TOIMAGE: "toimage", NOT_HIDE: ":not(.hide)",
CONTAINER: "container", FLEX: "flex", FLOW: "flow",
MORE: "more",
PAGE: "page", TABS: "tabs", MENU: "menu", NODE: "node", PLUG: "plug",
ZONE: "zone", LIST: "list", ITEM: "item", NAME: "name", ICON: "icon", VIEW: "view",
HEAD: "head", LEFT: "left", MAIN: "main", FOOT: "foot", AUTO: "auto", SHOW: "show", HIDE: "hide",
PLUGIN: "plugin", LAYOUT: "layout", PROJECT: "project", DISPLAY: "display", PROFILE: "profile", CONTENT: "content", TABVIEW: "tabview",
DIV_PAGE: "div.page", DIV_TABS: "div.tabs", DIV_PATH: "div.path", DIV_CODE: "div.code", DIV_PLUG: "div.plug",
DIV_ZONE: "div.zone", DIV_LIST: "div.list", DIV_ITEM: "div.item", DIV_NAME: "div.name", SPAN_ITEM: "span.item", SPAN_ICON: "span.icon", SPAN_NAME: "span.name",
DIV_CONTENT: "div.content", TABLE_CONTENT: "table.content", TABLE_LAYOUT: "table.layout", DIV_TOGGLE: "div.toggle",
DIV_LAYOUT: "div.layout", DIV_LAYOUT_HEAD: "div.layout.head", DIV_LAYOUT_FOOT: "div.layout.foot", DIV_LAYOUT_LEFT: "div.layout.left",
DIV_FLOAT: "div.float", DIV_TOAST: "div.toast", DIV_CARTE: "div.carte",
DESKTOP: "desktop", DIV_DESKTOP: "div.desktop", DIV_EXPAND: "div.expand",
ITEM_CARD: "item.card",
DIV_ITEM_TEXT: "div.item.text",
DIV_ITEM_SELECT: "div.item.select",
DIV_TABS_SELECT: "div.tabs.select",
DIV_PROFILE: "div.profile", DIV_DISPLAY: "div.display",
IMAGE_PNG: "image/png", VIDEO_WEBM: "video/webm",
BACKGROUND_JPG: "usr/icons/background.jpg",
BACKGROUND_PNG: "usr/icons/background.png",
AVATAR_JPG: "usr/icons/avatar.jpg",
}
var icon = {
CHEVRON_DOWN: "bi bi-chevron-down", SEARCH: "bi bi-search", TERMINAL: "bi bi-terminal", SUN: "bi bi-sun", MOON: "bi bi-moon-stars",
portal: "bi bi-globe", desktop: "bi bi-window-desktop", admin: "bi bi-window-sidebar",
dream: "bi bi-box", space: "bi bi-box", store: "bi bi-shop",
word: "bi bi-book", repos: "bi bi-git", vimer: "bi bi-bug", build: "bi bi-tools", xterm: "bi bi-terminal", shell: "bi bi-terminal",
stats: "bi bi-card-list",
matrix: "bi bi-grid-3x3-gap",
feel: "bi bi-images",
plan: "bi bi-calendar4-week",
status: "bi bi-git",
access: "bi bi-file-earmark-lock",
sso: "bi bi-shield-check", login: "bi bi-person-check", token: "bi bi-key",
username: "bi bi-person-gear", nodename: "bi bi-globe",
password: "bi bi-shield-lock",
database: "bi bi-database",
table: "bi bi-table",
domain: "bi bi-globe",
origin: "bi bi-globe",
server: "bi bi-globe",
vendor: "bi bi-shop",
full: "bi bi-arrows-fullscreen", open: "bi bi-box-arrow-up-right",
more: "bi bi-three-dots-vertical", actions: "bi bi-three-dots",
search: "bi bi-search", favor: "bi bi-star",
plugs: "bi bi-tools",
tools: "bi bi-grid",
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",
detail: "bi bi-file-earmark-text",
enable: "bi bi-toggle-off", disable: "bi bi-toggle-on",
expire: "bi bi-clock-history",
name: "bi bi-sort-alpha-down",
time: "bi bi-clock-history",
size: "bi bi-calculator",
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",
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",
"begin_time": "bi bi-clock-history", "end_time": "bi bi-clock-history",
// scale: "bi bi-arrows-fullscreen",
pie: "bi bi-pie-chart",
tags: "bi bi-tags",
version: "bi bi-tags",
compile: "bi bi-tools",
publish: "bi bi-send-check",
upgrade: "bi bi-rocket-takeoff",
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",
binary: "bi bi-disc",
images: "bi bi-disc",
qrcode: "bi bi-qr-code",
main: "bi bi-house-door", top: "bi bi-globe",
configs: "bi bi-gear", config: "bi bi-gear", conf: "bi bi-gear", logs: "bi bi-calendar4-week", tag: "bi bi-tags",
data: "bi bi-database",
branch: "bi bi-diagram-3", commit: "bi bi-hash",
message: "bi bi-wechat",
address: "bi bi-pin-map",
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",
record: "bi bi-record-circle", record1: "bi bi-images", record2: "bi bi-record-circle",
"client.name": "bi bi-globe",
machine: "bi bi-pc-display",
host: "bi bi-pc-display",
port: "bi bi-hash",
arch: "bi bi-cpu", os: "bi bi-ubuntu",
cpu: "bi bi-cpu",
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",
notifications: "bi bi-chat-right-text",
play: "bi bi-play-circle",
app: "bi bi-box-arrow-down-left",
dev: "bi bi-git",
"Close": "bi bi-x-lg",
"Close Other": "bi bi-x-lg",
"Rename Tabs": "bi bi-pencil-square",
}
var svg = {
GROUP: "group", PID: "pid", GRID: "grid",
FIGURE: "figure", DATA: "data", SHIP: "ship", TRANS: "trans",
GO: "go",
SHAPE: "shape", TEXT: "text", RECT: "rect", LINE: "line", CIRCLE: "circle", ELLIPSE: "ellipse", BLOCK: "block",
STROKE_WIDTH: "stroke-width", STROKE: "stroke", FILL: "fill", FONT_SIZE: "font-size", FONT_FAMILY: "font-family", TEXT_ANCHOR: "text-anchor",
G: "g", X: "x", Y: "y", R: "r", RX: "rx", RY: "ry", CX: "cx", CY: "cy", X1: "x1", Y1: "y1", X2: "x2", Y2: "y2",
PATH: "path", PATH2V: "path2v", PATH2H: "path2h",
M: "M", Q: "Q", T: "T",
TEXT_LENGTH: "textLength",
}
try { module.exports = {
kit: kit, ice: ice,
ctx: ctx, mdb: mdb, web: web, aaa: aaa,
lex: lex, yac: lex, ssh: ssh, gdb: gdb,
tcp: tcp, nfs: nfs, cli: cli, log: log,
code: code, wiki: wiki, chat: chat, team: team, mall: mall,
http: http, html: html, icon: icon, svg: svg
} } catch (e) {}
var UID = "uid"

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

2168
frame.js

File diff suppressed because it is too large Load Diff

1108
index.css

File diff suppressed because it is too large Load Diff

View File

@ -1,184 +1,229 @@
Volcanos("base", { Volcanos("base", {help: "数据类型",
Int: function(val, def) { return parseInt(val)||def||0 }, Int: function(val, def) { return parseInt(val)||def||0 },
Min: function(val, min, max) {
if (max < min) { max = min }
if (val == "max") { return max }
return val < min? min: val > max? max: val
},
Max: function(val, max, min) {
if (min > max) { min = max }
return val > max? max: val < min? min: val
},
Obj: function(val, def) { Obj: function(val, def) {
try { try {
if (typeof val == code.STRING) { if (val == "") { return def } val = JSON.parse(val) } if (typeof val == lang.STRING) { if (val == "") { return def } val = JSON.parse(val) }
if (typeof val == code.NUMBER) { return [val] }
if (val.length > 0) { return val } for (var k in val) { return val } return def if (val.length > 0) { return val } for (var k in val) { return val } return def
} catch (e) { return typeof val == code.STRING && val.split(mdb.FS) || def } } catch (e) { return val && val.split && val.split(ice.FS) || def }
}, },
CopyStr: function(to, from) { if (!from) { return to } Copy: function(to, from) {
for (var k in from) { typeof from[k] == code.STRING && (to[k] = from[k]) } if (arguments.length == 2) {
for (var k in from) { to[k] = from[k] }
return to
}
for (var i = 2; i < arguments.length; i++) {
var k = arguments[i]; to[k] = from[k]
}
return to return to
}, },
Copy: function(to, from, merge) { if (!from) { return to } Eq: function(to, from) { var call = arguments.callee
if (arguments.length == 2 || typeof merge == code.BOOLEAN) { for (var k in from) { if (k == undefined) { continue } if (typeof to != typeof from) { return false }
if (merge && to.hasOwnProperty(k) && to[k] != undefined && to[k] != "") { continue } if (typeof to == lang.OBJECT) {
if (from[k] === "") { delete(to[k]) } else { to[k] = from[k] } if (to.length != from.length) { return false }
} return to } for (var i = 2; i < arguments.length; i++) { var k = arguments[i]; to[k] = from[k] } return to for (var i = 0; i < to.length; i++) {
}, if (!call(to[i], from[i])) { return false }
Eq: function(to, from, skip) { var call = arguments.callee; if (typeof to != typeof from) { return false } }
if (typeof to == code.OBJECT) { if (to.length != from.length) { return false } for (var k in to) {
for (var i = 0; i < to.length; i++) { if (!call(to[i], from[i])) { return false } } if (!call(to[k], from[k])) { return false }
for (var k in to) { if (k.indexOf("_") == 0) { continue } }
if (k != skip && !call(to[k], from[k])) { return false } return true
} return true }
} return to === from return to === from
}, },
Ext: function(path) { Ext: function(path) { return (path.split(ice.PS).pop().split(ice.PT).pop()).toLowerCase() },
return (path||"").split("?")[0].split("#")[0].split("/").pop().split(".").pop().toLowerCase() Path: function(path) { var res = ""
}, for (var i = 0; i < arguments.length; i++) {
Dir: function(path) { return path.endsWith(nfs.PS)? path: path.slice(0, path.lastIndexOf(nfs.PS)+1) }, res += (arguments[i][0]==ice.PS || res=="" || res[res.length-1]==ice.PS? "": ice.PS) + arguments[i].trim()
}
Path: function(path) { var res = "", arg = arguments; for (var i = 0; i < arg.length; i++) { if (!arg[i]) { continue }
res += (arg[i][0]==nfs.PS || res=="" || res[res.length-1]==nfs.PS? "": nfs.PS) + arg[i].trim()
} return res },
Args: function() { var res = [], arg = arguments; function encode(k, v) { k && v != undefined && v != null && res.push(encodeURIComponent(k)+mdb.EQ+encodeURIComponent(v)) }
for (var i = 0; i < arg.length; i += 2) { if (typeof arg[i] == code.OBJECT) {
if (arg[i].length > 0) { for (var j = 0; j < arg[i].length; j += 2) { encode(arg[i][j], arg[i][j+1]) } } else { for (var k in arg[i]) { encode(k, arg[i][k]) } } i--
} else { encode(arg[i], arg[i+1]) } } return res.join("&")
},
_parse: function(url, res) { var list = url.split("#")[0].split(ice.QS); res = res||{}, res._origin = list[0]
list[1] && list[1].split("&").forEach(function(item) { var ls = item.split(mdb.EQ); res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1]) })
return res return res
}, },
MergeURL: function(url) { var arg = this._parse(url); delete(arg._origin); for (var i = 1; i < arguments.length; i += 2) { delete(arg[arguments[i]]) } Args: function() { var res = []
var arg = this.Args.apply(this, [arg].concat(Array.prototype.slice.call(arguments, 1))); return url.split(ice.QS)[0]+(arg? ice.QS+arg: "") for (var i = 0; i < arguments.length; i += 2) {
}, if (typeof arguments[i] == lang.OBJECT) {
ParseURL: function(url) { var res = this._parse(url); res.link = url, res.origin = res._origin; return res }, for (var k in arguments[i]) { res.push(encodeURIComponent(k)+"="+encodeURIComponent(arguments[i][k])) }
ParseJSON: function(str) { var res; if (typeof str == code.OBJECT) { return str } i--; continue
if (str.indexOf(ice.HTTP) == 0) { var res = this._parse(str, {type: web.LINK, name: "", text: str}); return res.name = res._origin.split("://").pop().split(nfs.PS)[0], res } } else if (arguments[i]) {
try { res = JSON.parse(str), res.text = res.text||str, res.type = res.type||nfs.JSON } catch (e) { res = {type: mdb.TEXT, text: str} } return res res.push(encodeURIComponent(arguments[i])+"="+encodeURIComponent(arguments[i+1]))
},
ParseSize: function(size) { size = (size||"").toLowerCase().split(" ")[0]
if (size.endsWith("tb") || size.endsWith("t")) { return parseFloat(size) * this._unit.t }
if (size.endsWith("gb") || size.endsWith("g") || size.endsWith("gib")) { return parseFloat(size) * this._unit.g }
if (size.endsWith("mb") || size.endsWith("m") || size.endsWith("mib")) { return parseFloat(size) * this._unit.m }
if (size.endsWith("kb") || size.endsWith("k")) { return parseFloat(size) * this._unit.k }
return parseFloat(size)
}, _unit: {k: 1024, m: 1024*1024, g: 1024*1024*1024, t: 1024*1024*1024*1024},
Size: function(size) { var n = 100, k = this._unit.k, m = this._unit.m, g = this._unit.g, t = this._unit.t
if (size > t) { return parseFloat(size/t).toFixed(2)+"T" }
if (size > g) { return parseFloat(size/g).toFixed(2)+"G" }
if (size > m) { return parseFloat(size/m).toFixed(2)+"M" }
if (size > k) { return parseFloat(size/k).toFixed(2)+"K" }
return size
},
Number: function(d, n) { var res = []
while (d > 0) { res.push(d%10); d = parseInt(d/10); n-- } while (n > 0) { res.push("0"); n-- }
return res.reverse(), res.join("")
},
Format: function(obj) { return JSON.stringify(obj) },
Simple: function() { var res = []; for (var i = 0; i < arguments.length; i++) { var val = arguments[i]; switch (typeof val) {
case code.OBJECT: if (val.length > 0) { res = res.concat(val); break }
for (var k in val) { k && val[k] && res.push(k, val[k]) } break
default: res.push(val)
} } return res },
AddUniq: function(list, value) { list = list||[], list.indexOf(value) == -1 && list.push(value); return list },
isIn: function(item) { var arg = arguments; for (var i = 1; i < arg.length; i++) {
if (typeof arg[i] == code.OBJECT && arg[i].length > 0 && arg[i].indexOf(item) > -1) { return true }
if (item == arg[i]) { return true }
} },
TimeTrim: function(value) { var prefix = ""
if (!value) { return }
var now = new Date(), year = now.getFullYear()+"-", pre = this.Time(now, "%y-%m-%d ")
if (value.indexOf(pre) == -1) { var list = ["昨天", "前天", "", "", "", "", ""]
for (var i = 0; i < list.length; i++) {
var yestoday = this.Time(new Date(now - (i+1)*24*60*60*1000), "%y-%m-%d ")
if (value.indexOf(yestoday) == 0) {
prefix = (list[i] || ["周日", "周一", "周二", "周三", "周四", "周五", "周六", "周日"][new Date(value.replaceAll("-", "/").split(".")[0]).getDay()])+" ", pre = yestoday; break
}
} }
} }
if (value.indexOf(year) == -1) { return res.join("&")
return value.split(" ")[0] },
MergeURL: function(url) {
var args = {}; (url.split("?")[1]||"").split("&").forEach(function(item) { if (!item) { return }
var ls = item.split("="); args[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1])
})
for (var i = 1; i < arguments.length; i++) {
switch (typeof arguments[i]) {
case lang.STRING: args[arguments[i]] = arguments[i+1], i++; break
case lang.OBJECT:
if (arguments[i].length > 0) {
for (var j = 0; j < arguments[i].length; j += 2) { args[arguments[i][j]] = arguments[i][j] }
} else {
for (var k in arguments[i]) { args[k] = arguments[i][k] }
}
break
}
} }
return prefix+this.trimPrefix(value.split(":").slice(0, 2).join(":"), pre, year) var list = []; for (var k in args) { list.push(encodeURIComponent(k)+"="+encodeURIComponent(args[k])) }
return url.split("?")[0]+(list.length>0? "?"+list.join("&"): "")
},
ParseURL: function(url) { var res = {link: url}
var list = url.split("?"); res["origin"] = list[0]
list[1] && list[1].split("&").forEach(function(item) {
var ls = item.split("="); res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1])
})
return res
},
ParseJSON: function(str) { var res
if (typeof str == lang.OBJECT) { return str }
if (str.indexOf("http") == 0) { var ls = str.split("?")
res = {type: mdb.LINK, name: "", text: str}
res.name = ls[0].split("://").pop().split(ice.PS)[0]
ls[1] && ls[1].split("&").forEach(function(item) { var ls = item.split("=")
res[decodeURIComponent(ls[0])] = decodeURIComponent(ls[1])
})
return res
}
try { res = JSON.parse(str), res.text = res.text||str, res.type = res.type||nfs.JSON
} catch (e) { res = {type: mdb.TEXT, text: str} }
return res
},
ParseSize: function(size) { size = size.toLowerCase()
if (size.endsWith("tb") || size.endsWith("t")) {
return parseInt(size) * 1024 * 1024 * 1024 * 1024
}
if (size.endsWith("gb") || size.endsWith("g")) {
return parseInt(size) * 1024 * 1024 * 1024
}
if (size.endsWith("mb") || size.endsWith("m")) {
return parseInt(size) * 1024 * 1024
}
if (size.endsWith("kb") || size.endsWith("k")) {
return parseInt(size) * 1024
}
return parseInt(size)
},
Size: function(size) { size = parseInt(size)
if (size > 1000000000) {
return parseInt(size/1000000000) + ice.PT + parseInt(size/10000000%100) + "G"
}
if (size > 1000000) {
return parseInt(size/1000000) + ice.PT + parseInt(size/10000%100) + "M"
}
if (size > 1000) {
return parseInt(size/1000) + ice.PT + parseInt(size/10%100) + "K"
}
return size + "B"
},
Number: function(d, n) { var result = []
while (d > 0) { result.push(d%10); d = parseInt(d/10); n-- }
while (n > 0) { result.push("0"); n-- }
return result.reverse(), result.join("")
},
Format: function(obj) { return JSON.stringify(obj) },
Simple: function() { var res = []
for (var i = 0; i < arguments.length; i++) {
var arg = arguments[i]; switch (typeof arguments[i]) {
case lang.NUMBER: res.push(arg); break
case lang.STRING: res.push(arg); break
case lang.OBJECT:
if (arg.length > 0) { res = res.concat(arg); break }
for (var k in arg) { k && arg[k] && res.push(k, arg[k]) }
break
default: res.push(arg);
}
}
return res
},
AddUniq: function(list, value) { list = list||[]; return list.indexOf(value) == -1 && list.push(value), list },
Date: function(time) { var now = new Date()
if (typeof time == lang.STRING && time != "") { var ls = time.split(ice.SP)
var vs = ls[0].split("-")
now.setFullYear(parseInt(vs[0]))
now.setMonth(parseInt(vs[1])-1)
now.setDate(parseInt(vs[2]))
var vs = ls[1].split(":")
now.setHours(parseInt(vs[0]))
now.setMinutes(parseInt(vs[1]))
now.setSeconds(parseInt(vs[2]))
} else if (time) {
now = time
}
return now
}, },
Time: function(time, fmt) { var now = this.Date(time) Time: function(time, fmt) { var now = this.Date(time)
fmt = fmt||"%y-%m-%d %H:%M:%S" var list = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
fmt = fmt||"%H:%M:%S"
fmt = fmt.replace("%y", now.getFullYear()) fmt = fmt.replace("%y", now.getFullYear())
fmt = fmt.replace("%m", this.Number(now.getMonth()+1, 2)) fmt = fmt.replace("%m", this.Number(now.getMonth()+1, 2))
fmt = fmt.replace("%d", this.Number(now.getDate(), 2)) fmt = fmt.replace("%d", this.Number(now.getDate(), 2))
fmt = fmt.replace("%w", ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][now.getDay()]) fmt = fmt.replace("%w", list[now.getDay()])
fmt = fmt.replace("%H", this.Number(now.getHours(), 2)) fmt = fmt.replace("%H", this.Number(now.getHours(), 2))
fmt = fmt.replace("%M", this.Number(now.getMinutes(), 2)) fmt = fmt.replace("%M", this.Number(now.getMinutes(), 2))
fmt = fmt.replace("%S", this.Number(now.getSeconds(), 2)) fmt = fmt.replace("%S", this.Number(now.getSeconds(), 2))
fmt = fmt.replace("%s", this.Number(now.getMilliseconds(), 3))
return fmt return fmt
}, },
Date: function(time) { var now = new Date(); if (typeof time == code.STRING && time != "") { var ls = time.split(lex.SP) TimeAdd: function(t, d) { return new Date(t - t%(24*3600*1000) - 8*3600*1000 + d*24*3600*1000) },
var vs = ls[0].split("-"); now.setFullYear(parseInt(vs[0])), now.setMonth(parseInt(vs[1])-1), now.setDate(parseInt(vs[2])) Duration: function(n) { var res = "", h = 0
var vs = ls[1].split(nfs.DF); now.setHours(parseInt(vs[0])), now.setMinutes(parseInt(vs[1])), now.setSeconds(parseInt(vs[2]))
} else if (time) { now = time } return now },
DateAdd: function(stamp, days) { return new Date(stamp - stamp%(24*3600*1000) - 8*3600*1000 + days*24*3600*1000) },
Duration: function(n) { var res = "", h = 0; n = parseInt(n)
h = parseInt(n/3600000/24), h > 0 && (res += h+"d"), n = n % (3600000*24) h = parseInt(n/3600000/24), h > 0 && (res += h+"d"), n = n % (3600000*24)
h = parseInt(n/3600000), h > 0 && (res += h+"h"), n = n % 3600000 h = parseInt(n/3600000), h > 0 && (res += h+"h"), n = n % 3600000
h = parseInt(n/60000), h > 0 && (res += h+"m"), n = n % 60000 h = parseInt(n/60000), h > 0 && (res += h+"m"), n = n % 60000
h = parseInt(n/1000), h > 0 && (res += h), n = n % 1000 h = parseInt(n/1000), h > 0 && (res += h), n = n % 1000
return res + (n > 0? nfs.PT+this.Number(parseInt(n/10), 2): "") + "s" return res + (n > 0? ice.PT+parseInt(n/10): "") + "s"
}, },
isNight: function() { var now = new Date(); return now.getHours() < 7 || now.getHours() > 17 },
isNumber: function(val) { return typeof val == code.NUMBER }, getValid: function() {
isString: function(val) { return typeof val == code.STRING }, for (var i = 0; i < arguments.length; i++) { var v = arguments[i]
isObject: function(val) { return typeof val == code.OBJECT }, if (typeof v == lang.OBJECT) {
isArray: function(val) { return Array.isArray(val) }, if (v == null) { continue }
isFunc: function(val) { return typeof val == code.FUNCTION }, for (var k in v) { return v }
isUndefined: function(val) { return val == undefined }, if (v.length > 0) { return v }
isNull: function(val) { return val == null }, } else if (typeof v == lang.STRING && v) {
toLast: function(list, value) { if (!list) { return } return v
for (var i = 0; i < list.length-1; i++) { if (list[i] == value) { } else if (v == undefined) {
for (i; i < list.length-1; i++) { list[i] = list[i+1] } continue
list[list.length-1] = value } else {
} } return v
},
getValid: function() { for (var i = 0; i < arguments.length; i++) { var v = arguments[i]
if (typeof v == code.OBJECT) { if (v == null) { continue }
if (v.length > 0) { return v } for (var k in v) { return v }
} else if (typeof v == code.STRING) { if (v == "") { continue } else { return v }
} else if (v == undefined) { continue } else { return v }
} },
replaceAll: function(str) { if (!str) { return str } var arg = arguments; for (var i = 1; i < arg.length; i += 2) { if (!arg[i]) { continue }
if (str.replaceAll) { str = str.replaceAll(arg[i], arg[i+1]); continue }
if (arg[i] && str.replace) { while (str.indexOf(arg[i]) > -1) { str = str.replace(arg[i], arg[i+1]) } }
} return str },
contains: function(str) { var arg = arguments; for (var i = 1; i < arg.length; i++) { if (!arg[i] || str.indexOf(arg[i]) > -1) { return true } } },
capital: function(str) { return str.slice(0, 1).toUpperCase()+str.slice(1) },
beginWith: function(str) {
for (var i = 1; i < arguments.length; i++) {
if (typeof str == code.STRING && str.trim().indexOf(arguments[i]) == 0) { return true }
if (typeof str == code.OBJECT) { var begin = true
for (var j = 0; j < arguments[i].length; j++) {
if (str[j] != arguments[i][j]) { begin = false; break }
} if (begin) { return true }
} }
} }
}, },
endWith: function(str) { var arg = arguments; for (var i = 1; i < arg.length; i++) { if (typeof str == code.STRING && str.lastIndexOf(arg[i]) > 0 && str.lastIndexOf(arg[i]) + arg[i].length == str.length) { return true } } }, isNumber: function(val) { return typeof val == lang.NUMBER },
trimPrefix: function(str, pre) { if (typeof str != code.STRING) { return str } var arg = arguments, callee = arg.callee isString: function(val) { return typeof val == lang.STRING },
if (arg.length > 2) { for (var i = 1; i < arg.length; i++) { str = callee(str, arg[i]) } return str } isObject: function(val) { return typeof val == lang.OBJECT },
if (str.indexOf(pre) == -1) { return str } return str.slice(pre.length) isArray: function(val) { return typeof val == lang.OBJECT && val.length != undefined },
isFunc: function(val) { return typeof val == lang.FUNCTION },
isFunction: function(val) { return typeof val == lang.FUNCTION },
isCallback: function(key, value) { return key.indexOf("on") == 0 && typeof value == lang.FUNCTION },
isUndefined: function(val) { return val == undefined },
isNull: function(val) { return val == null },
replaceAll: function(str) {
for (var i = 1; i < arguments.length; i += 2) { if (!arguments[i]) { continue }
if (str.replaceAll) { str = str.replaceAll(arguments[i], arguments[i+1]); continue }
if (str.replace) { str = str.replace(arguments[i], arguments[i+1]); continue }
}
return str
}, },
trimSuffix: function(str, end, once) { while (str) { var index = str.lastIndexOf(end)
if (index == -1 || index+end.length != str.length) { break } str = str.slice(0, index) random: function(max, min) { min = min||0, parseInt(Math.random()*(max-min))+min },
if (once) { break } isNight: function() { var now = new Date(); return now.getHours() < 7 || now.getHours() > 17 },
} return str }, beginWith: function(str, begin) { return str.trim().indexOf(begin) == 0 },
trim: function(arg) { if (this.isString(arg)) { return arg.trim() } endWith: function(str, end) { return str.lastIndexOf(end) + end.length == str.length },
if (this.isArray(arg)) { for (var i = arg.length-1; i >= 0; i--) { if (!arg[i]) { arg.pop() } else { break } } } return arg trim: function(args) { if (this.isString(args)) { return args.trim() }
if (this.isArray(args)) { for (var i = args.length-1; i >= 0; i--) { if (!args[i]) { args.pop() } else { break } } }
return args
},
trimPrefix: function(str, pre) { if (str.indexOf(pre) == -1) { return str } return str.slice(pre.length) },
trimSuffix: function(str, end) { if (str.indexOf(end) == -1) { return str } return str.slice(0, str.indexOf(end)) },
join: function(list, sp) { return (list||[]).join(sp||ice.SP) },
joins: function(list, inner, outer) {
for (var i = 0; i < list.length; i++) {
list[i] = typeof list[i] == lang.STRING? list[i]: list[i].join(inner||ice.FS)
}
return list.join(outer||ice.SP)
}, },
join: function(list, sp) { return typeof list == code.STRING? list: (list||[]).join(sp||lex.SP) },
joins: function(list, inner, outer) { for (var i = 0; i < list.length; i++) { list[i] = typeof list[i] == code.STRING? list[i]: list[i].join(inner||mdb.FS) } return list.join(outer||lex.SP) },
joinKV: function(list, inner, outer) { var res = []; for (var i = 0; i < list.length-1; i += 2) { res.push(list[i]+(inner||": ")+list[i+1]) } return res.join(outer||lex.SP) },
random: function(max, min) { return min = min||0, parseInt(Math.random()*(max-min))+min },
}) })

View File

@ -1,148 +1,179 @@
Volcanos("core", { Volcanos("core", {help: "数据结构",
Defer: function(cb) { var defer = []; cb(defer) Keys: shy("连接器", function() { var list = []
while (defer.length > 0) { defer.pop()() } for (var i = 0; i < arguments.length; i++) { var v = arguments[i]
}, switch (typeof v) {
Keys: function() { var list = [] case lang.OBJECT: for (var j = 0; j < v.length; j++) { list.push(v[j]) } break
for (var i = 0; i < arguments.length; i++) { var v = arguments[i]; switch (typeof v) { case lang.FUNCTION: v = v()
case code.OBJECT: for (var j = 0; j < v.length; j++) { v[j] && list.push(v[j]) } break default: v && list.push(v+"")
case code.NUMBER: list.push(v+""); break
case code.FUNCTION: v = v()
default: v && list.push(v+"")
} } return list.join(nfs.PT)
},
Value: function(data, key, value) { if (data == undefined) { return } if (key == undefined) { return data }
if (typeof key == code.OBJECT) { if (key.length != undefined) { key = key.join(nfs.PT) } else { for (var k in key) { arguments.callee.call(this, data, k, key[k]) } return data } }
if (value != undefined) { var _node = data, keys = key.split(nfs.PT)
for (var i = 0; i < keys.length; i++) { var _next = _node[keys[i]]||{}; _node[keys[i]] = _next
if (i < keys.length - 1) { _node = _next } else {
if (value === "") {
delete(_node[keys[i]])
} else {
_node[keys[i]] = value
}
}
} }
} }
var node = data, keys = key.split(nfs.PT); while (node && keys.length > 0) { if (typeof node == "string") { return } return list.join(ice.PT)
if (keys[0] == "-1") { keys[0] = node.length-1 } node = node[keys[0]], keys = keys.slice(1) }),
} return node == undefined? data[key]: node Value: shy("存储器", function(data, key, value) {
}, if (data == undefined) { return }
Split: function(str) { if (!str || !str.length) { return [] } if (key == undefined) { return data }
var opt = {detail: false}, arg = []; for (var i = 1; i < arguments.length; i++) { var v = arguments[i]; typeof v == code.OBJECT? opt = v: arg.push(v) }
if (typeof key == lang.OBJECT && key.length > 0) { key = key.join(ice.PT) }
if (typeof key == lang.OBJECT) { for (var k in key) { arguments.callee.call(this, data, k, key[k]) } return data }
if (value != undefined) { data[key] = value }
if (data[key] != undefined) { return data[key] }
var p = data, ls = key.split(ice.PT); while (p && ls.length > 0) {
if (ls[0] == "-1") { ls[0] = p.length-1 }
p = p[ls[0]], ls = ls.slice(1)
} return p
}),
Split: shy("分词器", function(str) { if (!str || !str.length) { return [] }
var opt = {detail: false}, arg = []; for (var i = 1; i < arguments.length; i++) {
typeof arguments[i] == lang.OBJECT? opt = arguments[i]: arg.push(arguments[i])
}
// 字符定义
function _list(str) { var res = {}; for (var i = 0; i < str.length; i++) { res[str[i]] = true }; return res } function _list(str) { var res = {}; for (var i = 0; i < str.length; i++) { res[str[i]] = true }; return res }
var space = _list(arg[0]||"\t ,;\n") // 空白符 var space = _list(arg[0]||"\t ,;\n") // 空白符
var block = _list(arg[1]||"{[()]}") // 分隔符 var block = _list(arg[1]||"{[()]}") // 分隔符
var quote = _list(arg[2]||"'\"`") // 引用符 var quote = _list(arg[2]||"'\"`") // 引用符
var trans = _list(arg[3]||"\\") // 转义符 var trans = _list(arg[3]||"\\") // 转义符
var res = [], begin = 0; function push(obj) { obj && res.push(typeof obj == code.STRING || opt.detail? obj: obj.text), begin = -1 }
var res = [], begin = 0; function push(obj) {
obj && res.push(typeof obj == lang.STRING || opt.detail? obj: obj.text), begin = -1
}
// 开始分词
for (var s = "", i = 0; i < str.length; i++) { for (var s = "", i = 0; i < str.length; i++) {
if (space[str[i]]) { if (s) { continue } if (space[str[i]]) { // 空白符
begin > -1 && push(str.slice(begin, i)), opt.detail && push({type: code.SPACE, text: str.slice(i, i+1)}) if (s) { continue }
} else if (block[str[i]]) { if (s) { continue } begin > -1 && push(str.slice(begin, i))
begin > -1 && push(str.slice(begin, i)), push(str.slice(i, i+1)) opt.detail && push({type: html.SPACE, text: str.slice(i, i+1)})
} else if (quote[str[i]]) {
} else if (block[str[i]]) { // 分隔符
if (s) { continue }
begin > -1 && push(str.slice(begin, i))
push(str.slice(i, i+1))
} else if (quote[str[i]]) { // 引用符
if (s == "") { if (s == "") {
begin > -1 && push(str.slice(begin, i)), s = str[i], begin = i+1 begin > -1 && push(str.slice(begin, i))
s = str[i], begin = i+1
} else if (s == str[i]) { } else if (s == str[i]) {
push({type: code.STRING, text: str.slice(begin, i), left: s, right: str[i]}), s = "", begin = -1 push({type: lang.STRING, text: str.slice(begin, i), left: s, right: str[i]})
s = "", begin = -1
} }
} else if (trans[str[i]]) { begin == -1 && (begin = i), i++
} else { begin == -1 && (begin = i) } } else if (trans[str[i]]) { // 转义符
} return begin > -1 && (s? push({type: code.STRING, text: str.slice(begin), left: s, right: ""}): push(str.slice(begin))), res begin == -1 && (begin = i++)
},
SplitInput: function(item, type) { if (typeof item == code.OBJECT) { return item } type = type||html.TEXT; switch (item) { } else { // 普通符
case ctx.RUN: return {type: html.BUTTON, name: item} begin == -1 && (begin = i)
case ice.LIST: return {type: html.BUTTON, name: item, action: ice.AUTO} }
case ice.BACK: return {type: html.BUTTON, name: item} }
case mdb.NAME: return {type: html.TEXT, name: item}
case mdb.TEXT: return {type: html.TEXTAREA, name: item} // 剩余字符
case ctx.ARGS: return {type: html.TEXTAREA, name: item} begin >= 0 && (s? push({type: lang.STRING, text: str.slice(begin), left: s, right: ""}): push(str.slice(begin)))
default: var ls = this.Split(item, lex.SP, "*:=@"), res = {type: type, name: ls[0]}; for (var i = 1; i < ls.length; i += 2) { switch (ls[i]) { return res
case "*": res["need"] = "must", i--; break }),
case nfs.DF: res[mdb.TYPE] = ls[i+1]; break CallFunc: shy("调用器", function(func, args, mod) { args = args||{}
case mdb.EQ: var event = args["event"]||{}, can = args["can"]||args[0], msg = args["msg"]||args[1], cmds = args["cmds"]||[]
if (res[mdb.TYPE] == html.SELECT) { res.values = this.Split(ls[i+1]); for (var j = 1; j < res.values.length; j++) {
if (res.values[0] == "" || res.values[0] == res.values[j]) { res.value = res.values[0], res.values = res.values.slice(1); break } // 查找调用
} } else { res.value = ls[i+1] } break func = typeof func == lang.FUNCTION? func: typeof func == lang.STRING? this.Value(mod||can, func):
case ice.AT: res[ctx.ACTION] = ls[i+1]; break typeof func == lang.OBJECT && func.length > 0? this.Value(func[0], this.Keys(func.slice(1))): null
} } return res if (typeof func != lang.FUNCTION) { return }
} },
CallFunc: function(func, args, mod) { args = args||{}; var can = args["can"]||args[0], msg = args["msg"]||args[1], cb = args["cb"] // 解析参数
if (Array.isArray(args)) { this.List(args, function(arg) { if (!arg) { return } if (arg.request && arg.run) { can = arg } else if (arg.Append && arg.Result) { msg = arg } else if (typeof arg == code.FUNCTION) { cb = arg } }) } var list = [], echo = false, cb = args["cb"]
func = typeof func == code.FUNCTION? func: typeof func == code.OBJECT && func.length > 0? this.Value(func[0], this.Keys(func.slice(1))): typeof func == code.STRING? this.Value(mod||can, func): null this.List(func.toString().split(")")[0].split("(")[1].split(ice.FS), function(item, index) { item = item.trim(); if (item == "") { return }
if (typeof func != code.FUNCTION) { if (typeof cb == code.FUNCTION) { cb() } return } var arg = args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) ||
var list = [], echo = false; args.length > 0? list = args: this.List(func.toString().split(")")[0].split("(")[1].split(mdb.FS), function(item, index) { item = item.trim(); if (item == "") { return } event&&!(event instanceof Event)&&event[item] || args[index] || cmds[index] || null
list.push(args[item] || msg&&msg.Option&&msg.Option(item) || can&&can.Conf&&can.Conf(item) || null); if (item == "cb") { echo = true } if (item == "cb") { echo = true }
}); var res = func.apply(mod||can, list); if (msg && msg.Defer) { msg.Defer() } list.push(arg)
if (!echo && typeof cb == code.FUNCTION) { res && msg&&msg.Echo&&msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) } return res })
},
List: function(list, cb, interval, cbs) { // 执行调用
if (typeof list == code.STRING) { list = [list] } else if (typeof list == code.NUMBER) { // [end cb interval]|[begin end interval] var res = func.apply(mod||can, list)
var begin = 0, end = list, step = typeof interval == code.NUMBER? interval: 1; if (typeof cb == code.NUMBER) { begin = list, end = cb, cb = null } if (!echo && typeof cb == lang.FUNCTION) { res && msg && msg.Echo(res), arguments.callee.apply(this, [cb, {msg: msg, res: res}]) }
return res
}),
List: shy("迭代器", function(list, cb, interval, cbs) {
if (typeof list == lang.STRING) { // 默认序列
list = [list]
} else if (typeof list == lang.NUMBER) { // 等差序列 [end cb interval]|[begin end interval]
var begin = 0, end = list, step = typeof interval == lang.NUMBER? interval: 1
if (typeof cb == lang.NUMBER) { begin = list, end = cb, cb = null }
list = []; for (var i = begin; i < end; i += step) { list.push(i) } list = []; for (var i = begin; i < end; i += step) { list.push(i) }
} list = list||[] }
if (interval > 0) {
function loop(i) { i >= list.length? typeof cbs == code.FUNCTION && cbs(list): cb(list[i], i, list), setTimeout(function() { loop(i+1) }, interval) } list = list||[]
typeof cb == code.FUNCTION && list.length > 0 && setTimeout(function() { loop(0) }, interval/4) if (interval > 0) { // 时间序列
} else { var res = [] function loop(i) { if (i >= list.length) { return typeof cbs == lang.FUNCTION && cbs(list) }
for (var i = 0; i < list.length; i++) { var _res = typeof cb == code.FUNCTION? cb(list[i], i, list): list[i]; _res != undefined && res.push(_res) } cb(list[i], i, list), setTimeout(function() { loop(i+1) }, interval)
list = res }
} return list typeof cb == lang.FUNCTION && list.length > 0 && setTimeout(function() { loop(0) }, interval/4)
}, } else { // 选择序列
Next: function(list, cb, cbs, data) { var slice = [], res
for (var i = 0; i < list.length; i++) {
typeof cb == lang.FUNCTION? (res = cb(list[i], i, list)) != undefined && slice.push(res): slice.push(list[i])
}; list = slice
}
return list
}),
Next: shy("迭代器", function(list, cb, cbs) {
switch (typeof list) { switch (typeof list) {
case code.OBJECT: case lang.OBJECT: if (list == null) { list = []; break }
if (list == null) { list = []; break } if (list.length == undefined) { var ls = []; for (var k in list) { ls.push(k) } list = ls } break if (list.length == undefined) { var ls = []; for (var k in list) { ls.push(k) } list = ls } break
default: if (list == undefined) { list = []; break } list = [list] default: if (list == undefined) { list = []; break }
} list = [list]
function next(i) {
data = (i < list.length?
typeof cb == code.FUNCTION && cb(list[i], function(_data) { data = _data||data, next(i+1) }, i, list, data):
typeof cbs == code.FUNCTION && cbs(list))||data
} }
function next(i) { i < list.length? typeof cb == lang.FUNCTION && cb(list[i], function() { next(i+1) }, i, list):
typeof cbs == lang.FUNCTION && cbs(list) }
return next(0), list return next(0), list
}, }),
Item: function(obj, cb) { var list = [], keys = [] Items: shy("迭代器", function(obj, cb) { var list = []
if (obj && obj.detail && obj.option) { for (var k in obj) {
obj["detail"] && keys.push("detail") list = list.concat(this.List(obj[k], function(v, i) {
obj["option"] && keys.push("option") return typeof cb == lang.FUNCTION && cb(v, i, k, obj)
keys = keys.concat(obj.option, obj.append||[]) }))
obj["append"] && keys.push("append")
obj["result"] && keys.push("result")
} else {
for (var k in obj) { keys.push(k) }
} }
for (var i = 0; i < keys.length; i++) { var k = keys[i]; var res = typeof cb == code.FUNCTION? cb(k, obj[k], list): k; res != undefined && list.push(res) }
return list return list
}, }),
ItemKeys: function(obj, cb) { var list = [], keys = []; for (var k in obj) { keys.push(k) } keys.sort() Item: shy("迭代器", function(obj, cb) { var list = []
for (var i in keys) { var k = keys[i]; var res = typeof cb == code.FUNCTION? cb(k, obj[k]): k; res != undefined && list.push(res) } for (var k in obj) {
var res = typeof cb == lang.FUNCTION? cb(k, obj[k]): k
res != undefined && list.push(res)
}
return list return list
}, }),
ItemOrder: function(obj, key, cb) { var list = [], order = [], keys = {}, vals = {}, i = 0 ItemCB: shy("迭代器", function(meta, cb, can, item) { var list = []
for (var k in obj) { o = obj[k][key]||i++, order.push(o), keys[o] = k, vals[o] = obj[k] } order.sort() for (var k in meta) { (function(k) {
for (var i in order) { var k = order[i], res = typeof cb == code.FUNCTION? cb(keys[k], vals[k]): k; res != undefined && list.push(res) } if (k.indexOf("on") == 0 && typeof meta[k] == lang.FUNCTION) {
if (typeof cb == lang.FUNCTION) {
cb(k, meta[k])
} else {
cb[k] = function(event) { meta[k](event, can, item) }
}
list.push(k)
}
})(k) }
return list return list
}, }),
ItemForm: function(obj, cb) { var list = []
for (var k in obj) { list = list.concat(this.List(obj[k], function(v, i) { return typeof cb == code.FUNCTION && cb(v, i, k, obj) })) } Timer300ms: function(cb) { this.Timer(300, cb) },
return list Timer300: function(cb) { this.Timer(300, cb) },
}, Timer3s: function(cb) { this.Timer(3000, cb) },
ItemCB: function(meta, cb, can, item) { var list = [] Timer: shy("定时器, value, [1,2,3,4], {interval, length}", function(interval, cb, cbs) {
for (var k in meta) { if (k.indexOf("on") == 0 && typeof meta[k] == code.FUNCTION) { (function(k) { list.push(k) var timer = {stop: false}; function loop(i) {
if (typeof cb == code.FUNCTION) { timer.stop || i >= interval.length && interval.length >= 0 || cb(timer, interval.interval||interval[i], i, interval)?
cb(k, meta[k]) typeof cbs == lang.FUNCTION && cbs(timer, interval): setTimeout(function() { loop(i+1) }, interval.interval||interval[i+1])
} else { cb[k] = function(event) { can.misc.Event(event, can, function(msg) { }
meta[k](event, can, item)
}) } } interval = typeof interval == lang.OBJECT? interval: [interval]
})(k) } } return list if (interval.interval == 0) { cb(); return timer }
},
Timer: shy("定时器, value, [1,2,3,4], {delay, interval, length}", function(interval, cb, cbs) { var timer = {stop: false} typeof cb == lang.FUNCTION && setTimeout(function() { loop(0) }, interval.interval||interval[0])
if (interval == "0") { return cb && cb(), cbs && cbs() } return timer
function loop(i) { timer.stop || i >= interval.length && interval.length >= 0 || cb(timer, interval.interval||interval[i], i, interval)?
typeof cbs == code.FUNCTION && cbs(timer, interval): setTimeout(function() { loop(i+1) }, interval.interval||interval[i+1])
} interval = typeof interval == code.OBJECT? interval: [interval]; if (interval.interval == 0) { return cb(), timer }
var delay = interval.delay||interval.interval/2||interval[0]
return typeof cb == code.FUNCTION && (timer._timer = setTimeout(function() { loop(0) }, delay)), timer
}), }),
}) })

View File

@ -1,254 +0,0 @@
Volcanos("date", {
List: function(can, cb, now, head) { var list = [{th: head||(can.user.info.language == "en"? ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]: ["日", "一", "二", "三", "四", "五", "六"])}]
var tr; function _cb(day, type) { if (day.getDay() == 0) { list.push(tr = {type: html.TR, list: []}) } var lunar = can.date.solar2lunar(day), _day = new Date(day)
tr.list.push({view: [can.base.isIn(can.base.Time(day, "%y-%m-%d"), can.base.Time(now, "%y-%m-%d"))? html.SELECT: type, html.TD],
onclick: function(event) { cb(event, _day) }, list: [{text: day.getDate()+""}, {text: [lunar.autoDay, "", lunar.autoClass]}],
})
}
var first = new Date(now); first.setDate(1); var last = new Date(first); last.setMonth(last.getMonth()+1)
var begin = new Date(first); begin.setDate(first.getDate()-first.getDay()); var end = new Date(last); end.setDate(last.getDate()+7-last.getDay())
for (var day = new Date(begin); day < first; day.setDate(day.getDate()+1)) { _cb(day, mdb.PREV) }
for (var day = new Date(first); day < last; day.setDate(day.getDate()+1)) { _cb(day, mdb.MAIN) }
for (var day = new Date(last); day.getDay() != 0 && day < end; day.setDate(day.getDate()+1)) { _cb(day, mdb.NEXT) }
return list
},
// @1900-2100区间内的公历转农历
solar2lunar: function(date) { var y = date.getFullYear(), m = date.getMonth()+1, d = date.getDate()
var day = (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) - Date.UTC(1900,0,31))/86400000
for (var year = 1900, days = 0; year < 2101 && day > 0; year++) { days = this.lYearDays(year), day -= days } if (day < 0) { day += days, year-- }
var isLeap = false, leap = this.leapMonth(year); for (var month = 1; month < 13 && day > 0; month++) {
if (leap > 0 && month == leap+1 && isLeap == false) { month--, isLeap = true, days = this.leapDays(year) } else { days = this.monthDays(year, month) }
if (isLeap == true && month == leap+1) { isLeap = false } day -= days
} if (day == 0 && leap > 0 && month == leap+1) { if (isLeap) { isLeap = false } else { isLeap = true, month-- } } if (day < 0) { day += days, month-- } day++
// 节气
var term = null, firstTerm = this.getTerm(y, (m*2-1)), secondTerm = this.getTerm(y, (m*2))
if (d == firstTerm) { term = this.termName[m*2-2] } else if (d == secondTerm) { term = this.termName[m*2-1] }
// 干支
var gzY = this.toGanZhiYear(year)
var gzM = this.toGanZhi((y-1900)*12+m+(d >= firstTerm? 12: 11))
var gzD = this.toGanZhi(Date.UTC(y,m-1,1,0,0,0,0)/86400000+25567+10+d-1)
// 节日
var nWeek = date.getDay(), cWeek = this.nStr3[nWeek]; if (nWeek == 0) { nWeek = 7 }
function getFestival(list, m, d) { return list[m+"-"+d]? list[m+"-"+d].title: null }
var res = {Date: y+'-'+m+'-'+d, lunarDate: year+'-'+month+'-'+day,
Year: y, Month: m, Day: d, lYear: year, lMonth: month, lDay: day, gzYear: gzY, gzMonth: gzM, gzDay: gzD,
Animal: this.getAnimal(year), cnMonth: (isLeap?"\u95f0":'')+this.toChinaMonth(month), cnDay: this.toChinaDay(day),
isLeap: isLeap, Term: term, Astro: this.toAstro(m, d), nWeek: nWeek, ncWeek: "\u661f\u671f"+cWeek,
lunarFestival: getFestival(this.lfestival, month, day), Festival: getFestival(this.festival, m, d),
}
res.autoDay = res.lunarFestival||res.Festival||term||(day==1? this.toChinaMonth(month): this.toChinaDay(day))
res.autoClass = "lunar"+(res.lunarFestival||res.Festival? " fest":"")+(term? " term": "")
return res
},
// 天干表 ["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
Gan: ["\u7532","\u4e59","\u4e19","\u4e01","\u620a","\u5df1","\u5e9a","\u8f9b","\u58ec","\u7678"],
// 地支表 ["子","丑","寅","卯","辰","巳","午","未","申","酉","j戌","亥"]
Zhi: ["\u5b50","\u4e11","\u5bc5","\u536f","\u8fb0","\u5df3","\u5348","\u672a","\u7533","\u9149","\u620c","\u4ea5"],
toGanZhi: function(offset) { return this.Gan[offset%10] + this.Zhi[offset%12] },
toGanZhiYear: function(lYear) { // 农历年份转换为干支纪年
var ganKey = (lYear-3)%10; if (ganKey == 0) { ganKey = 10 }
var zhiKey = (lYear-3)%12; if (zhiKey == 0) { zhiKey = 12 }
return this.Gan[ganKey-1] + this.Zhi[zhiKey-1]
},
// 生肖表 ["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
Animals: ["\u9f20","\u725b","\u864e","\u5154","\u9f99","\u86c7","\u9a6c","\u7f8a","\u7334","\u9e21","\u72d7","\u732a"],
// 年份转生肖,精确划分生肖分界线是"立春"
getAnimal: function(y) { return this.Animals[(y - 4) % 12] },
// 月份表 ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
nStr1: ["\u6b63","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u51ac","\u814a"],
// 月旬表 ['初','十','廿','卅']
nStr2: ["\u521d","\u5341","\u5eff","\u5345"],
// 日子表 ['日','一','二','三','四','五','六','七','八','九','十']
nStr3: ["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341"],
toChinaMonth: function(m) { return this.nStr1[m-1]+"\u6708" },
toChinaDay: function(d) { switch (d) {
case 10: return '\u521d\u5341'
case 20: return '\u4e8c\u5341'
case 30: return '\u4e09\u5341'
default: return this.nStr2[Math.floor(d/10)]+this.nStr3[d%10]
} },
// 公历每个月份的天数普通表
solarMonth: [31,28,31,30,31,30,31,31,30,31,30,31],
// 返回公历y年m月的天数
solarDays: function(y, m) { var ms = m-1; if (ms == 1) { return ((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28 } else { return this.solarMonth[ms] } },
// 公历月、日判断所属星座
toAstro: function(m, d) { var arr = [20,19,21,21,21,22,23,23,23,23,22,22]
var s = "\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf"
return s.substr(m*2 - (d < arr[m-1]? 2: 0), 2) + "\u5ea7"
},
festival: { // 公历节日
'1-1': {title: '元旦节'},
'12-24': {title: '平安夜'},
'12-25': {title: '圣诞节'},
'2-14': {title: '情人节'},
'3-8': {title: '妇女节'},
'4-1': {title: '愚人节'},
'5-1': {title: '劳动节'},
'5-4': {title: '青年节'},
'6-1': {title: '儿童节'},
'9-10': {title: '教师节'},
'7-1': {title: '建党节'},
'8-1': {title: '建军节'},
'10-1': {title: '国庆节'},
},
lfestival: { // 农历节日
'12-30': {title: '除夕'},
'1-1': {title: '春节'},
'1-15': {title: '元宵'},
'5-5': {title: '端午'},
'7-7': {title: '七夕'},
'8-15': {title: '中秋'},
'9-9': {title: '重阳'},
},
// 返回农历y年m月非闰月的总天数计算m为闰月时的天数请使用leapDays方法
monthDays: function(y, m) { return (this.lunarInfo[y-1900] & (0x10000>>m))? 30: 29 },
// 返回农历y年闰月是哪个月若y年没有闰月则返回0
leapMonth: function(y) { return this.lunarInfo[y-1900] & 0xf },
// 返回农历y年闰月的天数 若该年没有闰月则返回0
leapDays: function(y) { if (this.leapMonth(y)) { return (this.lunarInfo[y-1900] & 0x10000)? 30: 29 } return 0 },
// 返回农历y年一整年的总天数
lYearDays: function(y) { var i, sum = 348
for (i = 0x8000; i > 0x8; i >>= 1) { sum += (this.lunarInfo[y-1900] & i)? 1: 0 }
return sum+this.leapDays(y)
},
lunarInfo: [ // 农历1900-2100的润大小信息表
0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909
0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919
0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929
0x06566,0x0d4a0,0x0ea50,0x16a95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939
0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949
0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959
0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969
0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979
0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989
0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x05ac0,0x0ab60,0x096d5,0x092e0,//1990-1999
0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009
0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019
0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029
0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039
0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049
0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50,0x06b20,0x1a6c4,0x0aae0,//2050-2059
0x092e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069
0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079
0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089
0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099
0x0d520, //2100
],
getTerm: function(y, n) { // 传入公历y年获得该年第n个节气的公历日期
var _table = this.termInfo[y-1900]
var _info = [
parseInt('0x'+_table.substr(0,5)).toString(),
parseInt('0x'+_table.substr(5,5)).toString(),
parseInt('0x'+_table.substr(10,5)).toString(),
parseInt('0x'+_table.substr(15,5)).toString(),
parseInt('0x'+_table.substr(20,5)).toString(),
parseInt('0x'+_table.substr(25,5)).toString(),
]
var _calday = [
_info[0].substr(0,1),
_info[0].substr(1,2),
_info[0].substr(3,1),
_info[0].substr(4,2),
_info[1].substr(0,1),
_info[1].substr(1,2),
_info[1].substr(3,1),
_info[1].substr(4,2),
_info[2].substr(0,1),
_info[2].substr(1,2),
_info[2].substr(3,1),
_info[2].substr(4,2),
_info[3].substr(0,1),
_info[3].substr(1,2),
_info[3].substr(3,1),
_info[3].substr(4,2),
_info[4].substr(0,1),
_info[4].substr(1,2),
_info[4].substr(3,1),
_info[4].substr(4,2),
_info[5].substr(0,1),
_info[5].substr(1,2),
_info[5].substr(3,1),
_info[5].substr(4,2),
]; return parseInt(_calday[n-1])
},
// 二十四节气速查表 ["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
termName: ["\u5c0f\u5bd2","\u5927\u5bd2","\u7acb\u6625","\u96e8\u6c34","\u60ca\u86f0","\u6625\u5206","\u6e05\u660e","\u8c37\u96e8","\u7acb\u590f","\u5c0f\u6ee1","\u8292\u79cd","\u590f\u81f3","\u5c0f\u6691","\u5927\u6691","\u7acb\u79cb","\u5904\u6691","\u767d\u9732","\u79cb\u5206","\u5bd2\u9732","\u971c\u964d","\u7acb\u51ac","\u5c0f\u96ea","\u5927\u96ea","\u51ac\u81f3"],
termInfo: [ // 1900-2100各年的24节气日期速查表
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f',
'97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f',
'b027097bd097c36b0b6fc9274c91aa','9778397bd19801ec9210c965cc920e','97b6b97bd19801ec95f8c965cc920f',
'97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd197c36c9210c9274c91aa',
'97b6b97bd19801ec95f8c965cc920e','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bcf97c3598082c95f8e1cfcc920f',
'97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f',
'97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd07f595b0b6fc920fb0722',
'9778397bd097c36b0b6fc9210c8dc2','9778397bd19801ec9210c9274c920e','97b6b97bd19801ec95f8c965cc920f',
'97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
'97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bd07f1487f595b0b0bc920fb0722',
'7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa','97b6b97bd197c36c9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
'97b6b7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36b0b70c9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa','97b6b7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','977837f0e37f149b0723b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c35b0b6fc9210c8dc2',
'977837f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'977837f0e37f14998082b0723b06bd','7f07e7f0e37f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f595b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f531b0b0bb0b6fb0722',
'7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35',
'7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd',
'7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35',
'7ec967f0e37f14998082b0723b06bd','7f07e7f0e37f14998083b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14898082b0723b02d5','7f07e7f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66aa89801e9808297c35','665f67f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66a449801e9808297c35',
'665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e26665b66a449801e9808297c35','665f67f0e37f1489801eb072297c35',
'7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722'],
})
Volcanos("page", {trans: function(can, text) {
return can.base.replaceAll(text, "&", "&amp;", "<", "&lt;", ">", "&gt;")
}})

View File

@ -1,403 +1,265 @@
Volcanos("misc", { Volcanos("misc", {help: "通信协议", Message: function(event, can) { var msg = {}
Event: function(event, can, cb) { for (var i = 3; i < arguments.length; i++) { can.request(event, arguments[i]) } cb(can.request(event)) }, var proto = {_event: event, _can: can,
Message: function(event, can) { var msg = kit.proto({}, {_event: event, _can: can, _target: can._target,
RunAction: function(event, sub, cmds, meta) { var msg = can.request(event); meta = meta || sub&&sub.onaction || {} RunAction: function(event, sub, cmds, meta) { var msg = can.request(event); meta = meta || sub&&sub.onaction || {}
if (!msg._method) { if (msg.Option(ice.MSG_HANDLE) == ice.TRUE) { return }
if (!cmds || cmds.length == 0 || cmds[0] != ctx.ACTION) { if (cmds && cmds[0] == ctx.ACTION && can.base.isFunc(meta[cmds[1]])) {
msg._method = http.GET return msg.Option(ice.MSG_HANDLE, ice.TRUE), can.core.CallFunc(meta[cmds[1]], {event: event, can: sub, msg: msg, button: cmds[1], cmd: cmds[1]}), true
} else if (can.base.isIn(cmds[1], mdb.CREATE, mdb.INSERT)) {
msg._method = http.PUT
} else if (can.base.isIn(cmds[1], mdb.REMOVE, mdb.DELETE)) {
msg._method = http.DELETE
} else {
msg._method = http.POST
}
}
if (msg.Option(ice.MSG_HANDLE) != ice.TRUE && cmds && cmds[0] == ctx.ACTION && can.base.isFunc(meta[cmds[1]])) { msg.Option(ice.MSG_HANDLE, ice.TRUE)
return can.core.CallFunc(meta[cmds[1]], {event: event._event||event, can: sub, msg: msg, button: cmds[1], cmd: cmds[1]}), true
} }
return false
}, },
Display: function(file) { return msg.Option(ice.MSG_DISPLAY, file) },
DisplayStory: function(file) { return msg.Option(ice.MSG_DISPLAY, chat.PLUGIN_STORY+file) },
SearchOrOption: function(key) { return can.misc.Search(can, key)||msg.Option(key) },
OptionProcess: function() { return msg.Option(ice.MSG_PROCESS) },
OptionStatus: function() { return msg.Option(ice.MSG_STATUS) }, OptionStatus: function() { return msg.Option(ice.MSG_STATUS) },
StatusTimeCount: function(obj) { msg.append && msg.Status(can.base.Copy(kit.Dict(mdb.TIME, can.base.Time(), mdb.COUNT, msg.Length()+"x"+msg.append.length), obj)) }, OptionProcess: function() { return msg.Option(ice.MSG_PROCESS) },
Status: function(obj) { return msg.Option(ice.MSG_STATUS, JSON.stringify(can.core.Item(obj, function(key, value) { return {name: key, value: value} }))) }, OptionOrSearch: function(key) { return can.misc.Search(can, key)||msg.Option(key) },
OptionDefault: function(key, val) { var arg = arguments; for (var i = 0; i < arg.length; i += 2) { msg.Option(arg[i]) || msg.Option(arg[i], arg[i+1]) } return msg.Option(key) }, Option: function(key, val) {
OptionSimple: function(key) { var arg = arguments, res = [] if (key == undefined) { return msg && msg.option || [] }
for (var i = 0; i < arg.length; i++) { res.push(arg[i], msg.Option(arg[i])) } if (can.base.isObject(key)) { can.core.Item(key, msg.Option) }
return res if (val == undefined) { return msg && msg[key] && msg[key][0] || "" }
},
Option: function(key, val) { if (key == undefined) { return msg.option || [] }
if (can.base.isObject(key)) { return can.core.Item(key, function(key, value) { msg.Option(key, value) }) }
if (val == undefined) { return can.base.isIn(key, msg.option) && msg[key] && msg[key][0] || "" }
return msg.option = can.base.AddUniq(msg.option, key), msg[key] = can.core.List(arguments).slice(1), val return msg.option = can.base.AddUniq(msg.option, key), msg[key] = can.core.List(arguments).slice(1), val
}, },
Append: function(key, val) { if (key == undefined) { return msg.append || [] } Append: function(key, val) {
if (can.base.isObject(key)) { return can.core.Item(key, msg.Append) } if (key == undefined) { return msg && msg.append || [] }
if (msg.IsDetail()) { if (can.base.isObject(key)) { can.core.Item(key, msg.Append) }
for (var i = 0; i < msg.key.length; i++) { if (val == undefined) { return msg && msg[key] && msg[key][0] || "" }
if (msg.key[i] == key) {
if (val != undefined) { msg.value[i] = val }
return msg.value[i]
}
}
return
}
if (val == undefined) { return can.base.isIn(key, msg.append) && msg[key] && msg[key][0] || "" }
return msg.append = can.base.AddUniq(msg.append, key), msg[key] = can.core.List(arguments).slice(1), val return msg.append = can.base.AddUniq(msg.append, key), msg[key] = can.core.List(arguments).slice(1), val
}, },
Result: function() { if (!msg.result) { return "" } return msg.result[0] == ice.ErrWarn? msg.result.join(lex.SP): msg.result.join("") }, Result: function() { return msg.result && msg.result.join("") || "" },
Results: function() { return msg.result && msg.result[0] == ice.ErrWarn? "": msg.Result() },
TableDetail: function() { var item = can.Option(); return msg.Table(function(value) { can.core.Value(item, value.key, value.value) }), item }, Length: function() {
IsDetail: function() { var max = "", len = 0; can.core.List(msg.append, function(key, index) {
return msg.Option("fields") == "detail" || msg.append && msg.append.length == 2 && msg.append[0] == "key" && msg.append[1] == "value" if (msg[key] && msg[key].length > len) { max = key, len = msg[key].length }
})
return len
},
Table: function(cb) { if (!msg.append || msg.append.length == 0) { return }
var max = "", len = 0; can.core.List(msg.append, function(key, index) {
if (msg[key] && msg[key].length > len) { max = key, len = msg[key].length }
})
return can.core.List(msg[max], function(value, index, array) { var one = {}, res
can.core.List(msg.append, function(key) { one[key] = (msg[key]&&msg[key][index]||"") })
return can.base.isFunc(cb) && (res = cb(one, index, array)) && res != undefined && res || one
})
}, },
Table: function(cb) { return can.core.List(msg.Length(), function(index) { var item = {}
can.core.List(msg.append, function(k) { item[k] = msg[k]&&msg[k][index]||"" })
return can.base.isFunc(cb)? cb(item, index): item
}) },
Length: function() { var max = 0; can.core.List(msg.append, function(k) { if (msg[k] && msg[k].length > max) { max = msg[k].length } }); return max },
Clear: function(key) { switch (key||ice.MSG_APPEND) { Clear: function(key) { switch (key||ice.MSG_APPEND) {
case ice.MSG_APPEND:
case ice.MSG_OPTION: case ice.MSG_OPTION:
case ice.MSG_APPEND: can.core.List(msg[key], function(key) { delete(msg[key]) }) can.core.List(msg[key], function(item) { delete(msg[item]) })
default: delete(msg[key]) default: msg[key] = []
} }, } },
Copy: function(res) { if (!res) { return msg } Copy: function(res) { if (!res) { return msg }
res.append && res.append.length > 0 && (msg.append = res.append) && res.append.forEach(function(key) { res.result && (msg.result = (msg.result||[]).concat(res.result))
var i = msg.option && msg.option.indexOf(key); if (i > -1) { msg.option[i] = "", delete(msg[key]) } res.append && (msg.append = res.append) && res.append.forEach(function(item) {
res[key] && (msg[key] = (msg[key]||[]).concat(res[key])) var i = msg.option && msg.option.indexOf(item); if (i > -1) {
}), res.result && res.result.length > 0 && (msg.result = (msg.result||[]).concat(res.result)) msg.option[i] = "", delete(msg[item])
res.option && res.option.length > 0 && (msg.option = res.option) && res.option.forEach(function(key) { res[key] && (msg[key] = res[key]) }) }
res._option && (msg._option = res._option) && res._option.forEach(function(key) { res[key] && (msg[key] = res[key]) }) res[item] && (msg[item] = (msg[item]||[]).concat(res[item]))
})
res.option && (msg.option = res.option) && res.option.forEach(function(item) {
res[item] && (msg[item] = res[item])
})
res._option && (msg._option = res._option) && res._option.forEach(function(item) {
res[item] && (msg[item] = res[item])
})
return msg return msg
}, },
Sort: function(key, swap) { var n = msg.Length()
key = key||msg.append[0], swap = swap||function(i, j) { return msg[key][i] > msg[key][j] }
switch (swap) {
case "str": swap = function(i, j) { return msg[key][i] > msg[key][j] }; break
case "str_r": swap = function(i, j) { return msg[key][i] < msg[key][j] }; break
case "int": swap = function(i, j) { return can.base.ParseSize(msg[key][i]) > can.base.ParseSize(msg[key][j]) }; break
case "int_r": swap = function(i, j) { return can.base.ParseSize(msg[key][i]) < can.base.ParseSize(msg[key][j]) }; break
}
for (var i = 0; i < n-1; i++) {
for (var j = i+1; j < n; j++) { var _swap = swap(i, j)
if (_swap === true) {
can.core.List(msg.append, function(k) {
var temp = msg[k][i]; msg[k][i] = msg[k][j], msg[k][j] = temp
})
} else if (_swap === false) {
continue
} else {
}
}
}
},
Push: function(key, value, detail) { Push: function(key, value, detail) {
if (can.base.isObject(key)) { can.core.List(value||msg.append||can.base.Obj(msg.Option(ice.MSG_FIELDS))||can.core.Item(key), function(item) { if (can.base.isObject(key)) {
detail? msg.Push(mdb.KEY, item).Push(mdb.VALUE, key[item]||""): msg.Push(item, key[item]||"") value = value||can.core.Item(key), can.core.List(value, function(item) {
}); return msg } detail? msg.Push(mdb.KEY, item).Push(mdb.VALUE, key[item]||""): msg.Push(item, key[item]||"")
var i = msg.option && msg.option.indexOf(key); if (i > -1) { msg.option[i] = "", msg[key] = [] } })
msg.append = can.base.AddUniq(msg.append, key), msg[key] = msg[key]||[] return msg
msg[key].push(can.base.isString(value)||can.base.isFunc(value)? value: JSON.stringify(value)); return msg
},
PushButton: function(button) { var args = can.core.List(arguments)
msg.Push(ctx.ACTION, can.core.List(args, function(button) {
return can.page.Format(html.INPUT, "", mdb.TYPE, html.BUTTON, mdb.NAME, button, mdb.VALUE, can.user.trans(can, button))
}).join("")); return msg
},
PushAction: function(button) { var args = can.core.List(arguments)
can.core.List(msg.Length(), function() {
msg.Push(ctx.ACTION, can.core.List(args, function(button) {
return can.page.Format(html.INPUT, "", mdb.TYPE, html.BUTTON, mdb.NAME, button, mdb.VALUE, can.user.trans(can, button))
}).join(""))
}); return msg
},
Echo: function(res) { msg.result = (msg.result||[]).concat(can.core.List(arguments)); return msg._hand = true, msg },
Dump: function(can, target) { can = can||msg._can; if (can.user.isNodejs) { return }
target = target||can._output
can.onmotion.clear(can, target), can.onappend.table(can, msg, null, target), can.onappend.board(can, msg, target), can.onmotion.story.auto(can)
},
Show: function(can) { can = can||msg._can; if (can.user.isNodejs) { return }
can.onmotion.clear(can), can.onappend.table(can, msg), can.onappend.board(can, msg), can.onmotion.story.auto(can)
},
Defer: function(cb) { msg._defer = msg._defer||[]
if (arguments.length == 0) { msg._defer = can.core.List(msg._defer.reverse(), function(cb) { can.base.isFunc(cb) && cb() }) } else { msg._defer.push(cb) }
},
IsErr: function() { return msg.result && msg.result[0] == "warn: " },
_caller: function(skip) { msg.Option("log.caller") || msg.Option("log.caller", can.misc.fileLine((skip||2)+3).link); return msg },
isDebug: function() { return msg.Option(log.DEBUG) == ice.TRUE },
}); return msg },
Inputs: function(can, msg, cmds, cb, meta) { var event = msg._event
if (msg.Option(ice.MSG_HANDLE) != ice.TRUE && cmds && cmds[0] == ctx.ACTION && meta.feature[cmds[1]]) { msg.Option(ctx.ACTION, cmds[1])
var action = meta.feature[cmds[1]]; if (can.base.isFunc(action)) { cb = cb||function() { can.Update() }
return action.list && action.list.length > 0? can.user.input(event, can, action.list, function(data) {
can.core.CallFunc(action, {can: can, msg: can.request(event, data), arg: cmds.slice(2), cb: cb})
}): can.core.CallFunc(action, {sup: meta.can, can: can, msg: can.request(event), arg: cmds.slice(2), cb: cb})
} }
var input = can.user.input(event, can, meta.feature[cmds[1]], function(args) { msg.result = []
can.onmotion.delay(can, function() { can.page.ClassList.add(can, input._target, html.PROCESS) }) msg.append = can.base.AddUniq(msg.append, key), msg[key] = msg[key] || []
can.Update(can.request(event, can.Option(), {_handle: ice.TRUE, _cancel: function(event) { msg[key].push(can.base.isString(value)||can.base.isFunction(value)? value: JSON.stringify(value))
can.page.ClassList.del(can, input._target, html.PROCESS) return msg
}}, msg), cmds.slice(0, 2).concat(args), function(msg) { can.page.ClassList.del(can, input._target, html.PROCESS) },
if (msg.IsErr()) { input.focus() Echo: function(res) { msg.result = msg.result || []
can.onappend.style(can, "warn", can.user.toastFailure(can, msg.Result())._target) for (var i = 0; i < arguments.length; i++) { msg.result.push(arguments[i]) }
} else { return msg._hand = true, msg
if (cb && cb(msg)) { return } },
input.cancel({}, can) }
return true return can.misc.proto(msg, proto)
} },
}); return true POST: function(can, msg, url, form, cb) { // _method _accept _upload _progress
}); return true var xhr = new XMLHttpRequest(); msg._xhr = xhr
} return false xhr.open(msg._method||"POST", url), xhr.onreadystatechange = function() {
if (xhr.readyState != 4) { return }
try { // 解析响应
var res = JSON.parse(xhr.responseText)
} catch (e) {
var res = {result: [xhr.responseText]}
}
if (xhr.status == 200) {
return can.base.isFunc(cb) && cb(msg.Copy(res))
}
can.user.toast(can, res, xhr.status)
}
if (msg._upload) { // 上传文件
var data = new FormData(); can.core.Items(form, function(value, index, key) {
data.append(key, value)
}), data.append(html.UPLOAD, msg._upload), data.append(ice.MSG_UPLOAD, mdb.UPLOAD)
xhr.upload.onprogress = function(event) {
can.base.isFunc(msg._progress) && msg._progress(event, parseInt(event.loaded*100/event.total), event.total, event.loaded)
}
} else { // 请求数据
var data = can.core.Items(form, function(value, index, key) { return key+"="+encodeURIComponent(value) }).join("&")
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
}
// 发送请求
xhr.setRequestHeader("Accept", msg._accept||"application/json")
try { xhr.send(data) } catch(e) { can.misc.Log(e) }
}, },
ParseCmd: function(can, msg, cb, cbs) { var list = [] Run: function(event, can, dataset, cmds, cb) {
return msg.Table(function(field, order) { var msg = can.request(event||{}), skip = {_handle: true}
field.feature = can.base.Obj(field.meta, {}) var form = {cmds: cmds||msg.cmd}; msg.option && msg.option.forEach(function(item) {
field.inputs = can.base.Obj(field.list, []) !skip[item] && msg[item] && (form[item] = msg[item])
field.name = can.core.Split(field.name)[0]
if (!field.inputs || field.inputs.length === 0) {
return can.onmotion.delay(can, function() { cb(field, order) })
}
can.core.List(field.inputs, function(input, index) {
input.action = input.action || input.value
input.value == ice.AUTO && (input.value = "")
if (input.value && input.value.indexOf("@") == 0) {
input.action = input.value.slice(1), input.value = ""
}
if (input.type == html.SELECT) {
input.values = input.values || can.core.Split(input.value)
}
if (can.base.isIn(input.type, html.TEXT, html.TEXTAREA)) {
// input.placeholder = can.user.trans(can, input.placeholder||input.name, field, html.INPUT)
}
if (input.type == html.BUTTON) {
input.value = can.user.trans(can, input.value||input.name, field)
} else {
cbs && cbs(input, index, field, order)
}
input.type == html.BUTTON && input.action == ice.AUTO && can.onmotion.delay(can, function() { cb(field, order) })
})
return field
}) })
can.misc.POST(can, msg, can.base.MergeURL(dataset.names.toLowerCase(),
"_", (msg._can.sup||msg._can)._name, ice.MSG_DAEMON, msg.__daemon||dataset.daemon||""
), form, cb)
}, },
Run: function(event, can, dataset, cmds, cb) { var msg = can.request(event), _can = msg._can; _can._fields && _can.sup && (_can = _can.sup) WSS: function(can, args, cb, onopen, onclose, onerror) { if (can.user.isIE) { return }
var form = {cmds: cmds}; can.core.List(msg.option, function(key) { !can.base.isIn(key, "log.caller", "_handle", "_toast") && msg[key] && (form[key] = msg[key]) }) var url = location.protocol.replace("http", "ws")+"//"+location.host+"/space/"
can.misc.POST(can, msg, dataset.names.toLowerCase(), form, cb) if (url.indexOf("chrome") == 0) { url = "ws://localhost:9020/space/" }
},
GET: function(can, path, cb) { can.misc.POST(can, can.request({}, {_method: http.GET}), path, {}, function(msg) { var socket = new WebSocket(can.base.MergeURL(url, args))
cb(msg._xhr.responseText) socket.onclose = function() { can.misc.Log(html.WSS, cli.CLOSE, args)
}) }, can.base.isFunc(onclose)? onclose(socket): can.core.Timer(can.base.random(3000, 1000), function() {
POST: function(can, msg, url, form, cb, cbs) { var xhr = new XMLHttpRequest(), begin = new Date(); msg._xhr = xhr, xhr._begin = begin can.misc.WSS(can, args, cb, onopen, onerror, onclose)
var data = can.core.ItemForm(form, function(v, i, k) { return k+mdb.EQ+encodeURIComponent(v) }).join("&")
if (can.user.isMailMaster && location.protocol == "http:") { msg._method = http.GET }
if (data && can.base.isIn(msg._method, http.GET, http.DELETE)) { url += (url.indexOf("?") == -1? "?": "&")+data, data = "" }
xhr.open(msg._method||http.POST, url), xhr.onreadystatechange = function() { if (xhr.readyState != 4) { return }
try { var res = JSON.parse(xhr.responseText) } catch (e) {
if (xhr.responseText.indexOf("warn: ")) { var res = {result: [xhr.responseText]} } else { var res = {result: [xhr.responseText]} }
} msg.Option("_cost", new Date() - begin), msg.detail || (msg.detail = res.detail), msg.Copy(res)
if (xhr.status == 200) { return can.base.isFunc(cb) && cb(msg) } typeof msg._failure == code.FUNCTION && msg._failure()
can.user.toastFailure(msg._can||can, msg.Result(), msg.Option(ice.MSG_TITLE)), can.misc.Warn(xhr.status, res, url, form), cbs && cbs(xhr)
}, xhr.setRequestHeader(http.Accept, msg._accept||http.ApplicationJSON)
if (msg._upload) { var data = new FormData(); can.core.ItemForm(form, function(v, i, k) { data.append(k, v) })
data.append(ice.MSG_UPLOAD, web.UPLOAD), data.append(web.UPLOAD, msg._upload)
xhr.upload.onprogress = function(event) { can.base.isFunc(msg._progress) && msg._progress(event, parseInt(event.loaded*100/event.total), event.total, event.loaded) }
} else {
xhr.setRequestHeader(http.ContentType, http.ApplicationFORM)
} try { xhr.send(data) } catch(e) { can.misc.Warn(e), cbs && cbs(e) }
},
WSS: function(can, args, cb, onopen, onclose, onerror, _msg) { if (can.user.isIE) { return }
args.debug = can.misc.Search(can, ice.MSG_DEBUG)
args[ice.FROM_DAEMON] = can.misc.Search(can, ice.FROM_DAEMON)
args.text = location.pathname+location.search, args.module = "shylinux.com/x/volcanos", args.version = can.base.trimPrefix(window._version, "?_v=")
var msg = can.request(); can.page.exportValue(can, msg), can.core.List(msg.Option(), function(value) { args[value] = msg.Option(value) })
var url = location.protocol.replace(ice.HTTP, "ws")+"//"+location.host+"/space/"; if (url.indexOf(html.CHROME) == 0) { url = "ws://localhost:9020/space/" }
try { var socket = new WebSocket(can.base.MergeURL(url, args)); _msg = _msg || can.request()._caller() } catch (e) {}
can._socket = socket, socket.onclose = function() { can.misc.Log(html.WSS, cli.CLOSE, args); if (socket._close) { return }
can.base.isFunc(onclose)? onclose(socket): can.core.Timer(can.base.random(3000, 300), function() {
args.name = args.name||can._wss_name, can.misc.WSS(can, args, cb, onopen, onerror, onclose, _msg)
}) })
}, socket.onerror = function() { can.misc.Log(html.WSS, log.ERROR, args) }, socket.onerror = function() { can.misc.Log(html.WSS, cli.ERROR, args)
can.base.isFunc(onerror)? onerror(socket): socket.close() can.base.isFunc(onerror)? onerror(socket): socket.close()
}, socket.onopen = function() { can.misc.Log(html.WSS, cli.OPEN, args, _msg)
}, socket.onopen = function() { can.misc.Log(html.WSS, cli.OPEN, args)
can.base.isFunc(onopen) && onopen(socket) can.base.isFunc(onopen) && onopen(socket)
}, socket.onmessage = function(event) { can.misc.Event(event, can, function(msg) { }
socket.onmessage = function(event) { // 解析命令
try { var data = JSON.parse(event.data) } catch (e) { var data = {detail: [event.data]} } try { var data = JSON.parse(event.data) } catch (e) { var data = {detail: [event.data]} }
msg.Reply = function() { if (msg.Option("space.noecho") == ice.TRUE) { return }
var res = can.request({}, {_handle: ice.TRUE}) var msg = can.request(event); msg.Reply = function() { // 回复命令
res._target = (msg[ice.MSG_SOURCE]||[]).reverse(), res._source = (msg[ice.MSG_TARGET]||[]).reverse().slice(1)||[] msg.Option({_handle: true, _source: (msg[ice.MSG_TARGET]||[]).reverse().slice(1).join(ice.PT)||"", _target: (msg[ice.MSG_SOURCE]||[]).reverse().join(ice.PT)})
res.append = msg.append, can.core.List(msg.append, function(key) { res[key] = msg[key] }), res.result = (msg.result||[]).concat(can.core.List(arguments)) msg.result = (msg.result||[]).concat(can.core.List(arguments)), can.misc.Log(html.WSS, ice.MSG_RESULT, msg.result, msg)
res.Option(ice.LOG_DISABLE, msg.Option(ice.LOG_DISABLE)) != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_RESULT, msg.result&&msg.result.length>0? msg.result: undefined, msg, _msg) delete(msg._event), delete(msg._can), socket.send(JSON.stringify(msg))
res.Option(ice.LOG_TRACEID, msg.Option(ice.LOG_TRACEID)) }, msg.detail = data.detail, msg.Copy(data)
res.Option(ice.MSG_DEBUG, msg.Option(ice.MSG_DEBUG))
socket.send(JSON.stringify(res)) try { // 执行命令
msg.Option("space.noecho", ice.TRUE) can.misc.Log(html.WSS, ice.MSG_DETAIL, msg.detail, msg)
}, msg.detail = data.detail||[], msg.Copy(data), msg[ice.MSG_TARGET] = data[ice.MSG_TARGET]||[] can.base.isFunc(cb) && cb(event, msg, msg.detail[0], msg.detail.slice(1))
try { msg.Option(ice.LOG_DISABLE) != ice.TRUE && can.misc.Log(html.WSS, ice.MSG_DETAIL, msg.detail, msg, _msg) } catch (e) { can.misc.Log(e), msg.Reply() }
can.core.CallFunc(cb, {event: event, msg: msg, cmd: msg.detail[0], arg: msg.detail.slice(1), cb: function() { msg.Reply() }})
} catch (e) { can.misc.Warn(e), msg.Reply() }
}) }
return socket
},
ResourceFavicon: function(can, path, space) { return can.misc.Resource(can, path||can.user.info.favicon||nfs.SRC_MAIN_ICO, space) },
ResourceIcons: function(can, path, space, serve) {
if (!path) {
if (can.user.info.nodetype == web.WORKER) {
return can.misc.Resource(can, can.user.info.favicon, can.user.info.nodename)
}
} }
return can.misc.Resource(can, path||(can.page.isDark(can)? "usr/icons/volcanos.png": "usr/icons/icebergs.png"), space, serve)
}, },
Resource: function(can, path, space, serve) { if (!path) { return "" }
if (!can.base.beginWith(path, web.HTTP, nfs.PS)) { path = nfs.P+path+(path.indexOf("usr/icons/") == -1? (space? can.core.Split(_version, "&")[0]: _version): "") } CookieSessid: shy("会话变量", function(can, value, path) {
if (!can.base.beginWith(path, web.HTTP)) { if (serve && serve.indexOf(location.origin) == -1) { var u = can.base.ParseURL(serve); path = u.origin + path } } return can.misc.Cookie(can, ice.MSG_SESSID+"_"+location.host.replaceAll(ice.PT, "_").replaceAll(ice.DF, "_"), value, path)
if (!space && !can.base.beginWith(path, web.HTTP)) { return location.origin+path } }),
if (!space && path.indexOf("pod=") > 0) { return path } Cookie: shy("会话变量", function(can, key, value, path) {
if (can.base.beginWith(path, "/") && path.indexOf("pod=") > 0) { return path } function set(k, v) { document.cookie = k+"="+v+";path="+(path||ice.PS) }
return can.base.MergeURL(path, ice.POD, space||can.ConfSpace()||can.misc.Search(can, ice.POD))
},
ShareLocal: function(can, path, space) { if (can.base.beginWith(path, web.HTTP, nfs.PS)) { return path }
return can.base.MergeURL(nfs.SHARE_LOCAL+path+_version, ice.POD, space||can.ConfSpace())
},
ShareCache: function(can, path, space) { if (can.base.beginWith(path, web.HTTP, nfs.PS)) { return path }
return can.base.MergeURL(nfs.SHARE_CACHE+path+_version, ice.POD, space||can.ConfSpace()||can.misc.Search(can, ice.POD))
},
Template: function(can, path, file) { return can.base.Path(nfs.SRC_TEMPLATE, can.ConfIndex(), path, file) },
MergePath: function(can, file, path) { return file.indexOf(nfs.PS) == 0 || file.indexOf(ice.HTTP) == 0? file: can.base.Path(path, file) },
MergeCache: function(can, hash, pod) { return can.base.MergeURL(can.misc.MergeURL(can, {_path: can.base.Path(web.SHARE_CACHE, hash)}, true), ice.POD, pod||can.ConfSpace()||can.misc.Search(can, ice.POD)) },
MergePodCmd: function(can, obj) {
if (can.base.beginWith(obj.pod, nfs.PS, web.HTTP)) {
if (location.search.indexOf("debug=true") > 0 && obj.pod.indexOf("debug=true") == -1) {
var ls = obj.pod.split("#"); ls[0] += (ls[0].indexOf("?") > 0? "&": "?") + "debug=true", obj.pod = ls.join("#")
} return obj.pod
}
obj.pod = obj.pod == undefined? can.misc.Search(can, ice.POD): obj.pod; return can.misc.MergeURL(can, obj, true)
},
MergeURL: function(can, obj, clear) { var path = location.pathname; obj._path && (path = obj._path), delete(obj._path)
can.misc.Search(can, log.DEBUG) && (obj.debug = ice.TRUE); var hash = obj._hash||""; delete(obj._hash)
var args = []; can.core.List([ice.POD, ice.CMD], function(key) { obj[key] && args.push(key == ice.POD? "s": "c", obj[key]), delete(obj[key]) })
var _location = location; if (can.user.isExtension) { var _location = new URL(Volcanos.meta.iceberg) }
return can.base.MergeURL(_location.origin+(args.length > 0? nfs.PS+args.join(nfs.PS): path)+(clear? "": _location.search), obj)+(hash? "#"+hash: "")
},
ParseURL: function(can, url) { url = url||location.href; var args = can.base.ParseURL(url)
delete(args.link), delete(args.origin), delete(args._origin)
var raw = new RegExp("(https?://[^/]+)([^?#]*)([^#]*)(.*)").exec(url)
var ls = can.core.Split(raw[2], nfs.PS);
if (ls[0] == chat.SHARE) { args[chat.SHARE] = ls[1] }
if (ls[0] == "s") { args[ice.POD] = decodeURIComponent(ls[1]); if (ls[2] == "c") { args[ice.CMD] = ls[3] } }
if (ls[0] == "c") { args[ice.CMD] = ls[1] }
for (var i = 1; i < ls.length; i += 2) { if (can.base.isIn(ls[i], [ice.POD, ice.CMD])) { args[ls[i]] = ls[i+1] } }
return args
},
SplitPath: function(can, path) {
if (path.indexOf("http") == 0) { return [path] }
if (path.indexOf("/require/") == 0) { return [path] }
if (path.indexOf("/p/") == 0) { return [path] }
if (path.indexOf("/plugin/") == 0) { return ["usr/volcanos/", path.split("?")[0]] }
var ls = path.split(nfs.PS); if (ls.length == 1) { return [nfs.PWD, ls[0]] }
if (ls[0] == ice.USR) { return [ls.slice(0, 2).join(nfs.PS)+nfs.PS, ls.slice(2).join(nfs.PS)] }
return [ls.slice(0, 1).join(nfs.PS)+nfs.PS, ls.slice(1).join(nfs.PS)]
},
PathJoin: function(dir, file, ext) { file = file||""
if (file.indexOf(nfs.PS) == 0 || file.indexOf(web.HTTP) == 0) { return file }
if (dir.indexOf(nfs.SRC) == 0 || dir.indexOf(nfs.USR) == 0) { dir = nfs.P+dir }
return dir+file+(ext? nfs.PT+ext: "")
},
isDebug: function(can) { return can.misc.Search(can, log.DEBUG) == ice.TRUE },
isImage: function(can, path) { return can.base.isIn(can.base.Ext(path), "png", "jpg", "jpeg") },
isVideo: function(can, path) { return can.base.isIn(can.base.Ext(path), "mp4", "m4v", "mov", "webm") },
isAudio: function(can, path) { return can.base.isIn(can.base.Ext(path), "mp3") },
Search: function(can, key, value) { var args = this.ParseURL(can, location.href)
if (can.base.isUndefined(key)) { return args } else if (can.base.isObject(key)) {
can.core.Item(key, function(k, v) { v === ""? delete(args[k]): (args[k] = v) })
} else if (can.base.isUndefined(value)) { return args[key] } else {
value === ""? delete(args[key]): (args[key] = value)
}
location.pathname.indexOf("/chat/pod/") == 0 && delete(args["pod"])
location.pathname.indexOf("/s/") == 0 && delete(args["pod"])
var search = can.base.Args(args)
return search? (location.search = search): (location.href = location.href.split(ice.QS)[0])
},
SearchHash: function(can) { var hash = location.hash
if (arguments.length > 1) {
hash = can.core.List(arguments, function(item) {
if (can.base.isArray(item)) { return item.join(nfs.DF) }
return can.base.replaceAll(item, ":", "%3A")
}).slice(1).join(nfs.DF)
if (can.isCmdMode() || can._name == "River" || can._name == "Action") { location.hash = hash }
}
return can.core.List(can.core.Split(can.base.trimPrefix(location.hash, "#"), nfs.DF)||[], function(item) { return decodeURIComponent(item) })
},
SearchOrConf: function(can, key, def) { return can.misc.Search(can, key)||Volcanos.meta.args[key]||can.misc.sessionStorage(can, "can."+key)||can.misc.localStorage(can, "can."+key)||can.Conf(key)||def },
CookieSessid: function(can, value, path) {
return can.misc.Cookie(can, ice.MSG_SESSID+"_"+(location.port||(location.protocol == "https:"? "443": "80")), value, path)||can.misc.Cookie(can, ice.MSG_SESSID, value, path)
},
Cookie: function(can, key, value, path) {
function set(k, v) { var expires = new Date(); expires.setTime(expires.getTime() + 30*24*3600000)
document.cookie = k+mdb.EQ+v+";path="+(path||nfs.PS)+";expires="+expires.toGMTString()
}
if (can.base.isObject(key)) { for (var k in key) { set(k, key[k]) } key = undefined } if (can.base.isObject(key)) { for (var k in key) { set(k, key[k]) } key = undefined }
if (can.base.isUndefined(key)) { var cs = {}; if (!document.cookie) { return } return document.cookie.split("; ").forEach(function(item) { var ls = item.split(mdb.EQ); cs[ls[0]] = ls[1] }), cs }
if (value === "") { var expires = new Date(); expires.setTime(expires.getTime() - 10) if (key == undefined) { var cs = {}
return document.cookie = key+mdb.EQ+value+";path="+(path||nfs.PS)+";expires="+expires.toGMTString() document.cookie.split("; ").forEach(function(item) { var ls = item.split("="); cs[ls[0]] = ls[1] })
} can.base.isUndefined(value) || set(key, value) return cs
var val = (new RegExp(key+"=([^;]*);?")).exec(document.cookie); return val && val.length > 1? val[1]: ""
},
sessionStorage: function(can, key, value) {
if (can.base.isUndefined(key)) { var res = {}; can.core.Item(sessionStorage, function(name, value) { can.base.isFunc(value) || name == "length" || (res[name] = value) }); return res }
if (can.base.isArray(key)) { key = key.join(":") }
if (!can.base.isUndefined(value)) {
if (value === "") { return sessionStorage.removeItem(key) } sessionStorage.setItem(key, value)
} return can.base.Obj(sessionStorage.getItem(key))||sessionStorage.getItem(key)
},
localStorage: function(can, key, value) {
if (can.base.isUndefined(key)) { var res = {}; can.core.Item(localStorage, function(name, value) { can.base.isFunc(value) || name == "length" || (res[name] = value) }); return res }
if (!can.base.isUndefined(value)) { if (value === "") { return localStorage.removeItem(key) } localStorage.setItem(key, value) } return can.base.Obj(localStorage.getItem(key))
},
Log: function() { var args = this._args("", arguments)
if (arguments[0].indexOf && arguments[0].indexOf("on") == 0) { args[1] = this.FileLine((arguments[0] == "onremote"? 1: 1)+this._skip) }
for (var i in arguments) { var arg = arguments[i]; if (arg && arg.Option && arg.Option("log.caller")) { args[1] = arg.Option("log.caller") } }
console.log.apply(console, args), this._signal(args)
},
Info: function() { var args = this._args(log.INFO, arguments); console.info.apply(console, args), this._signal(args) },
Warn: function() { var args = this._args(log.WARN, arguments); console.warn.apply(console, args), this._signal(args); },
Error: function() { var args = this._args(log.ERROR, arguments); args.push(lex.NL, this._stacks().slice(1).join(lex.NL)), console.error.apply(console, args), this._signal(args); debugger },
Debug: function() { var args = this._args(log.DEBUG, arguments); args.push(lex.NL, this._stacks().slice(1, 4).join(lex.NL)), console.debug.apply(console, args), this._signal(args) },
Trace: function() { var output = false
for (var i in arguments) { var arg = arguments[i]; if (arg.Conf && arg.Conf("log.trace") == ice.TRUE || arg.Option && arg.Option("log.trace") == ice.TRUE) { output = true } } if (!output) { return }
var args = this._args(log.TRACE, arguments); args.push(lex.NL, this._stacks().slice(1, 4).join(lex.NL)), console.debug.apply(console, args), this._signal(args)
},
FileLine: function(depth, length) { var file = this.fileLine(depth+1, length||9); return file.link },
fileLine: function(depth, length) { var list = this._stacks()
function split(i) { if (!list[i]) { return {} }
var ls = /(https*:\/\/[^/]+)*([^:]+):([0-9]+):([0-9]+)/.exec(list[i]); if (!ls) { return {} }
var name = ""; list[i].lastIndexOf(lex.TB) > 0 && (name = list[i].split(lex.TB).pop())
if (ls[0].indexOf(ice.QS) > -1) { ls[0] = ls[0].split(ice.QS)[0]+nfs.DF+ls[3]+nfs.DF+ls[4] }
return {name: name, link: ls[0], path: ls[2], file: ls[2].split(nfs.PS).slice(-length).join(nfs.PS), line: ls[3], cols: ls[4]}
} }
if (depth < 0) { var current = split(-depth)
for (var i = -depth+1; i < list.length; i++) { var pos = split(i); if (pos.path != current.path) { return pos } } value != undefined && set(key, value)
} return split(depth)||{} var val = (new RegExp(key+"=([^;]*);?")).exec(document.cookie)
return val && val.length > 0? val[1]: ""
}),
SearchOrConf: function(can, key, def) { can.base.getValid(can.misc.Search(can, key), can.Conf(key), def) },
Search: shy("请求参数", function(can, key, value) { var args = {}
if (value == undefined && can.base.isString(key)) {
var ls = location.pathname.split(ice.PS); if (ls[1] == chat.SHARE) { args[chat.SHARE] = ls[2] }
for (var i = 2; i < ls.length; i += 2) { if ({"pod": true, "cmd": true}[ls[i]]) { args[ls[i]] + ls[i+1] } }
}
location.search && location.search.slice(1).split("&").forEach(function(item) { var x = item.split("=")
x[1] != "" && (args[x[0]] = decodeURIComponent(x[1]))
})
if (can.base.isObject(key)) {
can.core.Item(key, function(key, value) {
if (value != undefined) { args[key] = value } args[key] == "" && delete(args[key])
})
} else {
if (key == undefined) { return args }
if (value == undefined) { return args[key] }
args[key] = value, args[key] == "" && delete(args[key])
}
return location.search = can.core.Item(args, function(key, value) { return key+"="+encodeURIComponent(value) }).join("&")
}),
MergeURL: shy("地址链接", function(can, objs, clear) {
var path = location.pathname; objs._path && (path = objs._path, delete(objs._path))
objs && objs.pod && (path = "/chat/pod/"+objs.pod, delete(objs.pod))
return can.base.MergeURL(location.origin+path+(clear?"":location.search), objs)
}),
runAction: function(can, msg, cmds, cb, list) {
if (cmds[0] == ctx.ACTION && list[cmds[1]]) { return list[cmds[1]](cmds.slice(2)), true }
if (list[cmds[0]]) { return list[cmds[0]](cmds.slice(1)), true }
},
concat: function(can, to, from) { to = to||[], from = from||[]
if (from[0] == ctx.ACTION && from[1] == ice.RUN && can.onengine.plugin.meta[from[2]]) { return from }
if (can.onengine.plugin.meta[from[0]]) { return from }
if (from[0] == "_search") { return from }
return to.concat(from)
},
proto: function(sub, sup) {
if (navigator.userAgent.indexOf("MSIE") > -1) {
for (var k in sup) { sub[k] = sub[k]||sup[k] }
} else {
sub.__proto__ = sup
}
return sub
},
Log: function() {
var args = [this._time(), this.FileLine(2, 3)]
for (var i in arguments) { args.push(arguments[i]) }
console.log.apply(console, args)
},
Info: function() {
var args = [this._time(), this.FileLine(2, 3)]
for (var i in arguments) { args.push(arguments[i]) }
console.log.apply(console, args)
},
Warn: function() {
var args = [this._time(), this.FileLine(2, 3), "warn"]
for (var i in arguments) { args.push(arguments[i]) }
args.push(ice.NL, this._fileLine().split(ice.NL).slice(2).join(ice.NL))
console.log.apply(console, args)
},
Debug: function() {
var args = [this._time(), this.FileLine(2, 3), "debug"]
for (var i in arguments) { args.push(arguments[i]) }
args.push(this.fileLine(2, 3))
console.log.apply(console, args)
navigator.userAgent.indexOf("Mobile") > -1 && alert(JSON.stringify(args.join(ice.SP)))
},
FileLine: function(depth, length) {
return this.fileLine(depth+1).split(ice.PS).slice(3).slice(-length).join(ice.PS).split(")")[0]
},
fileLine: function(depth) {
return (this._fileLine().split(ice.NL)[1+depth]||"").trim()
},
_fileLine: function() { var obj = {}
Error.captureStackTrace && Error.captureStackTrace(obj, arguments.callee)
return obj.stack || ""
}, },
_stacks: function(n, s) { var list = ((s||(new Error())).stack||"").split(lex.NL).slice(typeof n == "undefined"? 2: n)
for (var i = 0; i < list.length; i++) { var ls = list[i].trim().split(lex.SP)
list[i] = ls.pop().trim()
if (list[i][0] == "(") { list[i] = list[i].slice(1, -1) } // ")"
list[i] = " "+list[i]; if (ls.length > 1) { list[i] += " "+ls.pop() }
list[i] = list[i].replace(/\?[^:]+/, "").replace(location.origin, "")
} return list
}, _stack: function() { return ((new Error()).stack||"").split(lex.NL).slice(2) },
_time: function() { var now = new Date() _time: function() { var now = new Date()
var hour = now.getHours(); hour < 10 && (hour = "0"+hour) var hour = now.getHours()
var minute = now.getMinutes(); minute < 10 && (minute = "0"+minute) if (hour < 10) { hour = "0"+hour }
var second = now.getSeconds(); second < 10 && (second = "0"+second) var minute = now.getMinutes()
var mill = now.getMilliseconds(); mill < 10 && (mill = "00"+mill) || mill < 100 && (mill = "0"+mill) if (minute < 10) { minute = "0"+minute }
return [hour, minute, second].join(nfs.DF)+nfs.PT+mill var second = now.getSeconds()
if (second < 10) { second = "0"+second }
return hour+":"+minute+":"+second
}, },
_args: function(level, arg) { var args = [this._time(), this.FileLine(this._skip+1, 3)].concat(level? [level]: [])
for (var i in arg) { arg[i] != undefined && args.push(arg[i]) } return args
},
_signal: function(args) { this._list.push(args) }, _list: [], _skip: navigator && navigator.userAgent.indexOf("Chrome") > -1? 3: 3,
}) })

View File

@ -1,526 +1,416 @@
Volcanos("page", { Volcanos("page", {help: "用户界面", ClassList: {
ClassList: { has: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): []
has: function(can, target, key) { var list = target.className && target.className.split? target.className.split(lex.SP): []; return list.indexOf(key) > -1 }, return list.indexOf(key) > -1
add: function(can, target, key) { Array.isArray(key) && (key = key.join(lex.SP))
var list = target.className? target.className.split(lex.SP): []; can.core.List(can.core.Split(key, " .,"), function(key) { can.base.AddUniq(list, key) })
var value = list.join(lex.SP).trim(); return value != target.className && (target.className = value), value
}, },
del: function(can, target, key) { var list = target.className? target.className.split(lex.SP): [] add: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): []
return target.className = can.core.List(list, function(value) { return value == key? undefined: value }).join(lex.SP).trim() var value = can.base.AddUniq(list, key).join(ice.SP).trim()
return value != obj.className && (obj.className = value), value
},
del: function(can, obj, key) { var list = obj.className? obj.className.split(ice.SP): []
return obj.className = can.core.List(list, function(value) { return value == key? undefined: value }).join(ice.SP).trim()
},
set: function(can, obj, key, condition) {
return (condition? this.add(can, obj, key): this.del(can, obj, key)).indexOf(key) > -1
},
neg: function(can, obj, key) {
return (this.has(can, obj, key)? this.del(can, obj, key): this.add(can, obj, key)).indexOf(key) > -1
}, },
set: function(can, target, key, condition) {
return (condition? this.add(can, target, key): this.del(can, target, key)).indexOf(key) > -1 },
neg: function(can, target, key) { return (this.has(can, target, key)? this.del(can, target, key): this.add(can, target, key)).indexOf(key) > -1 },
tag: function(can, target) { return [document.body.tagName.toLowerCase()].concat(document.body.classList).join(lex.PT) }
}, },
SelectArgs: function(can, target, key, cb) { SelectArgs: function(can, option, key, cb) {
if (can.base.isUndefined(target)) { return can.page.SelectArgs(can, can._option, "").concat(can.page.SelectArgs(can, can._action, "")) } if (can.base.isUndefined(key)) { var value = {}
// if (can.base.isUndefined(key)) { var value = {}; can.page.SelectArgs(can, target, "", function(item) { item.name && item.value && (value[item.name] = item.value) }); return [value] } can.page.SelectArgs(can, option, "", function(item) {
if (can.base.isUndefined(key)) { var value = {}; can.page.SelectArgs(can, target, "", function(item) { item.name && (value[item.name] = item.value||"") }); return [value] } item.name && item.value && (value[item.name] = item.value)
if (can.base.isObject(key)) { return can.core.Item(key, function(key, value) { can.page.SelectArgs(can, target, key, value) }), [key] } }); return [value]
if (!can.base.isFunc(cb)) { var value = cb; cb = function(target) { }
can.base.isUndefined(value) || can.page.Select(can, target.parentNode, "span.value", function(target) { target.innerText = value }) if (can.base.isObject(key)) {
return target.name && (can.base.isUndefined(value)? target.value: (target.value = value))||"" return can.core.Item(key, function(key, value) { can.page.SelectArgs(can, option, key, value) }), [key]
}
if (!can.base.isFunc(cb)) { var value = cb; cb = function(item) { if (item.type == html.BUTTON) { return }
return item.name && (can.base.isUndefined(value)? item.value: (item.value = value))||""
} } } }
if (key.indexOf(nfs.PT) > -1) { return [""] } key && can.base.isString(cb) && can.page.Select(can, target, "div.item."+key+">span.value", cb) if (key.indexOf(ice.PT) > -1) { return [""]}
return can.page.Select(can, target, key? "select[name="+key+"],"+"input.select[type=button][name="+key+"],"+"input[type=text][name="+key+"],"+"textarea[name="+key+"]": ".args", cb) return can.page.Select(can, option, key? "textarea[name="+key+"],"+"input[name="+key+"],"+"select[name="+key+"]": ".args", cb)
}, },
SelectInput: function(can, target, name, cb) { return can.page.Select(can, target, "input[name="+name+"]", cb)[0] }, SelectAll: shy("选择节点", function(can, target, key, cb, interval, cbs) {
SelectChild: function(can, target, key, cb) { return can.core.List(can.page.Select(can, target, key||"*", function(node) { if (node.parentNode == target) { return node } }), cb) }, can.page.Select(can, target, html.IFRAME, function(item) {
SelectOne: function(can, target, key, cb) { return can.page.Select(can, target, key, function(target, index) { return index == 0 && can.base.isFunc(cb) && cb(target), target })[0] }, can.page.SelectAll(can, item.contentWindow.document.body, key, cb, interval, cbs)
Select: function(can, target, key, cb, interval, cbs) { target = target || document.body, key = key||"*" })
return can.core.List(key == nfs.PT? [target]: target.querySelectorAll(can.page.Keys(key)), cb, interval, cbs) return can.core.List(target && target.querySelectorAll(key), cb, interval, cbs)
}, }),
Modify: function(can, target, value) { target = can.base.isString(target)? document.querySelector(target): target; if (!target) { return } Select: shy("选择节点", function(can, target, key, cb, interval, cbs) { if (key == ice.PT) { cb(target); return [] }
can.base.isString(value)? (target.innerHTML = value): can.core.Item(value, function(key, val) { if (key == "view") { return } return can.core.List(target && target.querySelectorAll(can.page.Keys(key)), cb, interval, cbs)
key == "className" && can.base.isArray(val) && (val = val.join(lex.SP)), !can.base.isObject(val)? (target[key] = val): can.core.Item(val, function(k, v) { }),
if (can.base.isIn(k, "height", "width", "min-height", "max-height", "min-width", "max-width") && parseInt(v) < 0) { return target[key] && (target[key][k] = "") } Modify: shy("修改节点", function(can, target, value) { target = target||{}
if (can.base.isIn(k, "height", "width", "min-height", "max-height", "min-width", "max-width", "left", "top", "right", "bottom", "margin-left", "margin-top", "margin", "padding", "font-size") && v && (can.base.isNumber(v) || !can.base.endWith(v, "px"))) { v += "px" } target = can.base.isObject(target)? target: document.querySelector(target)
can.base.isString(value)? (target.innerHTML = value): can.core.Item(value, function(key, val) {
!can.base.isObject(val)? (target[key] = val): can.core.Item(val, function(k, v) {
var size = {
"height": true, "max-height": true, "min-height": true,
"width": true, "max-width": true, "min-width": true,
}
if (size[k] && parseInt(v) < 0) { return target[key] && (target[key][k] = "") }
var size = {
"margin-top": true, "margin-left": true, "font-size": true,
"left": true, "right": true, "top": true, "bottom": true,
"height": true, "max-height": true, "min-height": true,
"width": true, "max-width": true, "min-width": true,
}
if (size[k] && v && (can.base.isNumber(v) || v.indexOf && v.indexOf("px") == -1)) { v += "px" }
target[key] && (target[key][k] = v) target[key] && (target[key][k] = v)
}) })
}); return target
},
Create: function(can, key, value) { return can.page.Modify(can, document.createElement(key), value) },
Remove: function(can, target) { return target && target.parentNode && target.parentNode.removeChild(target), target },
Append: function(can, target, key, value) { if (can.base.isString(key)) { var res = can.page.Create(can, key, value); return target.appendChild(res), res }
value = value||{}, can.core.List(key, function(item) { if (!item) { return } if (item.nodeName) { target.appendChild(item); return }
if (can.base.isString(item)) { item = {view: [item]} }
var type = item.type||html.DIV, data = item.data||{}, name = item.name||data.name||""; data.className = data.className||""
can.core.Item(item, function(key, value) { switch (key) {
case mdb.TYPE: break
case mdb.NAME: break
case mdb.DATA: break
case mdb.LIST: break
case html.CLICK: data.onclick = item.click; break
case html.INNER: data.innerHTML = item.inner; break
default: can.base.isUndefined(item[key]) || (data[key] = item[key])
} })
if (item.view) { var list = can.core.List(item.view); if (can.base.isArray(list[0])) {
list[0] = can.base.replaceAll(can.core.List(list[0], function(v) { return v }).join(lex.SP), ".", " ")
}
list[0] && can.page.ClassList.add(can, data, list[0]), type = list[1]||type, data.innerHTML = list[2]||data.innerHTML||"", name = list[3]||name
} else if (item.text) { var list = can.core.List(item.text); if (can.base.isArray(list[2])) { list[2] = list[2].join(lex.SP) }
data.innerHTML = list[0]||data.innerHTML||"", type = list[1]||item.type||html.SPAN, list[2] && can.page.ClassList.add(can, data, list[2])
} else if (item.icon) { var list = can.core.List(item.icon)
if (icon[item.icon]) {
type = "i", data.className = icon[item.icon]
} else if (can.page.unicode[list[0]]) {
type = html.SPAN, name = list[0], data.className = "icon "+list[0], data.innerText = can.page.unicode[list[0]]
} else {
type = "i", data.className = list[0]
}
} else if (item.button) { var list = can.core.List(item.button); type = html.BUTTON, name = list[0]||name, data.innerText = can.user.trans(can, name)
data.onclick = function(event) { can.misc.Event(event, can, function(msg) { can.base.isFunc(list[1]) && list[1](event, name), can.onkeymap.prevent(event) }) }
} else if (item.select) { var list = item.select; type = html.SELECT, name = list[0][0], data.className = data.className||list[0][0]
data.onchange = function(event) { can.misc.Event(event, can, function(msg) { can.base.isFunc(list[1]) && list[1](event, event.target.value, name) }) }
item.list = list[0].slice(1).map(function(value) { return {type: html.OPTION, value: value, inner: can.user.trans(can, value)} })
} else if (item.input) { var list = can.core.List(item.input); type = html.INPUT, name = list[0], data.className = data.className||list[0], data.type = data.type||html.TEXT
data.onkeydown = function(event) { can.base.isFunc(list[1]) && list[1](event) }
data.onkeyup = function(event) { can.base.isFunc(list[2]) && list[2](event) }
} else if (item.username) { var list = can.core.List(item.username); type = html.INPUT, name = list[0]||name||html.USERNAME
// data.className = list[1]||data.className||name, data.autocomplete = data.autocomplete||html.USERNAME
data.className = list[1]||data.className||name
} else if (item.password) { var list = can.core.List(item.password); type = html.INPUT, name = list[0]||name||html.PASSWORD
// data.className = list[1]||data.className||name, data.type = html.PASSWORD, data.autocomplete = data.autocomplete||"current-password"
data.className = list[1]||data.className||name, data.type = html.PASSWORD
} else if (item.img) {
var list = can.core.List(item.img); type = html.IMG, data.src = list[0]
if (can.base.contains(data.src, ".jpg")) { data.className = data.className||"jpg" }
} else if (item.row) { type = html.TR, item.list = item.row.map(function(text) { return {text: [text, item.sub||html.TD]} })
} else if (item.th) { type = html.TR, item.list = item.th.map(function(text) { return {text: [text, html.TH]} })
} else if (item.td) { type = html.TR, item.list = item.td.map(function(text) { return can.base.isObject(text)? text: {text: [text||"", html.TD]} }) }
// if (type == html.SELECT) { data.title = can.user.trans(can, data.title||name) }
if (type == html.INPUT) {
if (data.type == html.TEXT || data.type == html.PASSWORD || !data.type) {
// data.autocomplete = data.autocomplete||"new-password"
if (!can.user.isMobile) {
data.placeholder = (data.placeholder||name||"").split(nfs.PT).pop(), data.title = can.user.trans(can, data.title||data.placeholder, null, html.INPUT)
}
} else if (data.type == html.BUTTON) {
// data.value = can.user.trans(can, data.value)
}
}
if (type == html.TEXTAREA) {
if (!can.user.isMobile) {
data.placeholder = can.user.trans(can, (data.placeholder||name||"").split(nfs.PT).pop(), null, html.INPUT)
}
}
can.core.List(["className", "placeholder", "title"], function(key) { data[key] || delete(data[key]) })
name && (data.name = name); var node = can.page.Create(can, type, data)
value[data.type] = node
value[type] = value[name] = value[can.core.Split(data.className)[0]] = node, value._target = value._target||node, value.first = value.first||node, value.last = node
item.list && can.page.Append(can, node, item.list, value), target && target.appendChild && target.appendChild(node), can.base.isFunc(item._init) && item._init(node, value)
}); return value },
Appends: function(can, target, key, value) { return target.innerHTML = "", can.page.Append(can, target, key, value) },
AppendData: function(can, target, prefix, key, value, cb) { var open = can.page.unicode.opens, close = can.page.unicode.closes
function short(value, length) {
if (length == undefined) {
value.indexOf(lex.NL) > -1 && (value = value.trim().split(lex.NL)[0]+can.page.unicode.inner)
return can.page.trans(can, value)
} else {
if (length > 5) {
return can.page.unicode.inner
}
} return value
}
function show(value, deep) { deep = deep == undefined? 2: 0; switch (typeof value) {
case code.OBJECT: if (!value) { return {} }
if (value._path) { return {value: "@\""+value._path+"\""} }
if (value.tagName) { return {type: nfs.TARGET, value: "$"+value.tagName.toLowerCase()+(value.className? nfs.PT+value.className.replaceAll(lex.SP, nfs.PT):"")} }
if (deep < 0) { return {value: value.length == undefined? "{"+can.page.unicode.inner+"}": "["+can.page.unicode.inner+"]"} }
if (value.length != undefined) { return {value: (value.length > 3? value.length+lex.SP: "")+"["+can.core.List(value, function(value, index) { if (index < 6) { return short(show(value, deep-1).value, index+1) } }).join(mdb.FS)+"]"} }
return {value: "{"+can.core.Item(value, function(key, val, list) { if (value.hasOwnProperty(key) && val && list.length < 7) { return short(key+nfs.DF+show(val, deep-1).value, list.length) } }).join(mdb.FS)+"}"}
case code.STRING: return {open: "s", close: "s", value: "\""+(deep == 2? value.replaceAll("\n", "\\n"): short(value))+"\""}
case code.NUMBER: return {open: "n", close: "n", value: value}
case code.BOOLEAN: return {open: "b", close: "b", value: value}
case code.FUNCTION: return {open: "f", close: "f", value: deep == 2? (""+value).split(lex.NL)[0]: "function(...) {...}"}
default: return {value: value}
} } var loaded = false, _show = show(value); _show.open = _show.open||open, _show.close = _show.close||close
var ui = can.page.Append(can, target, [!key && value.tagName? can.page.AppendView(can, value): {view: [[html.ITEM, _show.type||typeof(value)], key == ""? html.SPAN: html.DIV], list: [
{view: [mdb.ICON, html.SPAN, _show.close+lex.SP]}, {view: [mdb.NAME, html.SPAN, key || key === 0? key+lex.SP: ""]}, {view: [mdb.VALUE, html.SPAN, _show.value]},
], onclick: function() {
cb && cb(prefix, value); if (!can.base.isIn(typeof value, code.OBJECT, code.FUNCTION)) { return }
ui.icon.innerText = (can.onmotion.toggle(can, ui.list)? _show.open: _show.close)+lex.SP
if (typeof value == code.FUNCTION) { return ui.list.innerText = value.toString() }
if (loaded) { return } loaded = true, ui.icon.innerText = _show.open+lex.SP
if (value.tagName) { can.page.Append(can, ui.list, [can.page.AppendView(can, value)]), can.onappend.style(can, mdb.VIEW, ui.list)
can.core.List(can.core.Item(target, function(key, value) { if (["textContent", "innerHTML", "outerHTML"].indexOf(key) > -1 || typeof value == code.FUNCTION || key.toUpperCase() == key) { return } return key }).sort(), function(key) {
target[key] && can.page.AppendData(can, ui.list, can.core.Keys(prefix, key), key, target[key], cb)
})
} else if (value.length != undefined) {
can.core.List(value, function(value, index) { can.page.AppendData(can, ui.list, can.core.Keys(prefix, index), index, value, cb) })
} else {
can.core.List(can.core.Item(value, function(key, val) { if (
(value["preventDefault"] && val && typeof val != code.FUNCTION) || (value["responseText"] && val && typeof val != code.FUNCTION) ||
value.hasOwnProperty(key) && val) { return key } }).sort(), function(key) { can.page.AppendData(can, ui.list, can.core.Keys(prefix, key), key, value[key], cb) })
var key = "__proto__"; value[key] && can.core.Item(value[key]).length > 0 && can.page.AppendData(can, ui.list, can.core.Keys(prefix, key), key, value[key], cb)
}
}}, {view: [[html.LIST, _show.type||typeof(value), html.HIDE]]}]); return ui
},
AppendView: function(can, target, tag, list, loaded, cb) {
function field(target) { return target? can.core.List(target.attributes, function(item) {
return item.value == ""? undefined: {type: html.SPAN, list: [{text: lex.SP}, {text: item.name}, {text: mdb.EQ}, {className: code.STRING, text: JSON.stringify(item.value)}]}
}): [] }
var ui = {}; tag = tag||target.tagName.toLowerCase(), isclose = tag != mdb.META && tag != web.LINK, _field = field(target)
var inner = list || target.children.length > 0 && target.innerText != target.innerHTML? can.page.unicode.inner: ""
return {view: mdb.VIEW, list: [
{view: [[html.ITEM, target.tagName && target.tagName.toLowerCase()]], list: [
{text: [(inner? can.page.unicode.closes: ""), "", html.TOGGLE], _init: function(target) { ui.toggle = target }},
{className: code.KEYWORD, text: can.page.trans(can, ice.LT)}, {className: code.KEYWORD, text: tag}, {type: html.SPAN, list: _field}, {className: code.KEYWORD, text: can.page.trans(can, ice.GT)},
inner? {text: [inner, "", code.INNER], _init: function(target) { ui.inner = target }}:
target.innerText? {text: target.innerText, _init: function(target) { ui.inner = target }}:
null,
{className: code.KEYWORD, text: can.page.trans(can, ice.LT+nfs.PS+tag+ice.GT), _init: function(target) { ui._close = target }},
], onclick: inner && function(event) {
ui.toggle.innerText = (can.onmotion.toggle(can, ui.list)? can.page.unicode.opens: can.page.unicode.closes)+lex.SP
if (target.children.length == 0 && !list) { return }
ui.inner && can.onmotion.toggle(can, ui.inner), can.onmotion.toggle(can, ui.close), can.onmotion.toggle(can, ui._close)
if (!loaded) { if (can.page.tagis(target, ctx.STYLE, nfs.SCRIPT)) { can.page.Append(can, ui.list, [{text: target.innerHTML}]) } else {
can.page.Append(can, ui.list, can.core.List(target.children, function(node) { return can.page.AppendView(can, node, "", null, false, cb) }))
} } loaded = true, can.base.isFunc(cb) && cb(target)
}, onmouseenter: function() { can.page.Select(can, document.body, nfs.PT+html.PICKER, function(target) { can.page.ClassList.del(can, target, html.PICKER) })
!can.page.tagis(target, nfs.SCRIPT) && can.onappend.style(can, html.PICKER, target)
}, _init: function(target) { can.onmotion.delay(can, function() { loaded && target.click() }) }},
inner && {view: [[html.LIST, html.HIDE]], _init: function(target) { ui.list = target }, list: list},
inner && {view: [[html.ITEM, html.HIDE]], list: [{text: ["", "", html.TOGGLE]}, {className: code.KEYWORD, text: can.page.trans(can, ice.LT+nfs.PS+tag+ice.GT)}], _init: function(target) { ui.close = target }},
]}
},
AppendStyle: function(can, style) {
var styleElement = document.createElement('style'); styleElement.type = 'text/css'
document.getElementsByTagName('head')[0].appendChild(styleElement)
styleElement.appendChild(document.createTextNode(style))
},
AppendTable: function(can, msg, target, list, cb) { if (!msg.append||msg.append.length == 0) { return }
var ui = can.page.Append(can, target, [{type: html.TABLE, list: [
{type: "colgroup", list: can.core.List(list, function(key) { if (key[0] != "_") {
try { var value = can.Option(key) } catch (e) {}
if (value == undefined) { return {view: [key, "col"]} } return {view: [[key, "option"], "col"]}
} }) }, {type: html.THEAD}, {type: html.TBODY},
]}])
var option = can.core.Item(can.Option())
can.page.Append(can, ui.thead, [{type: html.TR, data: {dataset: {index: -1}}, list: can.core.List(list, function(key) {
if (key[0] != "_") { return {className: option.indexOf(key) > -1? ice.MSG_OPTION: key == ctx.ACTION? ctx.ACTION: "", type: html.TH, list: [{text: can.user.trans(can, key, null, html.INPUT)}, {icon: "bi bi-sort-down-alt"}, {icon: "bi bi-sort-up"}]} }
}) }])
can.page.Append(can, ui.tbody, can.core.List(msg.Table(), function(item, index, array) {
return {dataset: {index: index}, className: item[mdb.STATUS], td: can.core.List(list, function(key) { if (key[0] != "_") { return cb(can.page.Color(item[key]).trim(), key, index, item, array) } }) }
}))
if (msg.Option(ice.TABLE_CHECKBOX) == ice.TRUE && !msg.IsDetail()) { can.onappend.checkbox(can, ui._target, msg), can.onappend.style(can, html.CHECKBOX, ui._target) }
return can.page.OrderTable(can, ui._target)
},
OrderTable: function(can, table) { can.page.Select(can, table, html.TH, function(th, index) { th.onclick = function(event) {
var dataset = event.currentTarget.dataset
can.onmotion.select(can, th.parentNode, html.TH, th)
can.page.RangeTable(can, table, index, (dataset["asc"] = (dataset["asc"] == "1") ? 0: 1) == "1")
} }); return table },
RangeTable: function(can, table, index, asc) { index = can.base.isArray(index)? can.core.List(index, function(item) { if (item > -1) { return item } }): [index]; if (index.length == 0) { return }
var list = can.page.Select(can, table, html.TR, function(tr) { if (can.page.isDisplay(tr)) { return tr } }).slice(1)
var is_time = true, is_number = true; can.core.List(list, function(tr) { var text = tr.childNodes[index[0]].innerHTML;
is_time = is_time && Date.parse(text) > 0, is_number = is_number && !isNaN(parseFloat(text||"0"))
}) })
var num_list = can.core.List(list, function(tr) { var text = tr.childNodes[index[0]].innerHTML; return is_time? Date.parse(text): is_number? can.base.ParseSize(text)||0: text }) return target
function less(a, b) { }),
if (can.base.endWith(a, nfs.PS) && !can.base.endWith(b, nfs.PS)) { return true } Remove: shy("删除节点", function(can, target) {
if (!can.base.endWith(a, nfs.PS) && can.base.endWith(b, nfs.PS)) { return false } return target && target.parentNode && target.parentNode.removeChild(target), target
return a < b }),
Create: shy("创建节点", function(can, key, value) {
return can.page.Modify(can, document.createElement(key), value)
}),
Append: shy("添加节点", function(can, target, key, value) { value = value||{}
if (can.base.isString(key)) { var res = can.page.Create(can, key, value); return target.appendChild(res), res }
can.core.List(key, function(item, index) { if (!item) { return }
if (can.base.isString(item)) { target.innerHTML = item; return }
if (item.nodeName) { target.appendChild(item); return }
// 基本结构: type name data list
var type = item.type||html.DIV, data = item.data||{}
var name = item.name||data.name||""
// 数据调整
can.core.Item(item, function(key, value) {
switch (key) {
case mdb.TYPE: break
case mdb.NAME: break
case mdb.DATA: break
case mdb.LIST: break
case html.INNER: data.innerHTML = item.inner; break
case html.CLICK: data.onclick = item.click; break
default: data[key] = item[key]
}
})
// 基本类型: view text button select input username password
// 基本类型: img row th td
if (item.view) { var list = can.core.List(item.view)
if (can.base.isArray(list[0])) { list[0] = list[0].join(ice.SP) }
list[0] && can.page.ClassList.add(can, data, list[0])
type = list[1]||html.DIV
data.innerHTML = list[2]||data.innerHTML||""
name = name||list[3]||""
} else if (item.text) { var list = can.core.List(item.text)
data.innerHTML = list[0]||data.innerHTML||""
type = list[1]||html.SPAN
list[2] && can.page.ClassList.add(can, data, list[2])
} else if (item.button) { var list = can.core.List(item.button)
type = html.BUTTON, name = name||list[0]
data.innerText = can.user.trans(can, list[0]), data.onclick = function(event) {
can.base.isFunction(list[1]) && list[1](event, name)
can.onkeymap.prevent(event)
return true
}
} else if (item.select) { var list = item.select
type = html.SELECT, data.name = name = name||list[0][0]
data.title = can.user.trans(can, data.title||name)
data.className = data.className||list[0][0]||""
item.list = list[0].slice(1).map(function(value) {
return {type: html.OPTION, value: value, inner: can.user.trans(can, value)}
})
data.onchange = function(event) {
can.base.isFunction(list[1]) && list[1](event, event.target.value, name)
}
} else if (item.input) { var list = can.core.List(item.input)
type = html.INPUT, name = name||list[0]||"", data.name = data.name||name
data.className = data.className||data.name
data.autocomplete = "off"
data.onfocus = data.onfocus||function(event) {
event.target.setSelectionRange(0, -1)
}
data.onkeydown = function(event) {
can.base.isFunction(list[1]) && list[1](event)
}
data.onkeyup = function(event) {
can.base.isFunction(list[2]) && list[2](event)
}
} else if (item.username) { var list = can.core.List(item.username)
type = html.INPUT, name = name||list[0]||html.USERNAME, data.name = data.name||name
data.className = list[1]||data.className||data.name
data.autocomplete = data.autocomplete||html.USERNAME
} else if (item.password) { var list = can.core.List(item.password)
type = html.INPUT, name = name||list[0]||html.PASSWORD, data.name = data.name||name
data.className = list[1]||data.className||data.name
data.autocomplete = data.autocomplete||"current-password"
data.type = html.PASSWORD
} else if (item.img) { var list = can.core.List(item.img)
type = html.IMG, data.src = list[0]
} else if (item.row) { type = html.TR
item.list = item.row.map(function(text) { return {text: [text, item.sub||html.TD]} })
} else if (item.th) { type = html.TR
item.list = item.th.map(function(text) { return {text: [text, html.TH]} })
} else if (item.td) { type = html.TR
item.list = item.td.map(function(text) { return {text: [text, html.TD]} })
}
// 语言转换
if (type == html.INPUT) { data.type == html.BUTTON && (data.value = can.user.trans(can, data.value))
if (data.type == html.TEXT||data.type == html.PASSWORD||!data.type) { data.autocomplete = data.autocomplete||"off"
data.placeholder = can.user.trans(can, (data.placeholder||data.name||"").split(ice.PT).pop())
data.title = can.user.trans(can, data.title||data.placeholder)
}
}
if (type == html.TEXTAREA) {
data.placeholder = can.user.trans(can, (data.placeholder||data.name||"").split(ice.PT).pop())
}
// 创建节点
!data.name && item.name && (data.name = item.name)
var node = can.page.Create(can, type, data)
// 创建索引
name = name||data.className||type||""
value[name||""] = value[data.className||""] = value[type] = node
value.first = value.first||node, value.last = node
value._target = value._target||node
// 递归节点
item.list && can.page.Append(can, node, item.list, value)
target && target.appendChild && target.appendChild(node)
can.base.isFunc(item._init) && item._init(node)
})
return value
}),
Appends: shy("添加节点", function(can, target, key, value) {
return target.innerHTML = "", can.page.Append(can, target, key, value)
}),
AppendTable: shy("添加表格", function(can, msg, target, list, cb) {
if (!msg.append||msg.append.length == 0) {return}
var table = can.page.Append(can, target, html.TABLE)
can.page.Append(can, table, [{type: html.TR, data: {dataset: {index: -1}}, list:
can.core.List(list, function(key) {
return key[0] == "_"? undefined: {text: [key.trim(), html.TH]}
})
}])
can.page.Append(can, table, can.core.List(msg.Table(), function(line, index, array) {
var _list = can.core.List(list, function(key) { if (key.indexOf("_") == 0) { return }
return cb(can.page.Color(line[key]).trim(), key, index, line, array)
})
return _list.length > 0? {type: html.TR, dataset: {index: index}, list: _list}: undefined
}))
return can.page.OrderTable(can, table)
}),
OrderTable: function(can, table) {
can.page.Select(can, table, html.TH, function(th, index) {
th.onclick = function(event) { var dataset = event.target.dataset
dataset["sort_asc"] = (dataset["sort_asc"] == "1") ? 0: 1
can.page.RangeTable(can, table, index, dataset["sort_asc"] == "1")
}
})
return table
},
RangeTable: function(can, table, index, sort_asc) {
var list = can.page.Select(can, table, html.TR, function(tr) {
return tr.style.display == html.NONE||can.page.ClassList.has(can, tr, "hide")? null: tr
}).slice(1)
index = can.base.isObject(index)? index: [index]
index = can.core.List(index, function(item) { if (item > -1) { return item} })
if (index.length == 0) { return }
var is_time = true, is_number = true
can.core.List(list, function(tr) {
var text = tr.childNodes[index[0]].innerText
is_time = is_time && Date.parse(text) > 0
is_number = is_number && !isNaN(parseInt(text))
})
var num_list = can.core.List(list, function(tr) {
var text = tr.childNodes[index[0]].innerText
return is_time? Date.parse(text):
is_number? can.base.ParseSize(text): text
})
function isless(a, b, index) {
if (a.childNodes[index[0]] && b.childNodes[index[0]]) {
if (a.childNodes[index[0]].innerText < b.childNodes[index[0]].innerText) { return true }
if (a.childNodes[index[0]].innerText > b.childNodes[index[0]].innerText) { return false }
}
return index.length > 1 && isless(a, b, index.slice(1))
} }
function isless(a, b, index) { if (a.childNodes[index[0]] && b.childNodes[index[0]]) {
if (a.childNodes[index[0]].innerHTML < b.childNodes[index[0]].innerHTML) { return true } // 选择排序
if (a.childNodes[index[0]].innerHTML > b.childNodes[index[0]].innerHTML) { return false }
} return index.length > 1 && isless(a, b, index.slice(1)) }
for (var i = 0; i < num_list.length; i++) { var min = i for (var i = 0; i < num_list.length; i++) { var min = i
for (var j = i+1; j < num_list.length; j++) { for (var j = i+1; j < num_list.length; j++) {
if (asc? less(num_list[min], num_list[j]): less(num_list[j], num_list[min])) { min = j; continue } if (num_list[min] == num_list[j] && index.length > 1 && list[index[1]]) {
if (num_list[min] == num_list[j] && index.length > 1) { if (asc? isless(list[min], list[j], index.slice(1)): isless(list[j], list[min], index.slice(1))) { min = j } } if (sort_asc? isless(list[min], list[j], index.slice(1)): isless(list[j], list[min], index.slice(1))) {
min = j
}
} else if (sort_asc? num_list[min] < num_list[j]: num_list[j] < num_list[min]) {
min = j
}
} }
if (min != i) { if (min != i) {
var temp = num_list[i]; num_list[i] = num_list[min]; num_list[min] = temp var temp = num_list[i]; num_list[i] = num_list[min]; num_list[min] = temp
var temp = list[i]; list[i] = list[min]; list[min] = temp var temp = list[i]; list[i] = list[min]; list[min] = temp
} }
var tbody = list[i].parentElement; list[i].parentElement && tbody.removeChild(list[i]), tbody.appendChild(list[i])
var tbody = list[i].parentElement
list[i].parentElement && tbody.removeChild(list[i])
tbody.appendChild(list[i])
} }
}, },
Format: function(type) { var arg = arguments; switch (type) {
case html.A: return `<a href="${arg[1]}" target="_blank">${arg[2]||arg[1]}</a>` Cache: function(name, output, data) { if (!name) { return }
case html.IMG: return arg[3]? `<img src="${arg[1]}" height="${arg[2]}" width=${arg[3]}>`: arg[2]? `<img src="${arg[1]}" height="${arg[2]}">`: `<img src="${arg[1]}">` var cache = output._cache||{}; output._cache = cache
case html.SPAN: arg[2] && typeof arg[2] == code.OBJECT && arg[2].join && (arg[2] = arg[2].join(lex.SP)) if (data) { if (output.children.length == 0) { return }
return arg[2]? `<span class="${arg[2]}">${arg[1]}</span>`: arg[1] var temp = document.createDocumentFragment()
default: /* type inner arg... */ while (output.childNodes.length > 0) { // 写缓存
var list = ["<"+type]; for (var i = 2; i < arg.length; i += 2) { list.push(lex.SP+arg[i]+mdb.EQ+arg[i+1]) } var item = output.childNodes[0]
return list.concat(">", arg[1], "</", type, ">").join("") item.parentNode.removeChild(item),
} }, temp.appendChild(item)
ColorList: [ }
"#8085e9", return cache[name] = {node: temp, data: data}, name
"#95a2ff", }
"#73abf5", output.innerHTML = ""
"#3cb9fc",
"#0082fc", var list = cache[name]; if (!list) { return }
"#87e885", while (list.node.childNodes.length > 0) { // 读缓存
"#90ed7d", var item = list.node.childNodes[0]
"#22ed7c", item.parentNode.removeChild(item)
"#05f8d6", output.appendChild(item)
"#cb9bff", }
"#bf19ff", return delete(cache[name]), list.data
"#f47a75", },
"#fa8080", Format: function(type) {
"#f7a35c", switch (type) {
"#ffc076", case html.A: return "<a href='"+arguments[1]+"' target='_blank'>"+(arguments[2]||arguments[1])+"</a>"
"#f9e264", case html.IMG: return arguments[2]? "<img src='"+arguments[1]+"' height="+arguments[2]+">": "<img src='"+arguments[1]+"'>"
"#fae768", }
"#5f45ff", },
"#02cdff", replace: function(can, text, key, value) {
"#0090ff", return can.base.replaceAll(text, "<", "&lt;", ">", "&gt;", key, value)
"#854cff", },
"#09b0d3", Color: function(text) { if (typeof text != lang.STRING) { return "" }
"#1d27c9", if (text.indexOf("http://") == 0 || text.indexOf("https://") == 0 || text.indexOf("ftp://") == 0) {
"#765005", var ls = text.split(ice.SP);
"#314976", text = "<a href='"+ls[0]+"' target='_blank'>"+ls[0]+"</a>"+ls.slice(1).join(ice.SP)
"#009db2", }; text = text.replace(/\\n/g, "<br>")
"#024b51",
"#0780cf", if (text.indexOf("\033\[") == -1) { return text }
],
Color: function(text) { if (typeof text != code.STRING) { return "" } text = text.replace(/\\n/g, "<br>")
if (text.indexOf(ice.HTTP) == 0 && text.length > 10) { var ls = text.split(lex.SP); text = "<a href='"+ls[0]+"' target='_blank'>"+decodeURI(ls[0])+"</a>"+ls.slice(1).join(lex.SP) }
if (text.indexOf("export ctx_dev=") == 0 && text.length > 10) {
return "<div class='story' data-type='spark' data-name='shell'><div>"+"<span>"+text+"</span>"+"</div></div>"
} if (text.indexOf("\033\[") == -1) { return text }
text = text.replace(/\033\[41m/g, "<span style='background-color:#f00'>")
text = text.replace(/\033\[31m/g, "<span style='color:#f00'>") text = text.replace(/\033\[31m/g, "<span style='color:#f00'>")
text = text.replace(/\033\[32m/g, "<span style='color:#0f0'>") text = text.replace(/\033\[32m/g, "<span style='color:#0f0'>")
text = text.replace(/\033\[33m/g, "<span style='color:#ff0'>") text = text.replace(/\033\[33m/g, "<span style='color:#ff0'>")
text = text.replace(/\033\[34m/g, "<span style='color:#00f'>") text = text.replace(/\033\[34m/g, "<span style='color:#00f'>")
text = text.replace(/\033\[36m/g, "<span style='color:#0ff'>") text = text.replace(/\033\[36m/g, "<span style='color:#0ff'>")
text = text.replace(/\033\[37m/g, "<span style='color:gray'>")
text = text.replace(/\033\[34;1m/g, "<span style='color:#00f'>") text = text.replace(/\033\[34;1m/g, "<span style='color:#00f'>")
text = text.replace(/\033\[37;1m/g, "<span style='color:#fff'>") text = text.replace(/\033\[37;1m/g, "<span style='color:#fff'>")
text = text.replace(/\033\[1m/g, "<span style='font-weight:bold'>") text = text.replace(/\033\[1m/g, "<span style='font-weight:bold'>")
text = text.replace(/\033\[0m/g, "</span>") text = text.replace(/\033\[0m/g, "</span>")
text = text.replace(/\033\[m/g, "</span>") text = text.replace(/\033\[m/g, "</span>")
return text // } return text
}, },
Keys: function() { var list = []; /* FS SP GT PT */ for (var i = 0; i < arguments.length; i++) { var v = arguments[i]; if (typeof v == code.OBJECT) { input: function(can, item, value) {
for (var j = 0; j < v.length; j++) { if (typeof v[j] == code.OBJECT) { var input = {type: html.INPUT, name: item.name, data: item, dataset: {}, _init: item._init, style: item.style||{}}
for (var k = 0; k < v[j].length; k++) { if (typeof v[j][k] == code.OBJECT) { v[j][k] = v[j][k].join(nfs.PT) } }
v[j] = v[j].join(ice.GT)
} } list.push(v.join(lex.SP))
} else { list.push(v+"") } } return list.join(mdb.FS) },
Cache: function(name, output, data) { if (!name) { return } var cache = output._cache||{}; output._cache = cache
if (data) { if (output.children.length == 0) { return } var temp = document.createDocumentFragment()
while (output.childNodes.length > 0) { var item = output.childNodes[0]; item.parentNode.removeChild(item), temp.appendChild(item) }
return cache[name] = {node: temp, data: data}, name
} output.innerHTML = ""; var list = cache[name]; if (!list) { return }
while (list.node.childNodes.length > 0) { var item = list.node.childNodes[0]; item.parentNode.removeChild(item), output.appendChild(item) }
return delete(cache[name]), list.data
},
parentNode: function(can, target, tag) {
for (target; target; target = target.parentNode) {
if (can.page.tagis(target, tag)) { return target }
}
},
insertBefore: function(can, target, before, parent) {
if (typeof before == code.STRING) { before = can.page.SelectOne(can, parent, before) }
parent = parent||before.parentNode
if (can.base.isArray(target)) {
return can.core.List(target, function(item) { if (!item) { return }
var target = can.page.Append(can, parent, [item])._target
return parent.insertBefore(target, before), target
})[0]
} return before && parent.insertBefore(target, before), target
},
styleHeight: function(can, target, value) { return can.page.style(can, target, html.HEIGHT, value), target.offsetHeight },
styleWidth: function(can, target, value) { return can.page.style(can, target, html.WIDTH, value), target.offsetWidth },
styleClass: function(can, target, value) { return can.page.Modify(can, target, {className: value}), target.className },
style: function(can, target, style) { var value = {}; for (var i = 2; i < arguments.length; i += 2) {
if (typeof arguments[i] == code.OBJECT) { can.page.Modify(can, target, {style: arguments[i--]}) } else { value[arguments[i]] = arguments[i+1] }
} return can.page.Modify(can, target, {style: value}), value },
tagis: function(target) { if (!target || !target.tagName) { return }
function isin(ls, list) {
for (var i = 0; i < ls.length; i++) { var has = false
for (var j = 0; j < list.length; j++) { if (ls[i] == list[j]) { has = true } }
if (!has) { return false }
} return true
}
var type = target.tagName.toLowerCase(); for (var i = 1; i < arguments.length; i++) {
var ls = arguments[i].split("."); if (type != ls[0]) { continue }
if (isin(ls.slice(1), target.classList)) { return true }
}
},
tagClass: function(target) { return target.tagName.toLowerCase()+(target.className? nfs.PT+target.className.replaceAll(lex.SP, nfs.PT): "") },
isDark: function(can) {
return can.page.tagis(document.body, "body.dark")
},
isDisplay: function(target) { return target && target.style.display != html.NONE && target.className.indexOf(html.HIDE) == -1 },
isSelect: function(target) { return target && target.className.indexOf(html.SELECT) > -1 },
isIconInput: function(can, name) {
return can.base.isIn(name, mdb.CREATE, mdb.INSERT, mdb.PRUNES, mdb.PRUNE, ice.HELP, cli.START, cli.CLOSE, web.REFRESH) || icon[name] || can.Conf("feature._icons."+name) || can.core.Value(can.onaction, ["_trans.icons", name])
},
editable: function(can, item, ok) { item.setAttribute("contenteditable", ok) },
draggable: function(can, item, ok) { item.setAttribute("draggable", ok) },
height: function() { return window.innerHeight },
width: function() { return window.innerWidth },
ismodkey: function(event) { return [code.META, code.ALT, code.CONTROL, code.SHIFT].indexOf(event.key) > -1 },
unicode: { // https://symbl.cc/cn/
refresh: "↻",
goback: "↺", play: "▶", create: "+", insert: "+", prunes: "♻︎", prune: "♻︎",
select: "▿", remove: "✕", delete: "✕", close: "✕",
menu: "☰",
opens: "▾", closes: "▸",
prev: "", next: "",
start: "+", // play: "▸",
back: "◀", reback: "▶",
push: "⇈", pull: "⇊",
lt: "", gt: "",
inner: "...",
favor: "\u2606",
help: "\u2753",
},
inputs: function(can, list, type) {
var _list = []; for (var i = 0; i < list.length; i++) {
switch (list[i]) {
case "": _list.push(""); break
case ice.AUTO:
_list.push({type: html.BUTTON, name: ice.LIST})
_list.push({type: html.BUTTON, name: ice.BACK})
break
case web.FILTER:
_list.push({type: html.TEXT, name: web.FILTER, icon: icon.search})
break
case mdb.PAGE:
_list.push({type: html.TEXT, name: mdb.OFFEND, value: can._msg.Option(mdb.OFFEND)})
_list.push({type: html.TEXT, name: mdb.LIMIT, value: can._msg.Option(mdb.LIMIT), _init: function(target) {
can.onappend.figure(can, {action: "key", run: function(event, cmds, cb) {
var msg = can.request(event)
msg.Push(cmds[1], "10")
msg.Push(cmds[1], "30")
msg.Push(cmds[1], "50")
msg.Push(cmds[1], "100")
cb(msg)
}}, target, function() { can.Update() })
}})
_list.push(mdb.NEXT, mdb.PREV)
break
default: (function() { var item = can.core.SplitInput(list[i], type||html.BUTTON)
if (item.type == html.SELECT) {
item._init = function(target) { target.value = item.value||item.values[0]
target.onchange = function(event) { can.misc.Event(event, can, function(msg) { can.run(event) }) }
}
}
item.action && (function() { item._init = function(target) {
can.onappend.figure(can, item, target, function() { can.Update({}, ) })
} })()
_list.push(item), type = item.type
})()
}
}
return _list
},
button: function(can, name, cb) {
var icon = can.Conf("_icons."+name)
if (icon) { return {icon: icon, onclick: cb||function(event) { can.Update(event, [ctx.ACTION, name]) }} }
return {view: [["item.button"]], list: [
{type: html.INPUT, data: {type: html.BUTTON, name: name, value: can.user.trans(can, name)}, onclick: cb||function(event) { can.Update(event, [ctx.ACTION, name]) }},
{text: name},
]}
},
input: function(can, item, value) { var input = {type: html.INPUT, name: item.name, data: item, style: item.style||{}, dataset: {}, _init: item._init}
item.value == ice.AUTO && (item.value = "", item.action = ice.AUTO), item.action == ice.AUTO && (input.dataset.action = ice.AUTO) item.value == ice.AUTO && (item.value = "", item.action = ice.AUTO), item.action == ice.AUTO && (input.dataset.action = ice.AUTO)
switch (item.type = item.type||html.TEXT) { switch (item.type = item.type||html.TEXT) {
case html.SELECT: input.type = html.SELECT, item.className||can.page.ClassList.add(can, item, ctx.ARGS) case html.TEXTAREA: input.type = html.TEXTAREA
item.values = can.base.isString(item.values)? can.core.Split(item.values): item.values input.style.height = input.style.height||can.Conf([ctx.FEATURE, html.TEXTAREA, item.name, html.HEIGHT].join(ice.PT))||can.Conf(["feature", html.TEXTAREA, html.HEIGHT].join(ice.PT))
if (!item.values && item.value) { item.values = can.core.Split(item.value), item.value = item.values[0] } input.style.width = input.style.width||can.Conf([ctx.FEATURE, html.TEXTAREA, item.name, html.WIDTH].join(ice.PT))||can.Conf(["feature", html.TEXTAREA, html.WIDTH].join(ice.PT))
if (item.values.slice(1).indexOf(item.values[0]) > -1) { item.value = item.value||item.values[0], item.values = item.values.slice(1) } // no break
item.value = value||item.value, input.list = item.values.map(function(value) { case html.USERNAME:
return {type: html.OPTION, value: value, inner: can.user.trans(can, value, null, html.VALUE)} case html.PASSWORD:
}); break // no break
case html.TEXTAREA: input.type = html.TEXTAREA // no break
case html.USERNAME: // no break
case html.PASSWORD: // no break
case html.TEXT: case html.TEXT:
case html.FILTER: item.autocomplete = "off"
item.className||can.page.ClassList.add(can, item, ctx.ARGS), item.name = item.name||item.type, item.value = value||item.value||""; item.name = item.name||item.type
//item.placeholder = item.placeholder||item.name item.value = value||item.value||""
break item.placeholder = item.placeholder||item.name||item.type
case html.UPLOAD: item.type = html.FILE, input.name = html.UPLOAD; break item.title = item.title||item.placeholder||item.name||item.type
item.className || can.page.ClassList.add(can, item, ctx.ARGS)
break
case html.SELECT: input.type = html.SELECT
item.values = can.base.isString(item.values)? can.core.Split(item.values): item.values
if (!item.values && item.value) { item.values = can.core.Split(item.value), item.value = item.values[0] }
item.value = value||item.value, input.list = item.values.map(function(value) {
return {type: html.OPTION, value: value, inner: value}
}), item.className || can.page.ClassList.add(can, item, ctx.ARGS)
break
case html.BUTTON: item.value = item.value||item.name||mdb.LIST; break case html.BUTTON: item.value = item.value||item.name||mdb.LIST; break
} return input case "upfile": item.type = html.FILE; break
case html.UPLOAD: item.type = html.FILE, input.name = html.UPLOAD; break
default:
}
return input
}, },
icons: function(can, name, space) { if (!name) { return }
if (can.base.contains(name, "/") && can.misc.isImage(can, name)) { return {img: can.misc.Resource(can, name, space)} } styleDisplay: function(can, target, value) {
// if (can.page.unicode[name]) { return {text: [can.page.unicode[name], "", "icon"]} } return can.page.style(can, target, html.DISPLAY, value), target.style.display
if (can.base.beginWith(name, "bi ")) { return {icon: name} }
if (name == mdb.DELETE) { return {icon: "bi bi-trash"} }
var _icon = can.base.getValid(can.Conf("_icons."+name), can.Conf("_trans.icons."+name), can.core.Value(can.onaction, ["_trans.icons."+name]), icon[name])
if (_icon) { return {icon: _icon} }
}, },
requireChina: function(can, title, list, name, path) { styleHeight: function(can, target, value) {
can.onappend.plugin(can, {title: title, display: "/plugin/story/china.js", style: html.FLOAT, height: can.ConfHeight(), width: can.ConfHeight()}, function(sub) { return can.page.style(can, target, html.HEIGHT, value), target.offsetHeight
sub.run = function(event, cmds, cb) { var msg = can.request(event, {title: title, name: name, path: path})
can.core.List(list, function(item) { msg.Push(mdb.NAME, item.name), msg.Push(mdb.VALUE, item.value) }), cb(msg)
can.onmotion.resize(can, sub._target, function(height, width) { sub.onimport.size(sub, height, width, true) })
}
})
}, },
requireModules: function(can, libs, cb, cbs) { if (!libs || libs.length == 0) { return cb && cb() } styleWidth: function(can, target, value) {
for (var i = 0; i < libs.length; i++) { if (libs[i].indexOf(nfs.PS) == 0 || libs[i].indexOf(ice.HTTP) == 0) { continue } return can.page.style(can, target, html.WIDTH, value), target.offsetWidth
if (libs[i].indexOf(nfs._CSS) == -1 && libs[i].indexOf(nfs._JS) == -1) { libs[i] = libs[i]+"/lib/"+libs[i]+nfs._JS }
libs[i] = nfs.M+libs[i]
} can.require(libs, cb, cbs)
}, },
requireDraw: function(can, cb) { can.require([chat.PLUGIN_LOCAL+"wiki/draw.js", chat.PLUGIN_LOCAL+"wiki/draw/path.js"], function() { style: function(can, target, style) { var value = {}
can.onimport._last_init(can, can.request()), can.onappend.style(can, wiki.DRAW, can._fields), cb() for (var i = 2; i < arguments.length; i += 2) {
}, function(can, mod, sub) { mod == chat.ONIMPORT && (can[mod]._last_init = sub._init) }) }, if (typeof arguments[i] == lang.OBJECT) {
drawText: function(can, text, size, margin, fonts) { text = text.slice(0, 1), size = size||80, margin = margin == undefined? 10: margin can.base.Copy(value, arguments[i--])
var colors = ["rgb(239,150,26)", 'rgb(255,58,201)', "rgb(111,75,255)", "rgb(36,174,34)", "rgb(80,80,80)"] } else {
var canvas = can.page.Create(can, html.CANVAS, {width: size, height: size}), ctx = canvas.getContext("2d") value[arguments[i]] = arguments[i+1]
ctx.fillStyle = colors[Math.floor(Math.random()*(colors.length))], ctx.fillRect(margin, margin, size-2*margin, size-2*margin)
ctx.fillStyle = cli.WHITE, ctx.font = (fonts||can.base.Min(size/text.length-30, 16))+"px Arial", ctx.textAlign = "center", ctx.textBaseline = "middle", ctx.fillText(text, size/2, size/2)
return canvas.toDataURL(html.IMAGE_PNG, 1)
},
position: function(event, target) { var p = target.getBoundingClientRect(); return {x: event.clientX - p.x, y: event.clientY - p.y} },
getquery: function(can, target) {
var list = []; for (var p = target; p; p = p.parentNode) {
if (can.page.tagis(p, "body")) { list.pop(); break }
list.push(can.core.Keys(p.tagName.toLowerCase(), can.core.List(p.classList).join(".")), ">")
if (can.page.tagis(p, html.FIELDSET)) {
if (can.page.tagis(p, "fieldset.web.chat.tutor")) { return "" }
list.pop(); break
} }
} }
return list.reverse().join("") return can.page.Modify(can, target, {style: value}), value
}, },
theme: function(cb) { var themeMedia = window.matchMedia("(prefers-color-scheme: dark)") Keys: function() { var list = []
cb && themeMedia.addListener(function(event) { cb(event.matches? html.DARK: html.LIGHT) }) for (var i = 0; i < arguments.length; i++) { var v = arguments[i]
cb && cb(themeMedia.matches? html.DARK: html.LIGHT) if (typeof v == lang.OBJECT) {
return themeMedia.matches? html.DARK: html.LIGHT for (var j = 0; j < v.length; j++) {
}, if (typeof v[j] == lang.OBJECT) {
appendAction: function(can, value, target) { if (!value.action) { return } target.innerHTML = value.action for (var k = 0; k < v[j].length; k++) {
can.page.Select(can, target, html.INPUT_BUTTON, function(target) { if (typeof v[j][k] == lang.OBJECT) { v[j][k] = v[j][k].join(ice.PT) }
var style = can.Conf(["_trans.input",can.ConfIndex().split(".").pop(), "style", target.name])||can.Conf("_style."+target.name)||can.page.buttonStyle(can, target.name); style && can.onappend.style(can, style, target) }
target.onclick = function(event) { v[j] = v[j].join(ice.GT)
if (can.page.ClassList.has(can, can._fields, "_process")) { return } can.onappend.style(can, "_process") }
can.onkeymap.prevent(event), can.Update(can.request(event, value, {_toast: can.user.trans(can, target.name)}), [ctx.ACTION, target.name]) }
list.push(v.join(ice.SP))
} else {
list.push(v+"")
} }
}) }
return list.join(ice.FS)
}, },
parseAction: function(can, value) { var action = [] css: function(text) {
can.page.Select(can, can.page.Create(can, html.DIV, value.action), html.INPUT, function(target) { var styleSheet = document.createElement("style")
action.push(target.name), target.name != target.value && can.user.trans(can, kit.Dict(target.name, target.value)) styleSheet.type = "text/css", styleSheet.innerText = text
}) document.head.appendChild(styleSheet)
return action
}, },
buttonStyle: function(can, name) { tagis: function(type, target) { type = typeof type == lang.OBJECT? type: [type]
return can.Conf(["_trans.input", can.ConfIndex().split(".").pop(), "style", name])||can.Conf("_style."+name)|| if (type.indexOf(target.tagName.toLowerCase()) > -1) { return true }
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", "submit", "commit", "preview", "auto-preview", ice.APP)? html.NOTICE:
can.base.isIn(name, mdb.REMOVE, "rename", mdb.DELETE, mdb.PRUNES, mdb.PRUNE, nfs.TRASH, cli.RESTART, cli.STOP, cli.CLOSE, cli.REBOOT, web.CANCEL, code.UPGRADE, "reject", "del", "drop", "access", "kill", "prockill")? html.DANGER: "")
}, },
exportValue: function(can, msg, target) { target = target||can._output offsetTop: function(item) { var res = 0
msg.OptionDefault(ice.MSG_THEME, can.getHeaderTheme()) while (item) { res += item.offsetTop||0, item = item.parentNode }
msg.OptionDefault(ice.MSG_BG, can.page.styleValue(can, "--plugin-bg-color", target)) return res
msg.OptionDefault(ice.MSG_FG, can.page.styleValue(can, "--plugin-fg-color", target)) },
can.user.info.language && msg.OptionDefault(ice.MSG_LANGUAGE, can.user.info.language) offsetLeft: function(item) { var res = 0
return msg // if (item.offsetLeft) { return item.offsetLeft }
while (item) { res += item.offsetLeft||0, item = item.parentNode }
return res
}, },
styleValue: function(can, key, target) { const styles = getComputedStyle(target||document.body); return styles.getPropertyValue(key) },
styleValueInt: function(can, key, target) { return parseInt(can.base.trimSuffix(can.page.styleValue(can, key, target), "px")) }
}) })

View File

@ -1,454 +1,336 @@
Volcanos("user", { Volcanos("user", {help: "用户操作", agent: {
agent: { scanQRCode: function(cb, can) {
getLocation: function(can, cb) { var call = arguments.callee; if (call._res) { return cb(call._res) } can.user.input(event, can, [{type: html.TEXTAREA, name: "text", text: ""}], function(ev, button, data, list, args) {
navigator.geolocation.getCurrentPosition(function(res) { cb(list[0], can.base.ParseJSON(list[0]))
cb(call._res = {type: "ip", name: "当前位置", text: "某某大街", latitude: res.coords.latitude.toFixed(6), longitude: res.coords.longitude.toFixed(6)}) })
}, function(some) { can.base.isFunc(cb) && cb({type: "location", name: "北京市", text: "天安门", latitude: 39.98412, longitude: 116.30748}) } )
}, },
openLocation: function(can, msg) { getLocation: function(cb) {
navigator.geolocation.getCurrentPosition(function(res) {
cb({latitude: parseInt(res.coords.latitude*100000), longitude: parseInt(res.coords.longitude*100000)})
}, function(some) {
typeof cb == lang.FUNCTION && cb({name: "some"})
} );
},
openLocation: function(msg) {
window.open("https://map.baidu.com/search/"+encodeURIComponent(msg.Option(mdb.TEXT)) window.open("https://map.baidu.com/search/"+encodeURIComponent(msg.Option(mdb.TEXT))
+"/@12958750.085,4825785.55,16z?querytype=s&da_src=shareurl&wd="+encodeURIComponent(msg.Option(mdb.TEXT))) +"/@12958750.085,4825785.55,16z?querytype=s&da_src=shareurl&wd="+encodeURIComponent(msg.Option(mdb.TEXT)))
}, },
chooseImage: function(can, cb, count) { can.base.isFunc(cb) && cb([]) }, chooseImage: function(cb) {
uploadImage: function(can, id, cb) {}, typeof cb == lang.FUNCTION && cb([])
previewImage: function(can, url, list) {}, },
scanQRCode: function(can, cb) { can.user.input(event, can, [{type: html.TEXTAREA, name: mdb.TEXT, text: ""}], function(list) { cb(can.base.ParseJSON(list[0])) }) }, },
connectWifi: function(can, ssid, password, cb, cbs) {},
getClipboard: function(can, cb) {},
enableDebug: function(can) {},
init: function(can, content, icons) { can.user.agent.cmd = can, can.user.agent._init_content = content, can.user.agent._init_icons = icons }, _init_content: [],
}, info: {},
isIPad: false,
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, isWeiXin: navigator.userAgent.indexOf("MicroMessenger") > -1,
isIPhone: navigator.userAgent.indexOf("iPhone") > -1, isIPhone: navigator.userAgent.indexOf("iPhone") > -1,
isMobile: navigator.userAgent.indexOf("Mobile") > -1, isMobile: navigator.userAgent.indexOf("Mobile") > -1,
isMacOSX: navigator.userAgent.indexOf("Mac OS X") > -1, isMacOSX: navigator.userAgent.indexOf("Mac OS X") > -1,
isWindows: navigator.userAgent.indexOf("Windows") > -1, isWindows: navigator.userAgent.indexOf("Windows") > -1,
isNodejs: navigator.userAgent.indexOf("nodejs") > -1,
isIE: navigator.userAgent.indexOf("MSIE") > -1, isIE: navigator.userAgent.indexOf("MSIE") > -1,
isWebview: window.webview != undefined,
isExtension: location && location.protocol && location.protocol == "chrome-extension:", isExtension: location && location.protocol && location.protocol == "chrome-extension:",
isLocalFile: location && location.protocol && location.protocol == "file:", isLocalFile: location && location.protocol && location.protocol == "file:",
isLandscape: function() { return window.innerWidth > window.innerHeight }, isLandscape: function() { return window.innerWidth > window.innerHeight },
isTechOrRoot: function(can) { return can.base.isIn(can.user.info.userrole, aaa.TECH, aaa.ROOT) },
mod: { mod: {
isPod: location && location.pathname && (location.pathname.indexOf(web.CHAT_POD) == 0 || location.pathname.indexOf("/x/") == 0 || location.pathname.indexOf("/s/") == 0), isPod: location && location.pathname && (location.pathname.indexOf("/chat/pod/") == 0),
isCmd: location && location.pathname && (location.pathname.indexOf(web.CHAT_POD) == 0 && location.pathname.indexOf("/cmd/") > 0 isDiv: location && location.pathname && (location.pathname.indexOf("/chat/div/") == 0),
|| location.pathname.indexOf(web.CHAT_CMD) == 0 || location.pathname.indexOf(nfs.WIKI_PORTAL) == 0 isCmd: location && location.pathname && (location.pathname.indexOf("/chat/pod/") == 0 && location.pathname.indexOf("/cmd/") > 0 ||
), location.pathname.indexOf("/chat/cmd/") == 0 || location.pathname.indexOf("/help/") == 0),
}, },
alert: function(text) { alert(JSON.stringify(text)) }, alert: function(text) { alert(JSON.stringify(text)) },
confirm: function(text) { return confirm(JSON.stringify(text)) }, confirm: function(text) { return confirm(JSON.stringify(text)) },
prompt: function(tip, def, cb, silent) { (text = silent? def: prompt(tip, def||"")) != undefined && typeof cb == code.FUNCTION && cb(text); return text }, prompt: function(tip, def, cb, silent) { (text = silent? def: prompt(tip, def||"")) != undefined && typeof cb == lang.FUNCTION && cb(text); return text },
reload: function(force) { (force || confirm("重新加载页面?")) && location.reload() }, reload: function(force) { (force || confirm("重新加载页面?")) && location.reload() },
jumps: function(url) { jumps: function(url) { location.href = url },
location.href = url open: function(url) { window.open(url) },
time: function(can, time, fmt) { var now = can.base.Date(time)
var list = can.user.language(can) == "en"? ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]
return can.base.Time(time, (fmt||"%y-%m-%d %H:%M:%S").replace("%w", list[now.getDay()]))
}, },
opens: function(url) {
if (window.parent && window.parent.openurl) { return window.parent.openurl(url) } title: function(text) { return text && (document.title = text), document.title },
window.openurl? window.openurl(url): this.open(url) topic: function(can, name) {
can.user.isMobile && (name += " mobile") && can.user.isLandscape() && (name += " landscape")
can.page.Modify(can, document.body, {className: name})
}, },
open: function(url) { if (!url) { return } language: function(can) { return can.misc.Search(can, "language") },
if (location.search.indexOf("debug=true") > 0 && url.indexOf("debug=true") == -1) { trans: function(can, text, list) { if (can.base.isObject(text)) {
var ls = url.split("#"); ls[0] += (ls[0].indexOf("?") > 0? "&": "?") + "debug=true", url = ls.join("#") return can.core.Item(text, function(k, v) { can.core.Value(can._trans, k, v) })
} }
window.open(url) || (location.hostname != tcp.LOCALHOST && (location.href = url))
if (can.user.language(can) == "en") { return text }
if (can.base.isFunction(text)) { text = text.name||"" }
return list&&list[text] || can.Conf("trans."+text) || can.Conf("feature._trans."+text) || can._trans&&can._trans[text] || {
"create": "创建", "remove": "删除", "insert": "添加", "delete": "删除", "modify": "编辑",
"inputs": "补全", "prunes": "清理", "export": "导出", "import": "导入",
"list": "查看", "back": "返回", "run": "执行", "done": "完成", "share": "共享",
"edit": "编辑", "save": "保存", "copy": "复制", "show": "显示", "hide": "隐藏",
"project": "项目", "profile": "详情", "actions": "参数",
"plugin": "插件",
"open": "打开", "close": "关闭",
"start": "启动", "stop": "停止",
"begin": "开始", "end": "结束",
"clear": "清空", "refresh": "刷新",
"submit": "提交", "cancel": "取消",
"label": "标签", "exec": "执行",
}[text]||text
}, },
close: function(url) { return window.close() }, toastProcess: function(can, title) { return can.user.toast(can, ice.PROCESS, title) },
theme: function(can, name) { can.base.isString(name) && (name = [name]) || name || [] toastSuccess: function(can, title) { return can.user.toast(can, ice.SUCCESS, title) },
name.push(html.WIDTH+parseInt((can.page.width()+32)/320)) toast: function(can, content, title, duration, progress) {
can.user.mod.isCmd && name.push(chat.CMD), can.user.mod.cmd && name.push(can.base.replaceAll(can.user.mod.cmd, ".", " ")) var meta = can.base.isObject(content)? content: {content: content, title: title||can._help, duration: duration, progress: progress}
// if (window.innerWidth <= 1080) { can.user.isIPad = true } var width = meta.width||400, height = meta.height||100; if (width < 0) { width = window.innerWidth + width }
can.user.isIPad && name.push("pad") && can.user.isLandscape() && name.push(html.LANDSCAPE)
can.user.isWindows && name.push(html.WINDOWS), can.user.isWebview && name.push(html.WEBVIEW) var ui = can.page.Append(can, document.body, [{view: chat.TOAST, style: {
can.user.isMobile && name.push(html.MOBILE) && can.user.isLandscape() && name.push(html.LANDSCAPE) left: (window.innerWidth-width)/2, width: width, bottom: 100,
can.user.isWeiXin && name.push("weixin") }, list: [
can.user.language(can) && name.push(can.core.Split(can.user.language(can), "-_.")[0]) {text: [meta.title||"", html.DIV, html.TITLE], title: "点击复制", onclick: function(event) {
can.user.info.userrole && name.push(can.user.info.userrole) can.user.copy(event, can, meta.title)
can.misc.isDebug(can) && name.push(log.DEBUG) }},
can.page.styleClass(can, document.body, name.join(lex.SP)) {view: "duration", title: "点击关闭", onclick: function() { action.close() }},
}, can.base.isObject(meta.content)? meta.content: {text: [meta.content||"执行成功", html.DIV, "content"]},
title: function(text) {
if (window.webview) { return title(text) } {view: chat.ACTION}, meta.progress != undefined && {view: "progress", style: {width: width}, list: [
return text && (document.title = text), document.title {view: "current", style: {width: (meta.progress||0)/100*width}},
}, ]},
language: function(can) { return (can.misc.SearchOrConf(can, aaa.LANGUAGE)||can.user.info.language||"") }, ] }])
isEnglish: function(can) { return can.base.isIn(can.core.Split(can.user.language(can).toLowerCase()||"en", "_-.")[0], "en", "en-us") },
transValue: function(can, value, key) { var action = can.onappend._action(can, meta.action||[""], ui.action, {
if (value.Append) { return can.user.trans(can, value.Append(key), null, "value."+key) } close: function(event) { can.page.Remove(can, action._target), action.timer.stop = true },
if (value.Option) { return can.user.trans(can, value.Option(key), null, "value."+key) } timer: can.core.Timer({interval: 100, length: (parseInt(meta.duration||1000))/100}, function(event, interval, index) {
return can.user.trans(can, value[key], null, "value."+key) if (index > 30) { ui.duration.innerHTML = parseInt(index/10)+ice.PT+(index%10)+"s..." }
}, }, function() { action.close() }), _target: ui._target, ui: ui,
trans: function(can, text, list, zone) { if (can.base.isNumber(text)) { return text+"" } if (can.user.isEnglish(can)) { return text }
if (can.base.isObject(text)) { return can.core.Item(text, function(k, v) { can.core.Value(can._trans, can.core.Keys(zone, k), v) }) }
if (can.base.isFunc(text)) { text = text.name||"" } if (list && can.base.isString(list)) { return list }
var key = can.core.Keys(zone, text)
if (text == can.Conf("index") && can.Conf("help")) { return can.Conf("help") }
return can.core.Value(list, key) ||
can.Conf(["feature._trans", zone||"input", (can.ConfIndex()||"").split(".").pop(), text]) ||
can.Conf(["feature._trans", zone, (can.ConfIndex()||"").split(".").pop(), text]) ||
can.Conf(["feature._trans", key]) || can.Conf(["trans", key]) ||
can.core.Value(can._trans, key) ||
can.core.Value(can.user._trans, key) || text
}, _trans: {"_week_header": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]},
time: function(can, time, fmt) {
var now = can.base.Date(time), list = can.user._trans["_week_header"]
return fmt == "%W"? list: can.base.Time(time, (fmt||"%y-%m-%d %H:%M:%S").replace("%w", list[now.getDay()]))
},
toastConfirm: function(can, content, title, action) {
if (!action.list || action.list.length == 0) { action = shy({confirm: action}, [html.CANCEL, html.CONFIRM]) }
var carte = can.user.toast(can, {content: content, title: title, action: action||[cli.CLOSE], duration: -1})
can.page.style(can, carte._target, html.TOP, 200, html.BOTTOM, ""); return carte
},
toastProcess: function(can, content, title, progress) {
content = can.user.trans(can, content||""), content += can.user.trans(can, " process", "中...")
return can.user.toast(can, {content: "🕑 "+content, title: title, duration: -1, progress: progress})
},
toastFailure: function(can, content, title) {
content = can.user.trans(can, content||"")
if (content.length < 8) { content += can.user.trans(can, " failure", "失败") }
return can.user.toast(can, {content: "❌ "+content, title: title, duration: -1})
},
toastSuccess: function(can, content, title, duration) {
content = can.user.trans(can, content||""), content += can.user.trans(can, " success", "成功")
return can.user.toast(can, {content: "✅ "+content, title: title, duration: duration||1000})
},
toast: function(can, content, title, duration, progress, hash) { can = can._fields? can.sup: can
var meta = can.base.isObject(content)? content: {content: content, title: title, duration: duration, progress: progress, hash: hash}
// var list = can.core.Split(content, " ", " ")
// content = can.core.List(list, function(text) { return can.user.trans(can, text) }).join("")
if (meta.title == can.ConfIndex()) { meta.title = can.user.trans(can, meta.title, can.ConfHelp()) }
meta.title = meta.title||can.user.trans(can, can.core.Keys(can.ConfSpace(), can.ConfIndex()), can.ConfHelp())||can._name.split(nfs.PS).slice(-2).join(nfs.PS)
meta.title = can.base.replaceAll(can.user.trans(can, meta.title||""), "%2F", "/")
meta.hash && can.misc.isDebug(can) && (meta.title += " "+meta.hash.slice(0, 6)), meta.action = meta.action||[""]
var width = meta.width||(html.QRCODE_WIDTH+2*html.PLUGIN_PADDING+10); if (width < 0) { width = can.page.width() + width }
if (can.user.isMobile && !can.user.isLandscape()) { width = window.innerWidth }
var ui = can.page.Append(can, meta.action.list||meta.action.length > 1 || !can._root||!can._root.Action||!can._root.Action._toast? document.body: can._root.Action._toast,
[{view: [[chat.TOAST, can.ConfIndex(), meta.style, html.FLOAT]], style: {width: width}, list: [
{view: [html.TITLE, "", meta.title], title: "点击复制", onclick: function(event) { can.user.copy(event, can, meta.title) }},
{view: [cli.CLOSE, "", can.page.unicode.close], title: "点击关闭", onclick: function() { action.close() }},
{view: "duration", title: "点击关闭", onclick: function() { action.close() }},
can.base.isObject(meta.content)? meta.content: {view: [[nfs.CONTENT, html.FLEX], "", meta.content||""]},
html.ACTION, !can.base.isUndefined(meta.progress) && {view: "progress", style: {width: width-2*html.PLUGIN_PADDING}, list: [
{view: "current", style: {width: (meta.progress||0)*(width-2*html.PLUGIN_PADDING-2)/100}},
]},
]}]
);
can.onengine.signal(can, chat.ONTOAST, can.request({}, {time: can.misc._time(), title: meta.title, content: meta.content}))
// meta.action.meta && can.core.Item(meta.action.meta, function(key, cb) { cb.help && can.core.Value(meta.action.meta, ["_trans", key], cb.help) })
var action = can.onappend._action(can, meta.action.list? meta.action.list.reverse(): meta.action, ui.action, {_trans: meta.action.meta? meta.action.meta._trans: {},
_engine: function(event, button) { can.core.CallFunc(meta.action.meta? meta.action.meta[button]: meta.action, [event, button]), action.close(event) },
open: function(event) { meta.content.indexOf(ice.HTTP) == 0 && can.user.open(meta.content), meta.title.indexOf(ice.HTTP) == 0 && can.user.open(meta.title) },
close: function() {
// event && event.isTrusted && can.onengine.signal(can, "onevent", can.request(event, {_type: "close"}))
action.timer.stop = true, can.page.Remove(can, ui._target), delete(can.__toast)
can._toast && (typeof can._toast.close == code.FUNCTION) && delete(can._toast)
},
cancel: function() { action.close() },
timer: can.core.Timer({interval: 100, length: (meta.duration||1000)/100}, function(event, interval, index) {
if (index > 30) { ui.duration.innerHTML = index/10+(index%10==0?".0":"")+"s..." }
}, function() {
can.page.style(can, ui._target, "margin-right", "-400px")
can.onmotion.delay(can, function() { action.close() }, 1000)
}), _target: ui._target,
}); can.onmotion.story.auto(can, ui._target) }); can.onmotion.story.auto(can, ui._target)
if (meta.action && meta.action.length == 1 && meta.action[0] === "") {
can.page.Select(can, action._target, html.DIV_ACTION, function(target) { can.onmotion.hidden(can, target) }) can.onengine.signal(can, chat.ONTOAST, can.request({}, {
} title: meta.title, content: meta.content,
if (action._target.parentNode == document.body) { can.onmotion.delay(can, function() { time: can.base.Time(), fileline: can.misc.FileLine(2, 2),
can.page.style(can, action._target, html.TOP, (can.page.height() - action._target.offsetHeight)/2, html.LEFT, (can.page.width()-action._target.offsetWidth)/2) }))
}) }
can._toast && (typeof can._toast.close == code.FUNCTION && can._toast.close(), delete(can._toast))
can._root && can._root.Action && can._root.Action._toast && (can._root.Action._toast.scrollTop += 10000)
if (meta.hash) { var list = can._root.Action._toastList = can._root.Action._toastList||{}
list[meta.hash] && can.page.insertBefore(can, action._target, list[meta.hash]._target), can.__toast = action
list[meta.hash] && (can.page.Remove(can, list[meta.hash]._target), list[meta.hash].close(), delete(list[meta.hash])), list[meta.hash] = action
} else {
can._toast = action
}
return action return action
}, },
space: function(can) { return can.Conf(web.SPACE)||can.Conf(ice.POD)||can.misc.Search(can, ice.POD) }, share: function(can, msg, cmd) {
template: function(can, file) { return can.base.MergeURL(can.base.Path(nfs.SRC_TEMPLATE, can.Conf(ctx.INDEX), file), ice.POD, can.user.space(can)) }, can.run(msg._event, cmd||[ctx.ACTION, chat.SHARE], function(msg) {
share: function(can, msg, cmds) { can.page.exportValue(can, msg) can.user.toast(can, {height: 300, width: 500,
can.run(msg, cmds||[ctx.ACTION, chat.SHARE], function(msg) { can.user.copy(msg._event, can, msg.Append(mdb.NAME)) title: msg.Append(mdb.NAME), duration: -1,
var ui = can.user.toast(can, {style: cli.QRCODE, title: msg.Append(mdb.NAME), duration: -1, content: msg.Append(mdb.TEXT), action: [cli.CLOSE, cli.OPEN], resize: html.IMG}) content: msg.Append(mdb.TEXT), action: [cli.CLOSE],
}), can.user.copy(msg._event, can, msg.Append(mdb.NAME))
}) })
}, },
copy: function(event, can, text) { if (!text) { return } login: function(can, cb, method) {
if (navigator.clipboard) { var ok = false; navigator.clipboard.writeText(text).then(function() { ok = true }) var ui = can.user.input({}, can, [{type: html.USERNAME}, {type: html.PASSWORD}], function(event, button, data, list) { return {
if (ok) { return can.user.toastSuccess(can, text, "copy success"), can.misc.Log(nfs.COPY, text), text } "登录": function() {
} can.run({}, [aaa.LOGIN, data[html.USERNAME], data[html.PASSWORD]], function(msg) {
var input = can.page.Append(can, document.body, [{type: html.TEXTAREA, value: text}])._target if (msg.Option(ice.MSG_USERNAME)) {
can.onmotion.focus(can, input), document.execCommand("Copy"), can.page.Remove(can, input) can.page.Remove(can, ui._target), can.base.isFunc(cb) && cb()
return can.user.toastSuccess(can, text, can.user.trans(can, "copy success", "复制成功")), can.misc.Log(nfs.COPY, text), text } else {
}, can.user.toast(can, "用户名或密码错误")
carte: function(event, can, meta, list, cb, parent, trans) { var msg = can.request(event); event = msg._event }
function remove_sub(carte) { carte._sub && can.page.Remove(can, carte._sub._target), delete(carte._sub) } parent? remove_sub(parent): can.onmotion.clearCarte(can) })
meta = meta||can.ondetail||can.onaction||{}, list = can.base.getValid(list, meta.list, can.core.Item(meta, function(key) { return true
if (can.base.beginWith(key, "_")) { return }
return key
})), trans = trans||meta._trans; if (!list || list.length == 0) { return }
var _events = event._events||event
function click(event, button, index) { can.misc.Event(event, can, function() { can.request(event, {action: button}), can.onkeymap.prevent(event), event._events = _events;
can.onengine.signal(can, "onevent", can.request(event, {_type: html.ACTION}));
(can.base.isFunc(cb)? cb(event, button, meta, carte, index): meta[button]? can.core.CallFunc([meta, button], {event: event, can: can, msg: msg, button: button}): can.Update(event, [ctx.ACTION, button])) || can.onmotion.clearCarte(can)
}) }
var isinput = can.page.tagis(event.target, html.INPUT)
var ui = can.page.Append(can, document.body, [{view: [[chat.CARTE,
can.Conf(ctx.INDEX)||can.ConfIndex(), msg.Option(ctx.ACTION), meta._style||msg.Option("_style"), chat.FLOAT,
]], list: can.core.List(list, function(item, index) {
if (typeof item == code.FUNCTION) { item = item(can); if (!item) { return } }
if (item === "") { return {type: html.HR} }
if (item == web.FILTER) { return {
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)) {
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]],
// list: [can.page.icons(can, item), {text: [can.user.trans(can, item, trans), "", "name"]}],
list: [{text: [can.user.trans(can, item, trans), "", "name"]}],
onclick: function(event) { click(event, item, index) },
onmouseenter: function(event) { remove_sub(carte) },
}
}
if (can.base.isArray(item)) {
function subs(event) { var sub = can.user.carte(event, can, meta, item.slice(1), cb||function(event, button) {
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), "", "name"]},
{text: [lex.SP+can.page.unicode.next, "", [html.ICON, "next"]]}
], onmouseenter: subs, onclick: subs}
}
return item
})}]); can.onkeymap.prevent(event), can.page.Select(can, ui._target, html.IMG, function(target) { target.onload = function() { can.onlayout.figure(event, can, ui._target) } })
var carte = {_target: ui._target, _parent: parent, layout: can.onlayout.figure(event, can, ui._target, parent), close: function() { can.page.Remove(can, ui._target) }}
return parent && (parent._sub = carte), carte
},
carteRight: function(event, can, meta, list, cb, parent) { var carte = can.user.carte(event, can, meta, list, cb, parent)
return carte && can.onlayout.figure(event, can, carte._target, true), carte
},
carteItem: function(event, can, item) { if (!item.action) { return }
var trans = {}, list = can.page.Select(can, can.page.Create(can, html.DIV, item.action), "", function(target) { trans[target.name] = can.user.trans(can, target.value); return target.name })
can.user.carteRight(event, can, {_trans: trans}, list, function(_event, button) {
can.Update(can.request(_event, event._msg, item), [ctx.ACTION, button]) })
},
input: function(event, can, form, cb, button) { if (!form || form.length == 0) { return cb() }
event = event||{}; var msg = can.request(event); event = event._event||event; var need = {}
var title = can.user.trans(can, msg.Option(ctx.ACTION))
var ui = can.page.Append(can, document.body, [{view: [[html.INPUT, can.Conf(ctx.INDEX)||can.ConfIndex(), msg.Option(ctx.ACTION), msg.Option(mdb.TYPE), chat.FLOAT]], list: [
{view: html.OPTION, list: [{type: html.TABLE, list: can.core.List(form, function(item) {
item = can.base.isString(item)? {type: html.TEXT, name: item}: item.length > 0? {type: html.SELECT, name: item[0], values: item.slice(1)}: item
item.type = item.type||(item.values? html.SELECT: item.name == html.TEXT? html.TEXTAREA: html.TEXT), need[item.name] = item.need
item._init = function(target) {
if (item.name && item.name != ctx.ACTION) { target.value = item.value||msg.Option(item.name)||can.Option(item.name)||target.value||"" }
// item.mode = chat.SIMPLE,
can.onappend.figure(can, can.base.Copy({space: msg.Option(web.SPACE), run: function(event, cmds, cb) { var _msg = can.request(event, {_handle: ice.TRUE, action: msg.Option(html.ACTION)}, msg, can.Option())
can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) { item.name && item.value && _msg.Option(item.name, item.value) }); (item.run||can.run)(event, cmds, cb, true)
}, _enter: function(event) { return action.submit(event, can, html.SUBMIT), true }}, item), target)
}, item.onkeydown = function(event) { if (event.key == code.ESCAPE) { event.target.blur() } }
// item.placeholder = can.user.trans(can, item.placeholder||item.name, null, html.INPUT)
// item.title = can.user.trans(can, item.title||item.placeholder||item.name, null, html.INPUT)
return {view: [[item.name, item.type, item.action], html.TR], list: [
{type: html.TD, list: [
{text: [can.user.trans(can, item.name||"", item._trans, html.INPUT), html.LABEL]},
item.need == "must" && {text: ["*", "", "must"]},
]}, {type: html.TD, list: []},
{type: html.TD, _init: function(target) { can.onappend.input(can, item, msg.Option(item.name)||(can._msg? can._msg.Option(item.name): ""), target) }},
], onclick: function(event) {
can.page.Select(can, event.currentTarget, "input", function(target) { target.focus() })
}}
})}]}, html.ACTION,
], onclick: function(event) { if (!can.page.tagis(event.target, html.INPUT, html.TEXTAREA)) { can.onmotion.clearCarte(can) } }}])
var action = can.onappend._action(can, button||[html.SUBMIT, html.CANCEL], ui.action, {
_trans: {submit: msg.Option(web.SUBMIT)},
focus: function(key) { can.onmotion.focus(can, can.page.Select(can, ui._target, key? "input.args[name="+key+"]": html.INPUT_ARGS)[0]) },
Option: function(key, value, hidden) {
if (!key) { var data = kit.Dict(msg.OptionSimple())
can.page.Select(can, ui._target, "input.args", function(target) { data[target.name] = target.value })
return data
}
var target = can.page.Select(can, ui._target, "input.args[name="+key+"]")[0]
if (!target) { return }
if (value != undefined) { target.value = target.value||value }
if (target.value && hidden) { can.onmotion.hidden(can, can.page.parentNode(can, target, html.TR)) }
return target.value
}, },
layout: function(event) { "扫码": function() {
if (event && event.target) { can.onlayout.figure(event, can, ui._target) can.misc.WSS(can, {type: html.CHROME, cmd: "pwd"}, function(event, msg, cmd, arg) { if (!msg) { return }
can.user.isMobile && can.page.style(can, ui._target, html.LEFT, (can.page.width()-ui._target.offsetWidth)/2, html.TOP, 40) if (cmd == "pwd") {
} else { return can.user.toast(can, arg[2], arg[1], -1), msg.Reply()
can.getActionSize(function(left, top, height) { can.page.style(can, ui._target, html.LEFT, left||0, html.TOP, (height/4||0)) }) }
} can.onmotion.resize(can, ui._target) if (cmd == ice.MSG_SESSID) {
return can.misc.CookieSessid(can, arg[0]), msg.Reply(), can.user.reload(true)
}
can.search(event, msg[ice.MSG_DETAIL]||[], function(msg) { msg.Reply() })
})
},
"授权": function() {
can.misc.WSS(can, {type: html.CHROME, cmd: "sso", "user.web": location.href}, function(event, msg, cmd, arg) { if (!msg) { return }
if (cmd == "pwd") {
return location.href = arg[1]
}
if (cmd == ice.MSG_SESSID) {
return can.misc.CookieSessid(can, arg[0]), msg.Reply(), can.user.reload(true)
}
can.search(event, msg[ice.MSG_DETAIL]||[], function(msg) { msg.Reply() })
})
},
"飞书": function() { location.href = "/chat/lark/sso" },
}[button]() }, can.base.Obj(method, ["登录", "扫码", "授权"]))
}, can.page.Modify(can, ui._target, {className: "input login", style: {left: (window.innerWidth-ui._target.offsetWidth)/2, top: window.innerHeight/6}})
cancel: function(event, can, button) { },
can.page.ClassList.del(can, can._fields||can._target, "_process") logout: function(can, force) { if (force||can.user.confirm("logout?")) {
button == "cancel" && msg._cancel && msg._cancel(event), callback("afterInputs", button) can.run({}, [ctx.ACTION, aaa.LOGOUT], function(msg) {
can.onengine.signal(can, "onremove", can.request(event, {query: can.page.getquery(can, ui._target)})), can.page.Remove(can, ui._target) can.misc.Search(can, chat.SHARE)? can.misc.Search(can, chat.SHARE, ""): can.user.reload(true)
},
submit: function(event, can, button) { var args = [], data = {}, err = false
var list = can.page.Select(can, ui._target, html.OPTION_ARGS, function(item) {
if (item.value == "" && need[item.name] == "must") { err = true, item.focus(), can.user.toast(can, item.name+" 是必选字段, 请重新输入") }
return item.name && args.push(item.name, item.value||""), data[item.name] = item.value||""
}); if (err) { return } can.onkeymap.prevent(event)
var _msg = can.request(event); _msg.Option(ctx.ACTION, msg.Option(ctx.ACTION)), _msg.Option("_toast", msg.Option("_toast"))
if (can.core.CallFunc(cb, {event: can.request(event, {_handle: ice.TRUE})._event, button: button, data: data, list: list, args: args, input: action})) {
callback("afterInputs", button)
} else {
action.cancel(event, can, button)
}
}, _target: ui._target, _engine: function(event, can, button) { action.submit(event, can, button) },
});
can.page.Select(can, action._target, "input", function(target) {
target.onfocus = target.onfocus||function(event) { can.onengine.signal(can, "onevent", can.request(event)) }
var onclick = target.onclick; target.onclick = function(event) { can.onengine.signal(can, "onevent", can.request(event, {_type: target.name})), onclick && onclick(event) }
}) })
title && can.page.Select(can, action._target, "input[name=submit]", function(target) { target.value = can.user.trans(can, title) }) } },
action.layout(event), can.onmotion.delay(can, function() { action.focus() }, 300)
function callback(key, button) { var sub = can._fields? can: can.sub; sub && sub.onaction && sub.onaction[key] && sub.onaction[key](event, sub, button, action) } toPNG: function(can, name, text, height, width) {
callback("beforeInputs") if (text.indexOf("<svg") != 0) {
// ui._target._layout = action.layout text = '<svg xmlns="http://www.w3.org/2000/svg">'+text+"</svg>"
return button === true && action.submit(event, can, html.SUBMIT), action }
var img = document.createElement(html.IMG)
img.onload = function() {
var canvas = document.createElement("canvas")
canvas.height = height, canvas.width = width
canvas.getContext("2d").drawImage(img, 0, 0)
var a = document.createElement("a")
a.href = canvas.toDataURL("image/png")
a.download = name, a.click()
}, img.src = "data:image/svg+xml,"+encodeURIComponent(text)
},
copy: function(event, can, text) {
if (navigator.clipboard) { var ok = false
navigator.clipboard.writeText(text).then(function() { ok = true })
if (ok) { return can.user.toastSuccess(can) }
}
var input = can.page.Append(can, event.target.parentNode, [{type: html.TEXTAREA, value: text}]).first
can.onmotion.focus(can, input), document.execCommand("Copy")
can.page.Remove(can, input), can.user.toastSuccess(can)
can.onkeymap.prevent(event)
can.misc.Log("copy", text)
return text
},
carte: function(event, can, meta, list, cb, parent) {
meta = meta||can.ondetail||can.onaction||{}, list = list&&list.length > 0? list: meta.list||[]; if (list.length == 0) { return }
cb = cb||function(event, item, meta) { var cb = meta[item]||meta["_engine"]; can.base.isFunc(cb) && cb(event, can, item) }
var ui = can.page.Append(can, document.body, [{view: chat.CARTE, style: {left: 0, top: 0}, onmouseleave: function(event) {
// can.page.Remove(can, ui._target)
}, list: can.core.List(list, function(item, index) {
return can.base.isString(item)? {view: html.ITEM, list: [{text: can.user.trans(can, item), click: function(event) {
can.user.isMobile && can.page.Remove(can, ui._target)
can.base.isFunc(cb) && cb(event, item, meta, index)
}, onmouseenter: function(event) {
carte._float && can.page.Remove(can, carte._float._target)
} }] }: {view: html.ITEM, list: [{text: can.user.trans(can, item[0])}], onmouseenter: function(event) {
var sub = can.user.carte(event, can, meta, item.slice(1), cb, carte)
carte._float && can.page.Remove(can, carte._float._target), carte._float = sub
can.onlayout.figure(event, can, sub._target, true)
} }
}) }] ); can.onlayout.figure(event, can, ui._target)
var carte = {_target: ui._target, _parent: parent}
null && can.onmotion.float.add(can, chat.CARTE, carte)
ui._target.onmouseover = function(event) {
can.onkeymap.prevent(event)
}
return can.onkeymap.prevent(event), carte
},
carteRight: function(event, can, meta, list, cb, parent) {
var carte = can.user.carte(event, can, meta, list, cb, parent)
can.page.Modify(can, carte._target, {style: {
left: event.clientX-event.offsetX+event.target.offsetWidth-3,
top: carte._target.offsetTop-event.target.offsetHeight+5,
}})
return carte
},
carteClient: function(event, can, meta, list, cb, parent) {
var ui = can.user.carte(event, can, meta, list, cb, parent)
can.page.Modify(can, ui._target, {style: {left: event.clientX, top: event.clientY}})
},
input: function(event, can, form, cb, button) { if (!form || form.length == 0) { return cb() }
var msg = can.request(event)
var ui = can.page.Append(can, document.body, [{view: [html.INPUT], style: {left: 0, top: 0}, list: [
{view: [chat.OPTION, html.TABLE], list: can.core.List(form, function(item) {
item = can.base.isString(item)? {type: html.TEXT, name: item}: item.length > 0? {type: html.SELECT, name: item[0], values: item.slice(1)}: item
item.type = item.type||(item.values? html.SELECT: item.name == html.TEXT? html.TEXTAREA: html.TEXT)
item._init = function(target) {
item.run = function(event, cmds, cb) {
can.request(event, function() { var value = {_handle: ice.TRUE, action: msg.Option(chat.ACTION)}
can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) {
item.name && item.value && (value[item.name] = item.value)
}); return value
}, msg, can.Option()), can.run(event, cmds, cb, true)
}
target.value = target.value||(item.name&&(msg.Option(item.name)||can.Option(item.name)))||""
can.onappend.figure(can, item, target)
}
return {type: html.TR, list: [{type: html.TD, list: [{text: item._trans||can.user.trans(can, item.name)||""}]}, {type: html.TD, list: [can.page.input(can, item)]} ]}
})}, {view: chat.ACTION},
]}]);
var layout = can.onlayout.figure(event, can, ui._target)
if (layout.left == undefined) { if (!layout.top) { layout.top = 32 }
layout.left = window.innerWidth/2-ui._target.offsetWidth/2
layout.right = ""
can.page.style(can, ui._target, layout)
}
can.page.ClassList.add(can, ui._target, chat.FLOAT)
var action = can.onappend._action(can, button||[html.SUBMIT, html.CANCEL], ui.action, {
cancel: function(event) { can.page.Remove(can, ui._target) },
_engine: function(event, can, button) { action.submit(event, can, button) },
submit: function(event, can, button) { var data = {}, args = [], list = []
list = can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) {
return item.name && item.value && args.push(item.name, item.value), data[item.name] = item.value
})
var msg = can.request(event, {_handle: ice.TRUE})
can.base.isFunc(cb) && !cb(event, button, data, list, args) && action.cancel()
}, _target: ui._target,
})
if (button === true) {
action.submit(event, can, "submit")
return action
}
can.page.Select(can, ui._target, html.INPUT_ARGS, function(item, index) {
index == 0 && can.core.Timer(100, function() { can.onmotion.focus(can, item) })
})
return action
}, },
select: function(event, can, type, fields, cb, cbs) { select: function(event, can, type, fields, cb, cbs) {
can.search(can.request(event, {fields: fields||"type,name,text"}), ["Search.onimport.select", type, "", ""], function(list) { var msg = can.request(event, {fields: fields||"type,name,text"})
can.core.Next(list, cb, cbs||function() { can.user.toastSuccess(can) }) can.search(msg._event, ["Search.onimport.select", type, "", ""], function(list) {
}) can.core.Next(list, cb, cbs||function() {
}, can.user.toastSuccess(can)
upload: function(event, can, cb, silent) { var begin = new Date()
var ui = can.page.Append(can, document.body, [{view: [[html.UPLOAD, can.Conf(ctx.INDEX)||can.ConfIndex(), chat.FLOAT]], list: [
html.ACTION, {view: html.OUTPUT, list: ["progress"]}, {view: html.STATUS, list: [html.SHOW, cli.COST, nfs.SIZE]},
]}])
can.user.isMobile && can.page.style(can, ui._target, html.LEFT, 0, html.WIDTH, window.innerWidth)
can.onlayout.figure(event, can, ui._target)
var action = can.onappend._action(can, [{type: html.UPLOAD, onchange: function(event) { action.show(event, 0, event.target.files[0].size, 0) }}, {type: html.BUTTON, name: cli.CLOSE}], ui.action, {
begin: function() { begin = new Date(), can.user.toastProcess(can, "upload")
var upload = can.page.Select(can, ui.action, html.INPUT_FILE)[0]; if (upload.files.length == 0) { return upload.focus() }
var msg = can.request(event, can.Option(), {_handle: ice.TRUE}); msg._upload = upload.files[0], msg._progress = action.show
can.runAction(event, html.UPLOAD, [], function(msg) {
if (msg.IsErr()) {
action.close(), can.user.toastFailure(can, msg.Result())
return
}
can.base.isFunc(cb)? cb(msg): can.Update(), action.close(), can.user.toastSuccess(can, "upload")
})
}, close: function(event) { can.page.Remove(can, ui._target) },
show: function (event, value, total, loaded) {
ui.cost.innerHTML = can.base.Duration(new Date() - begin)
ui.show.innerHTML = value+"%", value == 0 && action.begin(event)
ui.size.innerHTML = can.base.Size(loaded)+nfs.PS+can.base.Size(total)
can.page.styleWidth(can, ui.progress, value*(ui.output.offsetWidth-2)/100)
if (silent) { can.user.toast(can, ui.size.innerHTML, ui.cost.innerHTML, -1, value) }
}, _target: ui._target,
}); can.page.Select(can, ui.action, html.INPUT_FILE)[0].click(), silent && can.onmotion.hidden(can, ui._target); return action
},
downloads: function(can, text, name, ext) { return text && can.user.download(can, URL.createObjectURL(new Blob([text])), name, ext) },
download: function(can, path, name, ext) {
var a = can.page.Append(can, document.body, [{type: html.A, href: path, download: can.core.Keys(name, ext)||path.split(nfs.PS).pop()}])._target
return a.click(), can.page.Remove(can, a), path
},
toimage: function(can, name, target, silent) { var toast = can.user.toastProcess(can, "生成中...")
can.require(["/require/modules/html2canvas/dist/html2canvas.min.js"], function() { toast.close()
html2canvas(target||can._target).then(function (canvas) { var url = canvas.toDataURL(html.IMAGE_PNG)
silent? (can.user.download(can, url, name, nfs.PNG), can.user.toastSuccess(can)): can.user.toastImage(can, name, url)
}) })
}) })
}, },
toastImage: function(can, name, url) { var toast = can.user.toast(can, {content: {img: url, style: {"max-height": window.innerHeight/2, display: html.BLOCK}}, title: name, duration: -1, upload: function(event, can) { var begin = new Date()
action: shy([cli.CLOSE, web.DOWNLOAD], function(event, button) { var ui = can.page.Append(can, document.body, [{view: html.UPLOAD, style: {left: 0, top: 0}, list: [
can.user.input(event, can, [{name: mdb.NAME, value: name}], function(list) { can.user.download(can, url, list[0], nfs.PNG) }) {view: html.ACTION}, {view: html.OUTPUT, list: [{view: "progress"}]},
}), resize: html.IMG, {view: html.STATUS, list: [{view: html.SHOW}, {view: "cost"}, {view: "size"}]},
}) }, ]}]); can.onlayout.figure(event, can, ui._target)
login: function(can, _cb, _msg) {
can.misc.CookieSessid(can, ""), can.misc.Cookie(can, "sessid", "") var action = can.onappend._action(can, [
can.page.ClassList.add(can, document.body.parentNode, aaa.LOGIN), can.onimport.theme(can) {type: html.UPLOAD, onchange: function(event) {
function check() { action.show(event, 0, event.target.files[0].size, 0)
if (can.misc.CookieSessid(can) || can.user.info.sessid) { can.page.ClassList.del(can, document.body.parentNode, aaa.LOGIN), can.onimport.theme(can) }}, cli.CLOSE,
can.onmotion.clearFloat(can), can.onmotion.delay(can, function() { socket._close = true, socket.close() }) ], ui.action, {
return can.base.isFunc(_cb) && _cb(), _cb = null, true close: function(event) { can.page.Remove(can, ui._target) },
} can.core.Timer(1000, function() { check() }) begin: function(event) { begin = new Date()
} var upload = can.page.Select(can, ui.action, "input[type=file]")
var ui, socket = can.ondaemon._init(can, "", aaa.LOGIN, function(event, msg, cmd, arg) { if (upload[0].files.length == 0) { return upload[0].focus() }
if (cmd == ice.MSG_SESSID) {
if (!can.misc.CookieSessid(can, arg[0])) { can.user.info.sessid = arg[0] } check() var msg = can.request(event, can.Option(), {_handle: "true"})
} else if (cmd == cli.PWD) { if (check() || ui) { return } can._wss_name = can.ondaemon._list[0] = arg[0] msg._upload = upload[0].files[0], msg._progress = action.show
var hassso = false
var _list = [], list = {}; _msg.Table(function(value) { if (!value.order) { return } can.run(event, [ctx.ACTION, html.UPLOAD], function(msg) {
can.user.trans(can, kit.Dict(value.name, value.help)) can.user.toastSuccess(can), can.Update(), action.close()
if (value.type == "oauth") { hassso = true } }, true)
if (value.type == cli.QRCODE) { },
_list.push(value.name), list[value.name] = function(target) { show: function (event, value, total, loaded) { now = new Date()
can.user.isWeiXin || can.page.Modify(can, target, arg[2]) value == 0 && action.begin(event)
}
} else if (value.type == mdb.PLUGIN) { ui.show.innerHTML = value+"%"
_list.push(value.name), list[value.name] = function(target) { ui.cost.innerHTML = can.base.Duration(now - begin)
can.onappend.plugin(can, {space: value.space, index: value.index, args: can.core.Split(value.args), height: html.IFRAME_HEIGHT, width: html.IFRAME_HEIGHT, style: html.OUTPUT}, function(sub) { ui.size.innerHTML = can.base.Size(loaded)+ice.PS+can.base.Size(total)
var run = sub.run; sub.run = function(event, cmds, cb) { var msg = can.request(event, {space: arg[0]}); can.page.exportValue(can, msg), run(event, cmds, cb) } can.page.Modify(can, ui.progress, {style: {width: value*(ui.output.offsetWidth-2)/100}})
}, ui.output) },
} }); can.page.Select(can, ui.action, "input[type=file]")[0].click()
}
}) return action
var _cmd = "space login "+arg[0]
ui = can.onappend.tabview(can, list, _list, can.page.Append(can, document.body, [{view: "input login float flex"}])._target)
can.user.title(can.user.info.titles)
can.page.Append(can, ui._target, [{view: [[html.DISPLAY, html.FLEX]], list: [
{text: [can.user.trans(can, "or command login", "或命令行授权: "), html.LABEL]},
{text: ["$ "+_cmd, "", html.ITEM], title: "点击复制,并后台执行此命令,即可登录", style: {cursor: "copy"}, onclick: function() { can.user.copy(event, can, _cmd) }},
hassso && {text: [can.user.trans(can, "or oauth login", "或第三方授权: "), html.LABEL]},
hassso && {view: [["sso", html.FLEX]], list: _msg.Table(function(value) {
return value.type == "oauth" && {view: [[html.ITEM, value.name, html.FLEX]], title: value.link, list: [
{img: can.misc.Resource(can, value.icons)}, {text: can.user.trans(can, value.name, value.help)},
], onclick: function() {
can.user.jumps(can.base.MergeURL(value.link, ice.BACK, location.href))
}, _init: function(target) {
if (document.referrer) { var u = new URL(document.referrer)
value.link.indexOf(u.origin) == 0 && can.onmotion.delay(can, function() { target.click() }, 300)
}
}}
}) },
// {text: [can.user.info.titles]},
]}]), window.parent != window && window.innerHeight < 480 && can.onmotion.hidden(can, ui.output)
can.page.style(can, ui._target, {
left: (can.page.width()-ui._target.offsetWidth)/2,
top: can.user.isMobile? 20: can.page.height() < 480? (can.page.height()-ui._target.offsetHeight)/2: (can.page.height()-can.base.Min(ui._target.offsetHeight, html.IFRAME_HEIGHT)-html.HEADER_HEIGHT-html.ACTION_HEIGHT)/4+html.HEADER_HEIGHT,
})
}
})
}, },
logout: function(can) { can.user.toastConfirm(can, aaa.LOGOUT, "", function() { can.runAction({}, aaa.LOGOUT, [], function(msg) { download: function(can, path, name) {
can.misc.Cookie(can, "user_uid", "") var a = can.page.Append(can, document.body, [{type: html.A, href: path, download: name||path.split(ice.PS).pop()}]).first
can.misc.CookieSessid(can, ""), can.misc.Search(can, chat.SHARE)? can.misc.Search(can, chat.SHARE, ""): can.user.reload(true) a.click(), can.page.Remove(can, a)
}) }) },
header: function(can) { if (!can._root) { return } var header = can._root.Header
var meta = {
time: !can.user.isMobile && {view: [[html.ITEM, "state", mdb.TIME, html.FLEX]], _init: function(target) {
can.onappend.figure(can, {action: "date", _hold: true}, target, function(sub, value) {})
can.core.Timer({interval: 100}, function() { can.page.Modify(can, target, can.user.time(can, null, "%w %H:%M:%S")) })
}},
avatar: {view: [[html.ITEM, "state", aaa.AVATAR]], list: [{img: can.misc.Resource(can, can.user.info.avatar)}], onclick: function(event) { header && header.onaction.avatar(event, header) }},
usernick: {view: [[html.ITEM, "state", aaa.USERNICK, html.FLEX], "", can.user.info.usernick], onclick: function(event) { header && header.onaction.usernick(event, header) }, _init: function(target) {
can = can._fields? can.sup: can
can.ui.head = target.parentNode
}},
qrcode: {view: [[html.ITEM, "state", cli.QRCODE]], list: [{icon: icon.qrcode}], onclick: function(event) { var _can = can._fields? can.sup: can; _can.onaction["生成链接"](event, _can) }},
}; return can.core.List(can.base.getValid(can.core.List(arguments).slice(1), [html.SPACE, mdb.TIME, aaa.AVATAR, aaa.USERNICK, cli.QRCODE]), function(item) { return meta[item] })
}, },
email: function(can) { downloads: function(can, text, name) { can.user.download(can, URL.createObjectURL(new Blob([text])), name) },
can.page.Select(can, document.body, html.IFRAME, function(target) { camera: function(can, msg, cb) {
can.page.style(can, target, html.HEIGHT, can.page.height()) navigator.getUserMedia({video: true}, cb, function(error) {
can.page.style(can, target, html.WIDTH, can.page.width()) can.misc.Log(error)
}) })
}, },
}) })

View File

@ -1,10 +1,19 @@
{ {
"manifest_version": 2, "name": "volcanos", "version": "0.0.1", "manifest_version": 2,
"background": {"page": "/publish/chrome/daemon.html"}, "name": "volcanos", "version": "0.0.1",
"browser_action": {"default_popup": "/publish/chrome/popup.html"}, "background": {"page": "/publish/chrome/chrome.html"},
"content_scripts": [ "browser_action": {"default_popup": "/publish/chrome/popup.html"},
{"matches": ["<all_urls>"], "permissions": [ "content_scripts": [{"matches": ["<all_urls>"], "css": [
"tabs", "history", "cookies", "bookmarks", "contextMenus", "notifications", "http://localhost:9020/*" "/publish/chrome/contexts.css"
], "css": ["/publish/chrome/contexts.css"], "js": ["/proto.js", "/page/cache.js", "/publish/chrome/contexts.js"]} ], "js": [
] "/page/can.js", "/publish/chrome/contexts.js"
]}], "permissions": [
"tabs",
"history",
"cookies",
"bookmarks",
"contextMenus",
"notifications",
"http://localhost:9020/*"
]
} }

266
page/index.css Normal file
View File

@ -0,0 +1,266 @@
body { background-color:black; color:cyan; margin:0; padding:0; font-size:14px; }
h1, h2, h3 { clear:both; }
a { color:yellow; }
.hide, .hidden { display:none; }
tr.show { background-color:red; }
div.item { cursor:pointer; }
div.code {
background-color:#343a3445; color:white;
border:solid 3px green; padding:10px;
box-shadow:4px 4px 20px 4px #626bd0;
text-align:left; white-space:pre;
clear:both; overflow:auto;
}
div.story { text-align:left; white-space:pre; }
div.story[data-type=spark] {
background-color:#2169a9a6; color:white;
box-shadow:4px 4px 10px 1px #626bd0;
margin:10px 0px; padding:4px 10px;
border-left:solid 4px blue;
overflow:auto; cursor:copy;
}
select {
background-color:black; color:cyan;
box-shadow:4px 4px 10px 1px #626bd0;
height:1.92rem; padding:0 10px;
cursor:pointer;
}
textarea { background-color:cyan; width:400px; height:60px; white-space:pre; }
input[type=button] { background-color:black; color:cyan; cursor:pointer; }
input[type=text] {
background-color:cyan; color:black;
box-shadow:4px 4px 10px 1px #626bd0;
height:1.65rem; width:82px;
padding:0 4px;
}
input[name=date] { width:150px; }
input[name=path] { width:160px; }
input[name=line] { width:40px; }
input[name=text] { width:160px; }
input[name=url] { width:320px; }
input[name=cmd] { width:240px; background-color:black; color:white; }
table.layout { margin:0; border:0; padding:0; border-spacing:0; }
table.layout tr { margin:0; border:0; padding:0; }
table.layout th { margin:0; border:0; padding:0; }
table.layout td { margin:0; border:0; padding:0; vertical-align:top; }
table.layout td.content { position:relative; }
table.layout div.toggle {
background-color:#e1aeae45;
height:100px; top:20%;
position:absolute;
}
table.layout div.toggle>div {
display:table-cell;
vertical-align:middle;
color:white;
height:95px;
}
table.layout div.toggle.project {
left:0px; min-width:10px;
border-top-right-radius:10px;
border-bottom-right-radius:10px;
}
table.layout div.toggle.profile {
right:0px; min-width:10px;
border-top-left-radius:10px;
border-bottom-left-radius:10px;
}
table.layout div.toggle.display {
overflow:hidden;
margin-top:-12px;
height:10px; width:100px;
position:sticky; left:20%;
border-top-left-radius:10px;
border-top-right-radius:10px;
}
table.layout div.toggle.display>div { height:10px; width:100px; text-align:center; color:white; }
table.content { border:0; white-space:pre; overflow:auto; }
table.content tr { background-color:#04272f45; }
table.content th { background-color:#0fbd45; padding:2px 6px; cursor:pointer; }
table.content td { padding:2px 6px; max-width:800px; overflow:auto; }
td>input[type=button][name=create] { background-color:blue; }
td>input[type=button][name=remove] { background-color:red; }
td>input[type=button][name=start] { background-color:blue; }
td>input[type=button][name=stop] { background-color:red; }
legend { box-shadow:4px 4px 20px 4px #626bd0; cursor:pointer; }
fieldset { margin:0; border:0; padding:0; }
fieldset>form.option { float:left; display:contents; font-size:1.1rem; }
fieldset>form.option>div.item { float:left; margin-right:3px; height:2rem; min-height:25px; vertical-align:middle; }
fieldset>form.option>div.item>label { display:none; }
fieldset>form.option>div.item input.args.char { width:20px; }
fieldset>form.option>div.item input.args.tiny { width:40px; }
fieldset>form.option>div.item input.args.long { width:240px; }
fieldset>form.option>div.item input.args.full { width:480px; }
fieldset>form.option>div.item input.args[name=ID] { width:48px; }
fieldset>form.option>div.item input.args[name=id] { width:48px; }
fieldset>form.option>div.item input.args[name=limit] { width:48px; }
fieldset>form.option>div.item input.args[name=offset] { width:48px; }
fieldset>form.option>div.item input.args[name=offend] { width:48px; }
fieldset>form.option>div.item.textarea { clear:both; margin-top:4px; }
fieldset>div.action { float:left; display:contents; font-size:1.1rem; }
fieldset>div.action>div.item { float:left; margin-right:3px; height:2rem; vertical-align:middle; }
fieldset>div.action>div.item.space { width:10px; }
fieldset div.action>div.item>label { display:none; }
fieldset>div.action>div.tabs { float:left; margin:0; padding:4px; cursor:pointer; }
fieldset>div.action>div.tabs.over { background-color:blue; color:blue; }
fieldset>div.output { clear:both; overflow:auto; position:relative; }
fieldset>div.output td.project { background-color:#435f8c8c; }
fieldset>div.output td.project div.project { float:left; overflow:auto; min-width:88px; max-width:240px; }
fieldset>div.output td.project div.project div.item { padding:2px 10px; text-align:left; clear:both; cursor:pointer; white-space:pre; }
fieldset>div.output td.project div.project div.list { margin-left:10px; }
fieldset>div.output td.profile { background-color:#71909c91; }
fieldset>div.output td.profile div.profile { overflow:auto; }
fieldset>div.status { clear:both; }
fieldset>div.status>div.item { float:left; padding:4px; height:18px; }
fieldset.panel>legend { display:none; }
fieldset.plugin { margin:10px; padding:10px; background-color:#061c3c9e; box-shadow:2px 2px 10px 4px #626bd0; }
fieldset.plugin>div.action { float:none; display:block; height:1.8rem; overflow:auto; }
fieldset.plugin>div.status { border-top:1px solid darkcyan; }
fieldset.output { margin:0; padding:0; }
fieldset.output>legend { display:none; }
fieldset.output>form.option { display:none; }
fieldset.output>div.action { display:none; }
fieldset.output>div.status { display:none; }
fieldset.story>legend { display:block; padding:2px 20px; letter-spacing:4px; }
fieldset.story>div.status { border-top:1px solid darkcyan; }
fieldset.float { background-color:#023531cf; margin:0px; padding:0px; position:absolute; }
fieldset.float>legend { float:left; }
fieldset.float>div.action { display:block; float:none; height:2rem; overflow:auto; }
fieldset.float table { color:white; }
fieldset.input { background-color:#0d4142a6; position:fixed; top:32px; }
fieldset.input legend { display:none; }
fieldset.input div.output { max-height:400px; }
fieldset.input table { color:white; }
fieldset.input td { word-break:keep-all; }
fieldset.input.date table { text-align:center; width:280px; }
fieldset.input.date>div.action { height:4rem; }
body>div.toast { background-color:#0e3369b3; color:yellow; padding:5px; overflow:auto; position:fixed; }
body>div.toast div.title { float:left; cursor:copy; word-break:break-all; }
body>div.toast div.duration { float:right; cursor:pointer; }
body>div.toast div.content { text-align:center; white-space:pre; clear:both; }
body>div.toast div.progress { height:10px; border:solid 2px green; margin-left:-2px; clear:both; }
body>div.toast div.progress div.current { height:10px; background-color:red; }
body>div.toast div.action div.item { float:left; }
body>div.carte { background-color:#295b61; color:white; min-width:80px; padding:4px; position:fixed; z-index:0; }
body>div.carte div.item { padding:3px 12px; }
body>div.input { background-color:#0d4142a6; position:fixed; z-index:0; }
body>div.input div.item { float:left; }
body>div.input input[type=text] { width:171px; }
body>div.input input[name=username] { width:171px; }
body>div.input input[name=password] { width:171px; }
body>div.input textarea {
box-shadow:4px 4px 10px 1px #626bd0;
border:2px inset #14a58e;
width:171px; height:60px;
background-color:cyan;
padding:4px;
}
body>div.input.login { padding:10px; }
body>div.upload { background-color:black; color:yellow; position:fixed; padding:5px; }
body>div.upload div.item { float:left; }
body>div.upload div.output { border:solid 1px red; clear:both; }
body>div.upload div.progress { background-color:red; width:0; height:10px; }
body>div.upload div.status div.cost { float:left; }
body>div.upload div.status div.show { float:right; }
body>div.upload div.status div.size { text-align:center; }
body>div.upload input[type=file] { width:240px; }
* { tab-size:4; }
textarea { tab-size:2; }
input, select, option, table.content, div.item, div.code, code.story, div.story[data-type=spark] { font-size:1.1rem; font-family:monospace; }
legend { font-size:1.2rem; }
fieldset>div.status>div.item>label { font-size:0.6rem; color:#bdb8b8e0; }
body>div.toast div.title { color:#cae850; }
body>div.toast div.duration { color:gray; }
.select { background-color:red; }
div.item.select, div.item:hover { background-color:red; }
div.tabs.select, div.tabs:hover { background-color:#2e515f; border-bottom:solid 2px red; }
div.story[data-type=spark] span:hover { background-color:#c10c8a; box-shadow:4px 4px 10px 1px #29318e; }
h1:hover, h2:hover, h3:hover { background-color:green; cursor:pointer; }
input[type=button]:hover { background-color:gray; color:cyan; }
input[type=text]:hover { background-color:white; }
input[name=cmd]:hover { background-color:white; color:black; }
table.content tr.select, table.content tr:hover { background-color:green; }
table.content th:hover, table.content td.select, table.content td:hover { background-color:red; }
body>fieldset.input.date table td:hover { background-color:red; }
body.white { background-color:rgba(5,34,56,0.75); color:white; }
body.white select { background-color:#99CC66; color:white; border:2px solid #99CC66; border-radius:10px 10px 10px 10px; }
body.white input[type=button] { background-color:#FF9900; color:white; border:2px solid #FF9900; border-radius:10px; }
body.white input[type=text] { background-color:white; color:black; border:2px solid #14a58e; border-radius:6px; }
body.white input[name=cmd] { background-color:black; color:white; width:240px; }
body.white table { color:black; }
body.white table tr { background-color:#e1f1ff1f; }
body.white table th { background-color:#99CCFF; }
body.white table td>input[type=button][value=结束] { background-color:red; }
body.white table td>input[type=button][value=停止] { background-color:red; }
body.white table td>input[type=button][value=启动] { background-color:#52ce78; }
body.white table td>input[type=button][name=create] { background-color:blue; }
body.white table td>input[type=button][name=remove] { background-color:red; }
body.white fieldset>div.status>div.item>label { font-size:0.6rem; color:#cefbfbe0; }
body.white fieldset.Action { color:black; }
body.white fieldset.Action>div.action { color:white; }
body.white fieldset.Action>div.action div.item { height:21px; }
body.white fieldset.Action fieldset.plugin { background-color:#ffffff78; }
body.white fieldset.Action fieldset.plugin legend { background-color:#339999; color:white; border-radius:10px 10px 10px 10px; }
body.white fieldset.input table { color:white; }
body.white>div.input textarea { border:2px solid #14a58e; border-radius:6px; }
body.print { background-color:white; color:black; }
body.print a { color:blue; }
body.print select { box-shadow:0px 0px 0px 0px #626bd0; }
body.print input[type=text] { box-shadow:0px 0px 0px 0px #626bd0; }
body.print div.code { background-color:white; }
body.print legend { box-shadow:0px 0px 0px 0px #626bd0; }
body.print fieldset.Header { background-color:white; color:black; }
body.print fieldset.River { background-color:white; color:black; }
body.print fieldset.River>div.output div.list div.item { background-color:white; }
body.print fieldset.Action { background-color:white; }
body.print fieldset.Footer { background-color:white; color:black; }
body.white input[type=button]:hover { background-color:#FFCC33; border:2px solid #FFCC33; }
body.white input[type=text]:hover { background-color:cyan; }
body.white input[name=cmd]:hover { background-color:white; color:black; }
body.white table.content tr:hover { background-color:green; }
body.white fieldset.Action fieldset.plugin legend:hover { background-color:#6ee4e4; }
body.print fieldset.River>div.output div.item.select { background-color:white; border:solid 2px red; }
body.mobile select { font-size:1.4rem; height:1.4rem; margin-top:3px; }
body.mobile legend { font-size:2rem; }
body.mobile input { font-size:1.2rem; }
body.mobile input[type=text] { margin-top:5px; height:1.4rem; }
body.mobile fieldset.Header.head { width:-webkit-fill-available; }
body.mobile fieldset.Header.head { background-color:#000000b8; font-size:2rem; height:2rem; position:fixed; top:0; }
body.mobile fieldset.Header.head div.output { height:2rem; }
body.mobile fieldset.Header.head>div.output>div { height:1.5rem; }
body.mobile fieldset.Header.head>div.output div.menu { height:1.5rem; }
body.mobile fieldset.Header.head div.state.time { display:none; }
body.mobile fieldset.River.left { position:fixed; top:2rem; background-color:#243950bf; min-width:240px; font-size:2rem; }
body.mobile fieldset.River>div.output div.list div.item { font-size:2rem; }
body.mobile fieldset.Action.main { margin-top:4rem; }
body.mobile fieldset.Action.main.cmd { margin-top:0; margin-bottom:0; }
body.mobile fieldset.Footer.foot { width:-webkit-fill-available; }
body.mobile fieldset.Footer.foot { background-color:#000000b8; font-size:2rem; height:2rem; position:fixed; bottom:0; }
body.mobile fieldset.Footer.foot { display:none; }
body.mobile.landscape fieldset.Header.head { position:unset; }
body.mobile.landscape fieldset.Header.head div.state.time { display:block; }
body.mobile.landscape fieldset.Action.main { margin-top:0; margin-bottom:0; }
body.mobile.landscape fieldset.Footer.foot { position:unset; }
body.mobile>div.carte { font-size:2rem; }
body.mobile>div.input.login input { font-size:1.2rem; }

14
page/index.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=0.8,user-scalable=no">
<meta charset="utf-8"><title>volcanos</title>
<link rel="shortcut icon" type="image/ico" href="/favicon.ico">
<link rel="stylesheet" type="text/css" href="/page/cache.css">
<link rel="stylesheet" type="text/css" href="/page/index.css">
</head>
<body>
<script src="/proto.js"></script>
<script src="/page/cache.js"></script>
<script src="/page/index.js"></script>
</body>

118
page/index.js Normal file
View File

@ -0,0 +1,118 @@
Volcanos({name: "chat", panels: [
{name: "Header", help: "标题栏", pos: chat.HEAD, state: ["time", "usernick", "avatar"]},
{name: "River", help: "群聊组", pos: html.LEFT, action: ["create", "refresh"]},
{name: "Action", help: "工作台", pos: chat.MAIN},
{name: "Footer", help: "状态条", pos: chat.FOOT, state: ["ncmd"]},
{name: "Search", help: "搜索框", pos: chat.AUTO},
], main: {name: "Header", list: ["/publish/order.js"]}, river: {
serivce: {name: "运营群", storm: {
wx: {name: "公众号 wx", list: [
{name: "微信公众号", help: "wx", index: "web.wiki.word", args: ["usr/icebergs/misc/wx/wx.shy"]},
]},
mp: {name: "小程序 mp", list: [
{name: "微信小程序", help: "mp", index: "web.wiki.word", args: ["usr/icebergs/misc/mp/mp.shy"]},
]},
lark: {name: "机器人 lark", list: [
{name: "飞书机器人", help: "lark", index: "web.wiki.word", args: ["usr/icebergs/misc/lark/lark.shy"]},
]},
}},
product: {name: "产品群", storm: {
office: {name: "办公 office", list: [
{name: "feel", help: "影音媒体", index: "web.wiki.feel"},
{name: "draw", help: "思维导图", index: "web.wiki.draw"},
{name: "data", help: "数据表格", index: "web.wiki.data"},
{name: "plan", help: "计划任务", index: "web.team.plan"},
{name: "think", help: "智库", index: "web.wiki.word", args: ["usr/learning/"]},
{name: "index", help: "索引", index: "web.wiki.word", args: ["usr/learning/index.shy"]},
{name: "context", help: "编程", index: "web.wiki.word", args: ["src/main.shy"]},
]},
english: {name: "英汉 english", list: [
{name: "english", help: "英汉", index: "web.wiki.alpha.alpha", args: ["word", "hi"]},
{name: "chinese", help: "汉英", index: "web.wiki.alpha.alpha", args: ["line", "你好"]},
{name: "wubi", help: "五笔", index: "web.code.input.wubi", args: ["word", "wqvb"]},
{name: "wubi", help: "五笔", index: "web.code.input.wubi", args: ["line", "你好"]},
]},
learning: {name: "学习 learning", list: [
{name: "golang", help: "编程", index: "web.wiki.word", args: ["usr/golang-story/src/main.shy"]},
{name: "tmux", help: "粘贴", index: "web.code.tmux.text"},
{name: "study", help: "学习", index: "web.wiki.word", args: ["usr/learning/study.shy"]},
]},
chrome: {name: "爬虫 chrome", list: [
{name: "feel", help: "网页爬虫", index: "web.wiki.feel", args: ["spide/"], feature: {
display: "/plugin/local/wiki/feel.js",
height: 200, limit: 3,
}},
{name: "cached", help: "爬虫缓存", index: "web.code.chrome.cache", args: []},
{name: "spided", help: "网页爬虫", index: "web.code.chrome.spide", args: location && location.protocol && location.protocol=="chrome-extension:"? ["1", "", "spide"]: ["1"]},
{name: "modify", help: "编辑页面", index: "web.code.chrome.modify", args: []},
]},
}},
project: {name: "研发群", storm: {
studio: {name: "研发 studio", list: [
{name: "vimer", help: "编辑器", index: "web.code.vimer", args: ["src/", "main.go"], _action: ["autogen", "compile", "binpack"]},
{name: "repos", help: "代码库", index: "web.code.git.status"},
{name: "plan", help: "任务表", index: "web.team.plan"},
{name: "ctx", help: "上下文", index: "web.wiki.word", args: ["src/main.shy"]},
]},
web: {name: "网页 web", list: [
{name: "HTML5", help: "浏览器", index: "web.wiki.word", args: ["usr/icebergs/misc/chrome/chrome.shy"]},
]},
cli: {name: "命令 cli", list: [
{name: "bash", help: "命令行", index: "web.wiki.word", args: ["usr/icebergs/misc/bash/bash.shy"]},
{name: "git", help: "代码库", index: "web.wiki.word", args: ["usr/icebergs/misc/git/git.shy"]},
{name: "vim", help: "编辑器", index: "web.wiki.word", args: ["usr/icebergs/misc/vim/vim.shy"]},
{name: "tmux", help: "命令行", index: "web.wiki.word", args: ["usr/icebergs/misc/tmux/tmux.shy"]},
]},
linux: {name: "系统 linux", list: [
{name: "idc", help: "平台", index: "web.wiki.word", args: ["usr/linux-story/idc/idc.shy"]},
{name: "iso", help: "系统", index: "web.wiki.word", args: ["usr/linux-story/iso/iso.shy"]},
{name: "iot", help: "设备", index: "web.wiki.word", args: ["usr/linux-story/iot/iot.shy"]},
{name: "cli", help: "命令", index: "web.wiki.word", args: ["usr/linux-story/cli/cli.shy"]},
{name: "linux", help: "系统", index: "web.wiki.word", args: ["usr/linux-story/src/main.shy"]},
]},
nginx: {name: "代理 nginx", list: [
{name: "nginx", help: "代理", index: "web.wiki.word", args: ["usr/nginx-story/src/main.shy"]},
]},
context: {name: "编程 context", list: [
{name: "golang", help: "编程", index: "web.wiki.word", args: ["usr/golang-story/src/main.shy"]},
]},
redis: {name: "缓存 redis", list: [
{name: "redis", help: "缓存", index: "web.wiki.word", args: ["usr/redis-story/src/main.shy"]},
{name: "kafka", help: "队列", index: "web.wiki.word", args: ["usr/redis-story/src/kafka/kafka.shy"]},
]},
mysql: {name: "存储 mysql", list: [
{name: "mysql", help: "数据存储", index: "web.wiki.word", args: ["usr/mysql-story/src/main.shy"]},
{name: "clickhouse", help: "数据存储", index: "web.wiki.word", args: ["usr/mysql-story/src/clickhouse/clickhouse.shy"]},
]},
}},
profile: {name: "测试群", storm: {
website: {name: "定制 website", index: [
"web.chat.website",
"web.chat.div",
"web.code.vimer",
"web.dream",
]},
release: {name: "发布 release", index: [
"web.code.publish", "web.code.compile", "web.code.autogen", "web.code.git.server",
]},
research: {name: "测试 research", index: [
"web.code.favor", "web.code.bench", "web.code.pprof",
"web.code.case",
]},
}},
operate: {name: "运维群", storm: {
aaa: {name: "权限 aaa", index: [
"user", "totp", "sess", "role",
]},
web: {name: "应用 web", index: [
"serve", "space", "dream", "route",
"share", "spide", "cache", "story",
]},
cli: {name: "系统 cli", index: [
"qrcode", "daemon", "system", "runtime",
]},
nfs: {name: "文件 nfs", index: [
"cat", "dir", "tail", "trash",
]},
}},
}})

View File

@ -1,28 +1,65 @@
fieldset.Action { min-width:var(--project-width); } fieldset.Action {
fieldset.Action>div.output { overflow-x:hidden; } background-color:rgba(114, 153, 162, 0.54);
fieldset.Action>div.action:not(.flex) { width:100%; display:none; background-color:var(--plugin-bg-color); } min-width:160px;
fieldset.Action>div.action div.item { font-style:italic; font-size:1.1rem; padding:10px 20px; } }
fieldset.Action.tabs>div.action { display:flex; justify-content:center; display:none; } fieldset.Action>div.action {
fieldset.Action.tabs>div.output>fieldset>legend { display:none; } /* width:-webkit-fill-available; */
fieldset.Action.tabs>div.output>fieldset.plugin:not(.select) { display:none; } background-color:#159cc7b0;
fieldset.Header div.Action { display:contents; } display:none; height:28px;
fieldset.Action.tabview:not(.cmd)>div.output>fieldset.plugin>legend { float:left !important; } padding:0; margin:0;
fieldset.Action.tabview>div.output>fieldset.plugin:not(.select) { display:none; } position:absolute;
fieldset.Action.vertical>div.output>fieldset.plugin { float:left; } }
fieldset.Action.horizon>div.output>fieldset.plugin { float:left; }
fieldset.Action.horizon>div.output>fieldset.plugin>div.status { display:none; } fieldset.Action div.output fieldset.plugin:hover {
fieldset.Action.flow>div.output>fieldset.plugin { float:left; } box-shadow:4px 4px 12px 6px #626bd0;
fieldset.Action.free>div.output>fieldset.plugin { position:absolute; z-index:5; } }
fieldset.Action.free>div.output>fieldset.plugin.select { z-index:9; } fieldset.Action div.output fieldset.plugin legend {
fieldset.Action.free>div.output { overflow:hidden; } margin-top:4px 5px;
fieldset.Action.grid>div.output>fieldset.plugin { float:left; } padding:0px 10px;
fieldset.Action.grid>div.output>fieldset.plugin>div.status { display:none; } background-color:#0c739cd9;
fieldset.Action.tabview>div.project.toggle { display:none; } }
fieldset.Action.vertical>div.project.toggle { display:none; } fieldset.Action div.output fieldset.plugin legend:hover {
fieldset.Action.horizon>div.project.toggle { display:none; } background:red;
fieldset.Action.free>div.project.toggle { display:none; } }
fieldset.Action.grid>div.project.toggle { display:none; }
fieldset.Action>div.toggle.project { padding-top:50px; height:150px; top:30%; } fieldset.Action.tabs>div.action {
body:not(.mobile) fieldset.Action>div.project.toggle { display:none; } display:block;
body.mobile fieldset.Action>div.project.toggle { top:60%; } }
// body.mobile fieldset.Action>div.action div.item { display:none; } fieldset.Action.tabs>div.output {
margin-top:28px;
}
fieldset.Action.tabs>div.output>fieldset>legend {
display:none;
}
fieldset.Action.flow>div.output fieldset.plugin {
float:left;
}
fieldset.Action.grid>div.output fieldset.plugin {
float:left; overflow:auto;
}
fieldset.Action.grid>div.output fieldset.plugin>div.output {
overflow:auto;
}
fieldset.Action.tabs>div.output fieldset.plugin {
display:none;
float:left;
}
fieldset.Action.tabs>div.output fieldset.plugin.select {
display:block;
}
fieldset.Action.free>div.output fieldset.plugin {
position:absolute;
}
fieldset.Action.free>div.output fieldset.plugin.select {
display:block;
}
fieldset.panel.cmd>div.output>fieldset.plugin {
margin:0; padding:0;
}
fieldset.panel.cmd>div.output>fieldset.plugin>legend {
float:left; padding:0 10px; margin-right:3px;
height:25px;
background-color:darkcyan;
cursor:pointer;
}

View File

@ -1,204 +1,249 @@
(function() { const ALL = "all", TABS = "tabs", TABVIEW = "tabview", VERTICAL = "vertical", HORIZON = "horizon", GRID = "grid", FREE = "free", FLOW = "flow", PAGE = "page", CAN_LAYOUT = "can.layout" Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg) {
Volcanos(chat.ONIMPORT, { var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM)
_init: function(can, msg) { var river = can.Conf(chat.RIVER), storm = can.Conf(chat.STORM), list = can.db.list can.onmotion.clear(can), can.core.Next(msg.Table(), function(item, next) {
var _select; can.onmotion.clear(can), can.onaction.layout(can, list[3]) item.height = can.Conf(html.HEIGHT)-can.Conf(html.MARGIN_Y)
can.core.Next(msg.Table(), function(item, next, index) { item.type = chat.PLUGIN, item.mode = can.Mode(); if (item.deleted == ice.TRUE) { return next() } item.width = can.Conf(html.WIDTH)-can.Conf(html.MARGIN_X)
if (msg.Length() == 1) { item.height = can.ConfHeight()-can.Conf(html.MARGIN_Y), can.base.isIn(item.index, web.CHAT_MACOS_DESKTOP, web.CHAT_MESSAGE, web.WIKI_PORTAL) && (item.style = html.OUTPUT) } item.feature = can.base.Obj(item.feature||item.meta)
can.base.isIn(item.index, ssh.CLOUD_PROFILE) && (item.style = html.OUTPUT) item.inputs = can.base.Obj(item.inputs||item.list)
if (list.length == 0) {
can.user.info.nodetype == web.SERVER && item._command == web.DREAM && (list = [river, storm, item._command])
can.user.info.nodetype == web.WORKER && item._command == web.VIMER && (list = [river, storm, item._command])
}
can.onappend.plugin(can, item, function(sub, meta, skip) { can.onappend.plugin(can, item, function(sub, meta, skip) {
can.user.isMobile || sub.Conf(ice.AUTO, cli.DELAY) can.onimport._plugin(can, river, storm, sub, meta), skip || next()
if (msg.detail && can.base.isIn(meta.index, "can._notfound")) { sub.Conf(ctx.INDEX, msg.detail[index+3]) }
sub.run = function(event, cmds, cb) { return can.run(can.request(event, {pod: meta.pod||meta.space}), (can.base.beginWith(meta.index, "can.")? [meta.index]: [river, storm, meta.id||meta.index]).concat(cmds), cb) }
sub.onexport.output = function() { msg.Length() > 1 && can.onexport.isauto(can) && can.page.style(can, sub._output, html.HEIGHT, "", html.MAX_HEIGHT, ""), can.onaction.layout(can, list[3]) }
can.onaction.layout(can, list[3]), can.onimport._tabs(can, sub, meta), can._plugins = (can._plugins||[]).concat([sub])
can.onexport.layout(can) && list[0] == river && list[1] == storm? (can.base.isIn(list[2], sub.ConfIndex()) && (_select = sub)): (index == 0 && (_select = sub)), _select = _select||sub, skip || next()
}) })
}, function() { can.onaction.layout(can, list[3]), _select._tabs.click() }) }, function() { can.onimport._menu(can, msg), can.onkeymap._init(can)
can.onaction.onstorm_select(can, msg, river, storm)
})
}, },
_tabs: function(can, sub, meta) { var _init = true _plugin: function(can, river, storm, sub, meta) { sub._target._meta = meta
var tabs = [{view: [[html.TABS, meta.name], "", can.user.trans(can, meta.name, meta.help)], title: meta.help, onclick: function(event) { can._current = sub sub.run = function(event, cmds, cb) { var msg = sub.request(event)
return can.run(event, can.misc.concat(can, [river, storm, meta.id||meta.index], cmds), function(msg) {
can.base.isFunc(cb) && cb(msg)
})
}, can._plugins = can.misc.concat(can, can._plugins, [sub])
meta.id && (sub._option.dataset = sub._option.dataset||{}, sub._option.dataset.id = meta.id)
can.page.Modify(can, sub._output, {style: kit.Dict(html.MAX_WIDTH, meta.width)})
can.page.Append(can, can._action, [{view: [html.TABS, html.DIV, meta.name], onclick: function(event) {
can.onmotion.select(can, can._output, html.FIELDSET_PLUGIN, sub._target) 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._action, html.DIV_TABS, event.target)
can.onmotion.select(can, can._header_tabs, html.DIV_TABS, sub._header_tabs) }, onmouseenter: sub._legend.onmouseenter}])
can.user.mod.isPod && can.user.title(["后台", sub.ConfHelp(), can.user.info.titles].join(" "))
// 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.Conf(ice.AUTO) == cli.DELAY && sub._output.innerHTML == "" && sub.Update(event)
sub.onimport.size(sub, can.ConfHeight()-can.Conf(html.MARGIN_Y), can.ConfWidth()-can.Conf(html.MARGIN_X), can.onexport.isauto(can))
can.onengine.signal(can, "onindex", can.request(_init? {target: event.target, type: "click", isTrusted: true}: event, {index: sub.ConfIndex()})), _init = false
// can.onengine.signal(can, "onevent", can.request(_init? {target: event.target, type: "click", isTrusted: true}: event)), _init = false
}, oncontextmenu: sub._legend.onclick}]; sub._header_tabs = can.page.Append(can, can._header_tabs, tabs)._target, sub._tabs = can.page.Append(can, can._action, tabs)._target
}, },
_menu: function(can, msg) { if (can.user.isMobile) { return } if (!can.user.isTechOrRoot(can)) { return } _menu: function(can, msg) { if (can.user.mod.isPod||can.user.isMobile) { return }
var target = can.setHeaderMenu(can.base.Obj(can.Conf(chat.MENUS)||msg.Option(chat.MENUS), can.onaction._menus), function(event, button, list) { list && can.core.CallFunc([can.onaction, list[0]], [can, button]) }) can.setHeaderMenu(can.base.Obj(msg.Option(chat.MENUS), can.Conf(chat.MENUS)||can.onaction._menus), function(event, button, list) {
can.onmotion.hidden(can, can._header_tabs = can.page.Append(can, target, ["_tabs"])._target) can.core.CallFunc([can.onaction, list[0]], [can, button])
},
})
Volcanos(chat.ONACTION, {
_init: function(can, target) { can.db.list = can.misc.SearchHash(can)
can.db.list.length == 0 && can.misc.Search(can, chat.RIVER) && can.misc.Search(can, chat.STORM) && (can.db.list = [can.misc.Search(can, chat.RIVER), can.misc.Search(can, chat.STORM)])
can.Conf(html.MARGIN_X, 2*html.PLUGIN_PADDING+2*html.PLUGIN_MARGIN), can.Conf(html.MARGIN_Y, 2*html.PLUGIN_PADDING+2*html.PLUGIN_MARGIN+html.ACTION_HEIGHT)
can.core.List(["ontouchstart", "ontouchmove", "ontouchend"], function(item) {
can.onengine.listen(can, item, function(event, msg) { can.onaction[item](event, can), can.onengine.signal(can, chat.ONACTION_TOUCH, msg) }, target)
}) })
can._toast = can.page.Append(can, can._target, ["toast"])._target
},
onsize: function(can, msg, height, width) { can.Conf({height: can.base.Min(height, 240), width: width})
can.page.style(can, can._toast, html.MAX_HEIGHT, can.page.height()-can.getHeaderHeight()-can.getFooterHeight()-(html.PLUGIN_MARGIN+html.PLUGIN_PADDING+html.ACTION_HEIGHT))
},
onlogin: function(can, msg) {
can.Conf(html.MARGIN_Y, 2*html.PLUGIN_PADDING+2*html.PLUGIN_MARGIN+html.ACTION_HEIGHT)
can.Conf(html.MARGIN_X, 2*html.PLUGIN_PADDING+2*html.PLUGIN_MARGIN)
can.onimport._menu(can, msg), can.onkeymap._build(can)
can._root.River && can.onmotion.delay(can, function() { if (can.Mode()) { return }
var gt = can.page.unicode.next, lt = can.page.unicode.prev, river = can._root.River._target
var target = can.page.Append(can, can._target, [{view: [[html.TOGGLE, chat.PROJECT], "", can.page.isDisplay(river)? lt: gt], onclick: function(event) {
can.page.Modify(can, target, (can._river_show = can.onmotion.toggle(can, river))? lt: gt), can.onaction.layout(can)
can.misc.sessionStorage(can, "river:hide", can._river_show? "": ice.TRUE)
}}])._target; can._toggle = target
can.misc.sessionStorage(can, "river:hide") == ice.TRUE && target.click()
}); if (!can.Conf(chat.TOOL) && !can.user.mod.isCmd) { return }
if (can.base.beginWith(location.pathname, "/share/")) { can._names = location.pathname }
can.Conf(chat.TOOL)? can.onappend.layout(can, can.core.List(can.Conf(chat.TOOL), function(item, index, list) { item.type = chat.PLUGIN
if (list.length == 1) { can.user.mod.cmd = item.index
can.onaction._onaction_cmd(can), item.mode = chat.CMD, item.opts = can.misc.Search(can)
can.onappend.style(can, ice.CMD, document.body), can.onappend.style(can, item.index, document.body)
} return item
}), FLOW).layout(can.page.height(), can.page.width()): can.runAction(can.request(), ctx.COMMAND, [], function(msg) {
if (msg.Length() == 1) { can.onaction._onaction_cmd(can) } can.onimport._init(can, msg)
})
},
onstorm_select: function(can, msg, river, storm) { can.misc.SearchHash(can, river, storm)
if (can.onmotion.cache(can, function(save, load) { save({plugins: can._plugins, current: can._current}), can._plugins = []
return load(can.core.Keys(can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm)), function(bak) { can._plugins = bak.plugins, can._current = bak.current })
}, can._output, can._action, can._header_tabs)) {
if (msg.Option(web.REFRESH) != ice.TRUE) { return can._current && can._current._tabs.click(), can.onaction.layout(can) }
}
can.run(can.request({}, {_method: http.GET}), [river, storm], function(msg) {
if (msg.Length() == 0) { return can.user.isLocalFile? can.user.toastFailure(can, "miss data"): can.onengine.signal(can, chat.ONACTION_NOTOOL, can.request({}, {river: river, storm: storm})) }
return can.onimport._init(can, msg)
})
},
_onaction_cmd: function(can) { can.onengine.signal(can, chat.ONACTION_CMD), can.onlayout._init(can) },
onaction_cmd: function(can, msg) { can.user.mod.isCmd = true, can.page.ClassList.add(can, can._target, can.Mode(chat.CMD)), can.Conf(html.MARGIN_Y, 128), can.Conf(html.MARGIN_X, 0) },
onsearch: function(can, msg, arg) { var fields = msg.Option(ice.MSG_FIELDS).split(mdb.FS); if (arg[0] == mdb.PLUGIN) { can.onexport.plugin(can, msg, arg, fields) } if (arg[0] == ctx.COMMAND) { can.onexport.command(can, msg, arg, fields) } },
onresize: function(can) { can.onaction.layout(can) },
onkeydown: function(event, can, mode) {
if (can.isCmdMode() && !event.metaKey) { var sub = can._plugins[0].sub; sub && can.core.CallFunc([sub, "onaction.onkeydown"], {event: event, can: sub}); return }
// if (can._current && !event.metaKey) { var sub = can._current.sub; sub && can.core.CallFunc([sub, "onaction.onkeydown"], {event: event, can: sub}); return }
can.onkeymap.selectCtrlN(event, can, can._action, html.DIV_TABS) || can.onkeymap._parse(event, can, mode)
}, },
ontouchstart: function(event, can) { can.touch = can.touch || {}, can.touch.isStart = true, can.touch.startX = event.touches[0].clientX }, _share: function(can, share) { share && can.run({}, ["_share", share], function(msg) {
ontouchmove: function(event, can) { can.touch.isMove = true, can.touch.distanceX = event.touches[0].clientX - can.touch.startX }, can.user.title(msg.OptionOrSearch(chat.TITLE))
ontouchend: function(event, can) { can.setHeader(chat.TOPIC, msg.OptionOrSearch(chat.TOPIC))
if (can.touch.isMove && Math.abs(can.touch.distanceX) > 50) { // can.page.Select(can, document.body, html.FIELDSET_PANEL, function(item) {
if (can.touch.distanceX > 0) { can.onengine.signal(can, "onslideright") } else { can.onengine.signal(can, "onslideleft") } // item != can._target && can.onmotion.hidden(can, item)
} can.touch.isMove = false, can.touch.distanceX = 0, can.touch.isStart = false, can.touch.startX = 0 // })
},
store: function(can) { can.user.opens(can.misc.MergePodCmd(can, {cmd: web.STORE})) }, can.Conf(html.MARGIN_X, 0, html.MARGIN_Y, 2*html.ACTION_HEIGHT)
dream: function(can) { can.user.opens(can.misc.MergePodCmd(can, {cmd: web.DREAM})) }, // can.page.ClassList.add(can, can._target, ice.CMD)
portal: function(can) { can.user.opens(can.misc.MergePodCmd(can, {cmd: web.PORTAL})) }, can.onlayout._init(can)
desktop: function(can) { can.user.opens(can.misc.MergePodCmd(can, {cmd: web.DESKTOP})) },
layout: function(can, button, skip) { var before = can._layout||can.onlayout._storage(can); button = button||before||(can.user.isMobile? ALL: TABVIEW) can.Conf(chat.RIVER, "_share", chat.STORM, share)
var list = can.misc.SearchHash(can); list.length > 2 && (list[3] = button); can.isCmdMode() || can.misc.SearchHash(can, list[0], list[1], list[2], list[3]) can.onimport._init(can, msg)
can.page.ClassList.del(can, can._target, before), can._header_tabs && can.onmotion.hidden(can, can._header_tabs)
button = (can.onlayout._storage(can, can._layout = button))||can.misc.SearchOrConf(can, html.LAYOUT), can.page.ClassList.add(can, can._target, button)
can.onengine.signal(can, chat.ONLAYOUT, can.request({}, {layout: button, before: before}))
can._root.River && can._river_show === false && can.onmotion.hidden(can, can._root.River._target), skip || can.onlayout._init(can)
can.getActionSize(function(height, width) { var cb = can.onlayout[button]; can.base.isFunc(cb) && cb(can, height, width) || can.onlayout._plugin(can, button) })
},
// _menus: [[html.LAYOUT, ALL, TABS, TABVIEW, VERTICAL, HORIZON, GRID, FREE, FLOW, PAGE]],
_trans: kit.Dict(html.LAYOUT, "布局", ALL, "详情布局", TABS, "标签布局", TABVIEW, "标签分屏", VERTICAL, "上下分屏", HORIZON, "左右分屏", GRID, "网格布局", FREE, "自由布局", FLOW, "流动布局", PAGE, "网页布局"),
})
Volcanos(chat.ONLAYOUT, {
tabs: function(can, height, width) { can.ConfHeight(height+html.ACTION_HEIGHT), can.ConfWidth(width) },
tabview: function(can, height, width) { can.ConfHeight(height+html.ACTION_HEIGHT), can.ConfWidth(width), can.onmotion.toggle(can, can._header_tabs, true)
can.page.SelectOne(can, can._header_tabs, html.DIV_ITEM_SELECT)
// || can.page.Select(can, can._header_tabs, html.DIV_ITEM, function(target, index) { index == 0 && target.click() })
},
horizon: function(can, height, width) { can.ConfHeight(height), can.ConfWidth(width/2) },
vertical: function(can, height, width) { can.ConfHeight(height/2), can.ConfWidth(width) },
grid: function(can, height, width) { var m = can.user.isMobile? 1: 2, n = 2, h = height/n, w = width/m; can.ConfHeight(h+html.ACTION_HEIGHT), can.ConfWidth(w) },
free: function(can, height, width) { can.ConfHeight(height*3/4), can.ConfWidth(width*3/4), can.onmotion.toggle(can, can._header_tabs, true)
can.core.List(can._plugins, function(sub, index, array) { can.onmotion.move(can, sub._target, {left: (width/array.length/8*5+20)*index, top: (height/array.length/8*5)*index}) })
},
flow: function(can, height, width) { can.ConfHeight(height-html.ACTION_MARGIN), can.ConfWidth(width) },
page: function(can) { can.page.styleHeight(can, can._output, ""), can.page.style(can, document.body, kit.Dict(html.OVERFLOW, "")) },
_plugin: function(can, button) { can.core.List(can._plugins, function(sub) {
if (can.isCmdMode()) { return sub.onimport.size(sub, can.page.height(), can.page.width(), false) }
if (can.page.ClassList.has(can, sub._target, html.OUTPUT)) {
return sub.onimport.size(sub, can.ConfHeight()-(can.user.isMobile? 2*html.PLUGIN_PADDING: can.Conf(html.MARGIN_Y)-([ALL, TABS].indexOf(can.onexport.layout(can)) > -1? html.ACTION_HEIGHT: 0)), can.ConfWidth()-can.Conf(html.MARGIN_X), can.onexport.isauto(can))
}
sub.onimport.size(sub, can.ConfHeight()-can.Conf(html.MARGIN_Y)-(can._plugins.length == 1 || button && button != ALL || sub.isCmdMode()? 0: html.ACTION_MARGIN),
can.ConfWidth()-can.Conf(html.MARGIN_X), can._plugins.length > 1 && can.onexport.isauto(can)) && can.page.style(can, sub._output, html.HEIGHT, "", html.MAX_HEIGHT, "")
}) }, }) },
_storage: function(can, value) { return can.user.isMobile? "all": (can.misc.sessionStorage(can, can.core.Keys(CAN_LAYOUT, location.pathname), value)||[])[0] }, _cmd: function(can, item, next) {
}) can.base.Copy(item, {
Volcanos(chat.ONEXPORT, { height: can.Conf(html.HEIGHT)-can.Conf(html.MARGIN_Y),
size: function(can, msg) { width: can.Conf(html.WIDTH)-can.Conf(html.MARGIN_X),
msg.Option(html.LEFT, can._output.offsetLeft), msg.Option(html.TOP, can._output.offsetTop) opts: can.misc.Search(can),
msg.Option(html.HEIGHT, can._output.offsetHeight||window.innerHeight), msg.Option(html.WIDTH, can._output.offsetWidth||window.innerWidth) })
msg.Option(html.MARGIN_Y, can.Conf(html.MARGIN_Y)), msg.Option(html.MARGIN_X, can.Conf(html.MARGIN_X)) can.onappend.plugin(can, item, function(sub, meta, skip) {
can.user.title(meta.name), skip || next()
})
}, },
layout: function(can) { return can._layout||can.onlayout._storage(can)||can.misc.SearchOrConf(can, html.LAYOUT)||"" },
isauto: function(can) { return ["", ALL, FLOW, PAGE].indexOf(can.onexport.layout(can)) > -1 },
args: function(can, msg, cb) { can.core.Next(can._plugins, function(sub, next, index, list) {
cb(can.base.trim(can.page.SelectArgs(can, sub._option, "", function(item) { return item.value })), sub, next, index, list)
}) },
plugin: function(can, msg, arg, fields) { can.core.List(can._plugins, function(sub) { var meta = sub.Conf(); if (!can.base.contains(meta.index, arg[1])) { return }
var data = {ctx: ice.CAN, cmd: can._name, type: chat.PLUGIN, name: sub._index, text: shy(sub._legend.innerHTML, function(event) { sub._target.click() })}
if (meta.index) { data.context = "", data.command = meta.index } else if (meta.cmd) { data.context = meta.ctx, data.command = meta.cmd } else { return } msg.Push(data, fields)
}) },
command: function(can, msg, arg, fields) { var meta = can.onengine.plugin.meta; can.core.Item(arg[1] == ""? meta: meta[arg[1]]? kit.Dict(arg[1], meta[arg[1]]): {}, function(name, command) {
msg.Push(kit.Dict(ice.CTX, ice.CAN, ice.CMD, ctx.COMMAND, mdb.TYPE, ice.CAN, mdb.NAME, name||command.name, mdb.TEXT, command.help, ctx.CONTEXT, ice.CAN, ctx.COMMAND, name, ctx.INDEX, can.core.Keys(ice.CAN, name)), fields)
}) }
}) })
Volcanos(chat.ONENGINE, { Volcanos("onengine", {help: "解析引擎", list: [], _engine: function(event, page, msg, can, cmds, cb) {
_engine: function(event, sup, msg, can, cmds, cb) { var storm = can.core.Value(can._root, can.core.Keys(chat.RIVER, cmds[0], chat.STORM, cmds[1]))
var storm = can.core.Value(can._root, can.core.Keys(chat.RIVER, cmds[0], chat.STORM, cmds[1])); if (!storm || cmds.length != 2) { return false } if (!storm || cmds.length != 2) { return false }
if (storm.index) {
can.runAction(event, ctx.COMMAND, [].concat(can.core.List(storm.index, function(item) { if (storm.index) { // 命令索引
if (typeof item == code.FUNCTION) { item = item(can) } if (item) { return item.index||item } can.run(event, [ctx.ACTION, ctx.COMMAND].concat(storm.index), cb)
})), function(msg) { } else { // 命令列表
can.core.List(storm.index, function(item) { if (!item || typeof item == code.FUNCTION) { return } can.core.List(storm.list, function(value) {
msg.Push(ctx.ARGS, JSON.stringify(item.args||[])) msg.Push(mdb.NAME, value.name||"")
msg.Push(ctx.STYLE, item.style||"").Push(ctx.DISPLAY, item.display||"") msg.Push(mdb.HELP, value.help||"")
msg.Push(web.SPACE, item.space||"").Push("_ismain", ice.TRUE) msg.Push(ctx.INPUTS, JSON.stringify(value.inputs))
}), cb(msg) msg.Push(ctx.FEATURE, JSON.stringify(value.feature))
msg.Push(ctx.INDEX, value.index||"")
msg.Push(ctx.ARGS, value.args||"[]")
msg.Push(ice.MSG_ACTION, value._action||"")
}), can.base.isFunc(cb) && cb(msg)
}
return true
}})
Volcanos("onaction", {help: "交互操作", list: [], _init: function(can, cb, target) {
can.Conf(html.MARGIN_Y, 4*html.PLUGIN_MARGIN+2*html.ACTION_HEIGHT+html.ACTION_MARGIN)
can.Conf(html.MARGIN_X, 4*html.PLUGIN_MARGIN)
target.ontouchstart = function(event) {
can.onengine.signal(can, "onaction_touch", can.request(event))
}, can.base.isFunc(cb) && cb()
},
_menus: [
[chat.LAYOUT, "auto", "flow", "grid", "tabs", "free", "page", "toimage"],
[ice.HELP, "tutor", "manual", "service", "devops", "refer"],
],
_trans: {
"layout": "布局",
"auto": "默认布局",
"flow": "流动布局",
"grid": "网格布局",
"tabs": "标签布局",
"free": "自由布局",
"page": "网页布局",
"toimage": "生成图片",
"help": "帮助",
"tutor": "入门简介",
"manual": "使用手册",
"service": "服务手册",
"devops": "编程手册",
"refer": "参考手册",
},
onmain: function(can) {
can.onimport._share(can, can.misc.Search(can, web.SHARE))
},
onlogin: function(can) { if (!can.user.mod.isCmd) { return }
can.Conf(html.MARGIN_X, 0, html.MARGIN_Y, 2*html.ACTION_HEIGHT)
can.page.ClassList.add(can, can._target, ice.CMD)
can.onlayout._init(can)
can._names = location.pathname
can.Conf(chat.TOOL)? can.core.Next(can.Conf(chat.TOOL), function(item, next) {
can.onimport._cmd(can, item, next)
}): can.run(can.request()._event, [ctx.ACTION, ctx.COMMAND], function(msg) {
can.core.Next(msg.Table(), function(item, next) {
can.onimport._cmd(can, item, next)
}) })
} else { can.core.List(storm.list, function(item) { can.base.isString(item) && (item = {index: item}) })
msg.Push(ctx.INDEX, item.index||"").Push(mdb.ICONS, item.icons||"") },
msg.Push(mdb.NAME, item.name||"").Push(mdb.HELP, item.help||"") onstorm_select: function(can, msg, river, storm) { can.onlayout._init(can)
msg.Push(ctx.INPUTS, JSON.stringify(item.inputs)).Push(ctx.FEATURE, JSON.stringify(item.feature)) if (can.onmotion.cache(can, function() {
msg.Push(ctx.ARGS, item.args||"[]").Push(ctx.STYLE, item.style||"").Push(ctx.DISPLAY, item.display||"") var key = can.core.Keys(can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm))
msg.Push(web.SPACE, item.space||"").Push("_ismain", ice.TRUE) return key
}), can.base.isFunc(cb) && cb(msg) } return true }, can._action, can._output)) {
var conf = can.core.Value(can._root, can.core.Keys(chat.RIVER, river, chat.STORM, storm))||{}
can.onaction.layout(can, conf.layout||can.misc.SearchOrConf(can, chat.LAYOUT)||"auto", true)
return
}
can.run({}, [river, storm], function(msg) { if (msg.Length() > 0) { return can.onimport._init(can, msg) }
can.onengine.signal(can, "onaction_notool", can.request({}, {river: river, storm: storm}))
})
},
onsearch: function(can, msg, word) {
if (word[0] == mdb.FOREACH || word[0] == mdb.PLUGIN) { can.onexport.plugin(can, msg, word) }
},
onsize: function(can, msg, height, width) { can.Conf({height: height, width: width}) },
help: function(can, button) { can.user.open("/help/"+button+".shy") },
layout: function(can, button, slient) {
if (button == "toimage") {
can.onmotion.toimage(event, can, document.title, can._output)
return
}
can.page.ClassList.del(can, can._target, can.Conf(chat.LAYOUT))
can.page.ClassList.add(can, can._target, can.Conf(chat.LAYOUT, button))
if (button == "tabs") {
can.onmotion.select(can, can._output, html.FIELDSET_PLUGIN, 0)
can.onmotion.select(can, can._action, html.DIV_TABS, 0)
} else if (button == "free") {
can.page.Select(can, can._target, [[html.DIV_OUTPUT, html.FIELDSET_PLUGIN]], function(item, index) {
can.page.Modify(can, item, {style: {left: 40*index, top: 40*index}})
can.onmotion.move(can, item, {left: 40*index, top: 40*index})
})
} else if (button == "grid") {
can.user.input(event, can, [{name: "m", value: 2}, {name: "n", value: 2}], function(event, button, data, list, args) {
can.getActionSize(function(height, width) { var m = parseInt(data.m)||2, n = parseInt(data.n)||2
can.page.css(can.base.replaceAll(chat.ACTION_LAYOUT_FMT, "_width", (width-(4*m+1)*html.PLUGIN_MARGIN)/m+"px", "_height", (height-(4*n+1)*html.PLUGIN_MARGIN)/n+"px"))
})
}, true)
}
can.onlayout._init(can)
}, },
}) })
Volcanos(chat.ONKEYMAP, { Volcanos("onkeymap", {help: "键盘交互", list: [], _focus: [], _init: function(can, target) {
can.onkeymap._build(can), can.onengine.listen(can, "onkeydown", function(msg, model) {
can._keylist = can.onkeymap._parse(msg._event, can, model, can._keylist||[], can._output)
})
},
_mode: { _mode: {
plugin: { normal: {
Enter: function(event, can) { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: "*"})) }, j: function(event, can, target) { target.scrollBy(0, event.ctrlKey? 300: 30) },
Escape: function(event, can) { can.onmotion.clearFloat(can) || can._root.Search && can.onmotion.hidden(can, can._root.Search._target) }, k: function(event, can, target) { target.scrollBy(0, event.ctrlKey? -300: -30) },
b: function(event, can, target) { can.search(event, ["Header.onaction.black"]) },
w: function(event, can, target) { can.search(event, ["Header.onaction.white"]) },
g: function(event, can, target) { can.search(event, ["River.ondetail.创建群组"]) },
s: function(event, can, target) { can.search(event, ["River.ondetail.添加应用"]) },
t: function(event, can, target) { can.search(event, ["River.ondetail.添加工具"]) },
" ": function(event, can, target) {
can.onengine.signal(can, "onsearchfocus")
},
":": function(event, can, target) {
can.onengine.signal(can, "oncommandfocus")
},
enter: function(event, can, target) { can.misc.Log("enter") },
escape: function(event, can, target) {
can.page.Select(can, document.body, html.FIELDSET_AUTO, function(item) {
can.onmotion.hidden(can, item)
})
can.page.Select(can, document.body, can.page.Keys(html.FIELDSET_FLOAT, html.DIV_FLOAT), function(item) {
can.page.Remove(can, item)
})
},
}, },
}, _engine: {}, }, _engine: {},
toggleTheme: function(can, theme) { can.setHeader(chat.THEME, can.getHeaderTheme() == theme? ice.AUTO: theme) },
toggleLayout: function(can, layout) { can.onaction.layout(can, can.onexport.layout(can) == layout? ice.AUTO: layout) },
}) })
Volcanos(chat.ONPLUGIN, { Volcanos("onexport", {help: "导出数据", list: [],
_filter: shy("表格", [ice.LIST, html.FILTER]), args: function(can, cb, target) {
_plugin: shy("插件", [mdb.NAME, ice.LIST, ice.BACK]), can.core.Next(can.page.Select(can, target, [[html.FIELDSET_PLUGIN, html.FORM_OPTION]]), function(item, next, index, array) {
_action: shy("操作", [ice.LIST]), item.dataset.args = JSON.stringify(can.page.Select(can, item, html.OPTION_ARGS, function(item) { return item.value||"" }))
_display: shy("操作", [ice.LIST]), cb(item, next, index, array)
_output: shy("操作", [ice.LIST], function(can, sub) { can.onappend.style(sub, html.OUTPUT) }), })
_notfound: shy("缺失", [ctx.INDEX, web.SPACE, ice.LIST], function(can, msg, arg, sub) { msg.Echo("not found "+(arg[0]||sub.ConfIndex())+" "+(arg[1]||can.ConfSpace())) }), },
layout: shy("界面布局", {_init: function(can) { can.Option(chat.LAYOUT, can.getAction(chat.LAYOUT)) }}, ["layout:select=auto,tabs,tabview,horizon,vertical,grid,free,flow,page", ctx.RUN], function(can, msg, arg) { can.onaction.layout(can, arg[0]) }), size: function(can, msg) {
msg.Option(html.TOP, can._target.offsetTop)
msg.Option(html.LEFT, can._target.offsetLeft)
msg.Option(html.WIDTH, can._target.offsetWidth)
msg.Option(html.HEIGHT, can._target.offsetHeight-can._action.offsetHeight)
msg.Option(html.SCROLL, can.user.isMobile? can._target.parentNode.parentNode.scrollTop: can._output.scrollTop)
msg.Option(html.MARGIN_X, can.Conf(html.MARGIN_X))
msg.Option(html.MARGIN_Y, can.Conf(html.MARGIN_Y))
},
layout: function(can, msg) { return can.Conf(chat.LAYOUT) },
plugin: function(can, msg, word) { var fields = can.core.Split(msg.Option(ice.MSG_FIELDS))
can.page.Select(can, can._output, [[html.FIELDSET_PLUGIN, html.LEGEND]], function(item) {
if (item.innerHTML.indexOf(word[1]) == -1) { return }
var meta = item.parentNode._meta
var list = can.page.Select(can, item.nextSibling, html.OPTION_ARGS, function(item) { return item.value||"" })
var data = {ctx: "web.chat", cmd: ctx.ACTION,
type: mdb.PLUGIN, name: item.innerHTML, text: shy("跳转", function(event) {
var input = can.page.Select(can, item.parentNode, html.INPUT_ARGS)[0]
input && input.focus()
}), argument: JSON.stringify(list),
}
if (meta.index) {
data.context = "", data.command = meta.index
} else if (meta.cmd) {
data.context = meta.ctx, data.command = meta.cmd
} else {
return
}
msg.Push(data, fields)
})
},
}) })
})()

View File

@ -1,40 +1,36 @@
fieldset.Footer>div.output { font-style:italic; height:var(--footer-height); display:flex; } fieldset.Footer {
fieldset.Footer>div.output div.item { padding:7px; height:var(--footer-height); display:flex; align-items:center; } height:32px; padding:0 5px;
fieldset.Footer>div.output div.item.button { padding:7px 0; } clear:both;
fieldset.Footer>div.output div.title:first-child { margin-left:var(--header-height); white-space:pre; }
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); font-style:italic; border:0; }
fieldset.Footer>div.output div.toast { font-family:var(--status-font-family); line-height:18px; text-align:right; overflow:auto; flex-grow:1; justify-content:flex-end; }
fieldset.Footer>div.output div.state { font-family:var(--status-font-family); line-height:18px; white-space:pre; }
fieldset.Footer>div.output div.state label { font-size:var(--status-font-size); }
fieldset.Footer>div.output div.cmd { padding:0; margin-left:20px; }
fieldset.Footer>div.output div.cmd>input[name=cmd] { padding-left:30px; }
fieldset.Footer>div.output div.menu>div.River { display:flex; justify-content:space-around; }
fieldset.Footer>div.output div.menu>div.River>div.item { height:var(--footer-height); display:flex; flex-direction:column; text-align:center; flex-grow:1; }
fieldset.Footer>div.output div.menu>div.River>div.item>i { font-size:24px; margin-right:0; }
fieldset.Footer>div.output div.menu>div.River>div.item>span { font-size:var(--status-font-size); }
body.mobile fieldset.Footer>div.output>div.menu { width:100%; }
body.mobile fieldset.Footer>div.output>div:not(.menu) { display:none; }
.picker {
box-shadow:var(--notice-bg-color) 0px 0px 20px 5px !important;
background-color:var(--notice-bg-color) !important; color:white !important;
position:relative; left:-5px; top: -5px; transition:all 0.5s;
} }
.picker.danger { fieldset.Footer>div.output {
box-shadow:var(--danger-bg-color) 0px 0px 20px 5px !important; height:32px; overflow:hidden;
background-color:var(--danger-bg-color) !important; color:white !important; }
fieldset.Footer>div.output>div {
height:22px; padding:5px;
cursor:pointer;
}
fieldset.Footer>div.output>div:hover {
border-top:solid 2px red;
background-color:#2e515f;
}
fieldset.Footer>div.output div.title {
float:left;
}
fieldset.Footer>div.output div.state {
float:right;
}
fieldset.Footer>div.output div.toast {
float:right; background-color:darkcyan;
}
fieldset.Footer>div.output div.cmd {
float:left; padding:0px;
}
fieldset.Footer>div.output input[name=cmd] {
width:120px; height:25px;
border-radius:0;
}
fieldset.Footer>div.output input[name=cmd]:focus {
width:320px;
} }
div.view span.string { color:#f29766; }
div.view span.keyword { color:#5cadd4; }
div.item:not(.string):not(.number):not(.boolean)>span.value { color:var(--disable-fg-color); font-style:italic; }
span.item:not(.string):not(.number):not(.boolean)>span.value { color:var(--disable-fg-color); font-style:italic; }
fieldset.debug div.output table.content * { font-size:14px; }
fieldset.debug span.path { color:silver; font-style:italic; }
html.login body.width1 fieldset.Footer { display:none; }
html.login body.width1 fieldset.Header { display:none; }
body.dark fieldset.debug span.path { color:gray; }
body.dark fieldset.debug span.target { color:gray; }
body.dark div.item:not(.string):not(.number):not(.boolean)>span.value { color:gray; }
body.dark span.item:not(.string):not(.number):not(.boolean)>span.value { color:gray; }

View File

@ -1,208 +1,96 @@
(function() { var NTIP = "ntip", NLOG = "nlog", NCMD = "ncmd", NKEY = "nkey" Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
Volcanos(chat.ONIMPORT, { can.onmotion.clear(can)
_init: function(can, msg, target) { can._wss = can.ondaemon._init(can)
can.Conf(cli.BEGIN, can.base.Time(null, "%H:%M:%S"))
if (!can.user.isMobile && !can.misc.isDebug(can)) { can.onmotion.hidden(can); return }
can.Conf(nfs.VERSION, can.base.trimPrefix(window._version, "?_v=").split("&")[0])
can.ConfHeight(can.page.height()), can.ConfWidth(can.page.width())
can.Conf(NKEY, can.core.Item(can.misc.localStorage(can)).length)
can.onimport._title(can, msg, target) can.onimport._title(can, msg, target)
can.onimport._storm(can, msg, target) can.onimport._state(can, msg, target)
can.core.List([
// {index: chat.TUTOR},
// {index: chat.FLOWS, value: "流程"},
// {index: chat.MESSAGE},
{index: web.SPIDE, value: can.user.trans(can, "spide", "服务")},
{index: web.SPACE, value: can.user.trans(can, "space", "空间")},
{index: cli.RUNTIME},
{index: code.XTERM, args: [cli.SH]},
], function(value) { value.type = html.BUTTON, value.name = value.index
value.onclick = function() { can.onappend._float(can, value.index, value.args) }
can.onappend.input(can, value, "", can._output)
})
// can.onimport._command(can, msg, target)
can.onimport._toast(can, msg, target) can.onimport._toast(can, msg, target)
can.misc.isDebug(can) && can.onimport._state(can, msg, target) can.onimport._cli(can, msg, target)
can.base.isFunc(cb) && cb(msg)
}, },
_title: function(can, msg, target) { can.user.isMobile || can.core.List(can.Conf(chat.TITLE)||msg.result, function(item) { _title: function(can, msg, target) {
if (can.base.contains(item, ice.AT)) { item = '<a href="mailto:'+item+'">'+item+'</a>' } !can.user.isMobile && can.core.List(msg.result, function(item) {
can.page.Append(can, target, [{view: [[html.ITEM, chat.TITLE], "", item], title: "联系站长"}]) can.page.Append(can, target, [{view: [chat.TITLE, html.DIV, item], title: "联系站长"}])
}) },
_command: function(can, msg, target) { can.onappend.input(can, {type: html.TEXT, _className: "args trans", icon: icon.TERMINAL, name: ice.CMD, onkeydown: function(event) { can.onkeymap.input(event, can)
function close() { can.ui.cli && can.ui.cli.onaction.close() } if (event.key == code.ESCAPE) { return close() } if (event.key != code.ENTER) { return } close()
switch (event.target.value) {
case web.CLEAR:
case cli.CLOSE: break
default:
var list = can.core.Split(event.target.value, lex.SP)
can.onexport._float(can, "cli", {index: "can.console", display: "/plugin/local/code/xterm.js"}, list, function(sub) { can.getActionSize(function(left) { can.page.style(can, sub._target, html.LEFT, left+html.PLUGIN_MARGIN, html.RIGHT, "") }) })
}
}}, "", target, [chat.TITLE]) },
_storm: function(can, msg, target) { can.ui.storm = can.page.Append(can, can._output, [html.MENU])._target },
_state: function(can, msg, target) { can.user.isMobile || can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), can.onexport.list), function(item) {
can.page.Append(can, target, [{view: [[html.ITEM, chat.STATE]], list: [
{text: [item, html.LABEL]}, {text: [": ", html.LABEL]}, {text: [can.Conf(item)||"", "", item]},
], onclick: function(event) { can.core.CallFunc(can.onexport[item], [can]) }}]) })
},
_toast: function(can, msg, target) { can.ui.toast = can.page.Append(can, target, [{view: [[html.ITEM, chat.TOAST]], onclick: function(event) { can.onexport[NTIP](can) }}])._target },
_data: function(can, name, item) { can.db[name] = can.db[name]||can.request(), can.db[name].Push(item), can.onimport.count(can, name) },
tutor: function(event, can, type, text) { if (can.base.isIn(type, "keyup", "keydown")) { return }
!event._tutor && event.isTrusted && text && can.onimport._data(can, chat.TUTOR, {time: can.base.Time(), type: type, text: text}), event._tutor = true
},
value: function(can, name, value) { can.page.Select(can, can._output, "div.item>span."+name, function(target) { target.innerHTML = value }) },
count: function(can, name) { can.page.Select(can, can._output, can.core.Keys(html.SPAN, name), function(item) { item.innerHTML = can.Conf(name, parseInt(can.Conf(name)||"0")+1+"")+"" }) },
ntip: function(can, msg, time, title, content) { can.onimport._data(can, NTIP, {time: time, title: title, content: content}), can.page.Modify(can, can.ui.toast, [time, title, content].join(lex.SP)) },
ncmd: function(can, msg, _follow, _cmds) { can.onimport._data(can, NCMD, {time: can.base.Time(), follow: _follow, cmds: _cmds}), can.onimport.nlog(can, NLOG) },
nlog: function(can, name) { can.onimport.count(can, name) },
menu: function(can, cmds, cb, trans) { can.base.isString(cmds) && (cmds = [cmds])
return can.page.Append(can, can.ui.storm, [{view: cmds[0], list: can.core.List(can.base.getValid(cmds.slice(1), [cmds[0]]), function(item) {
return {view: [[html.ITEM, item.name]], list: [{icon: item.icon}, {text: item.name}], onclick: function(event) {
can.onmotion.select(can, event.currentTarget.parentNode, html.DIV_ITEM, event.currentTarget), cb(event, item.hash)
}}
}) }])._target
},
})
Volcanos(chat.ONACTION, {_init: function(can) {},
onsize: function(can) { can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth)
can.onimport.value(can, html.HEIGHT, can.page.height()), can.onimport.value(can, html.WIDTH, can.page.width())
},
onmain: function(can) {
can.run(can.request({}, {_method: http.GET}), [], function(msg) {
can.page.Appends(can, can._output, [{view: "item title", list: [{text: msg.Result()}]}])
}) })
}, },
onlogin: function(can, msg) { _state: function(can, msg, target) {
can.run(can.request({}, {_method: http.GET}), [], function(msg) { can.onmotion.clear(can), can.onimport._init(can, msg, can._output) }) can.core.List(can.base.Obj(msg.Option(chat.STATE)||can.Conf(chat.STATE), ["ncmd"]), function(item) {
}, can.page.Append(can, target, [{view: [can.base.join([chat.STATE, item]), html.DIV, can.Conf(item)], list: [
ontoast: function(can, msg) { can.core.CallFunc(can.onimport.ntip, {can: can, msg: msg}) }, {text: [item, html.LABEL]}, {text: [": ", html.LABEL]}, {text: [can.Conf(item)||"", html.SPAN, item]},
onremote: function(can, msg) { can.core.CallFunc(can.onimport.ncmd, {can: can, msg: msg}) }, ], onclick: function(event) {
onunload: function(can) { can._wss && can._wss.close() }, can.show = can.show? (can.page.Remove(can, can.show), null): can.onaction._cmd(can)
onrecord: function(can, msg) { var zone = can.misc.sessionStorage(can, "web.chat.script:zone"); zone && can.runAction(can.request(), nfs.SCRIPT, [zone].concat(msg.cmds[0])) }, can.page.Modify(can, can.show, {style: {left: "", top: "", right: 0, bottom: can.onexport.height(can)}})
onaction_cmd: function(can) { can.onappend.style(can, html.HIDE) }, }}])
onstorm_select: function(event, can, river, storm) { event.isTrusted != undefined && can.onimport._data(can, chat.TUTOR, {time: can.base.Time(), type: chat.STORM, text: [river, storm].join(",")}) },
ontheme: function(event, can, theme) { can.onimport.tutor(event, can, chat.THEME, theme) },
onevent: function(event, can, query) { var msg = can.request(event)
can.onimport.tutor(event, can, msg.Option("_type")||event.type, query||can.page.getquery(can, event.currentTarget||event.target))
},
onindex: function(event, can, index) { can.onimport.tutor(event, can, ctx.INDEX, index) },
onproject: function(event, can, query) { can.onimport.tutor(event, can, html.ITEM, query) },
onremove: function(event, can, query) { can.onimport.tutor(event, can, mdb.REMOVE, query) },
oncommand_focus: function(can) { can.page.Select(can, can._output, ["div.cmd", html.INPUT], function(target) { can.onmotion.focus(can, target) }) },
onlayout: function(can, layout, before) { if (can.user.isMobile) { return }
can.page.ClassList.del(can, can._target, before), can.page.ClassList.add(can, can._target, layout)
},
ondebugs: function(can, msg) { can.runAction(msg, msg.Option(ctx.ACTION), [msg.Option(ctx.INDEX)], function(_msg) { _msg.Table(function(item) {
can.onappend._float(can, item, can.base.Obj(item.args, []), function(sub) {
sub.run = function(event, cmds, cb) { can.run(can.request(event, {_method: http.POST, pod: sub.ConfSpace()}), [ctx.ACTION, msg.Option(ctx.ACTION), ctx.RUN].concat(cmds), cb) }
}) })
}) }) }, },
}) _toast: function(can, msg, target) {
Volcanos(chat.ONEXPORT, {list: [cli.BEGIN, nfs.VERSION], can.toast = can.page.Append(can, target, [{view: chat.TOAST, onclick: function(event) {
height: function(can) { can.onexport._float(can, html.HEIGHT, "can.view") }, can.show = can.show? (can.page.Remove(can, can.show), null): can.onappend.float(can, can._toast).first
width: function(can) { can.onexport._float(can, html.WIDTH, "can.data") }, can.page.Modify(can, can.show, {style: {left: "", top: "", right: 0, bottom: can.onexport.height(can)}})
ntip: function(can) { can.onexport._float(can, NTIP, "can.toast") }, }}]).first
nlog: function(can) { can.onexport._float(can, NLOG, "can.debug") }, },
ncmd: function(can) { can.onexport._float(can, NCMD, "can.debug", [chat.ONREMOTE]) }, _cli: function(can, msg, target) {
nkey: function(can) { can.onexport._float(can, NKEY, "can.localStorage") }, can.onappend.input(can, {type: html.TEXT, name: "cmd", onkeydown: function(event) {
begin: function(can) { can.onexport._float(can, NKEY, "can.data") }, can.onkeymap.input(event, can); if (event.key != lang.ENTER) { return }
version: function(can) { can.onexport._float(can, NKEY, "can.runtime") }, switch (event.target.value) {
_float: function(can, name, index, args, cb) { can.ui[name]? can.ui[name].onaction.close(): can.onappend._float(can, index, args||[], function(sub) { can.ui[name] = sub case cli.CLEAR: can.cli && can.cli.close(); break
can.base.isFunc(cb) && cb(sub), can.onmotion.delay(can, function() { sub.onaction.close = function() { can.page.Remove(can, sub._target), delete(can.ui[name]) } }) case cli.CLOSE: can.cli && can.cli.close(); break
}) }, default:
}) can.run(event, [ice.RUN].concat(can.core.Split(event.target.value, ice.SP)), function(msg) {
Volcanos(chat.ONPLUGIN, { can.cli && can.cli.close()
toast: shy("提示", {}, [html.FILTER, ice.LIST], function(can, msg, arg) { if (!can.db[NTIP]) { return } can.cli = can.onappend.float(can, msg, function(value, key, index, line, list) {
arg[0]? can.db[NTIP].Table(function(value) {
msg.append = [mdb.TIME, "title", "content"], (value.title == arg[0] || value.content.indexOf(arg[0]) > -1) && msg.Push(value) }), can.page.Modify(can, can.cli.first, {style: {bottom: can.onexport.height(can), top: ""}})
}): msg.Copy(can.db[NTIP]), msg.StatusTimeCount() })
}),
debug: shy("网页日志", {
"prune": shy("清空", function(can) { while(can.misc._list.pop()) {} can.onmotion.clear(can) }),
"w3schools": shy("教程", function(can) { can.user.open("https://www.w3schools.com/colors/colors_names.asp") }),
"mozilla": shy("文档", function(can) { can.user.open("https://developer.mozilla.org/en-US/") }),
"w3": shy("标准", function(can) { can.user.open("https://www.w3.org/TR/?tag=css") }),
}, ["type:select=log,info,warn,error,debug,onremote,wss", web.FILTER, ice.LIST, "prune", "w3schools", "mozilla", "w3"], function(can, msg, arg, cb) { var _can = can, can = msg._can
var stat = {}; var ui = can.page.Appends(can, can._output, [{view: [html.CONTENT, html.TABLE], list: [{type: html.TR, list: [
{text: [mdb.TEXT, html.TH]},
]}].concat(can.core.List(can.misc._list, function(list) { stat[list[2]] = ((stat[list[2]]||0)+1); return (!arg || !arg[0] || arg[0] == "log" || arg[0] == list[2]) && {type: html.TR, list: [
{type: html.TD, list: can.core.List(list, function(item, index) { var vimer
if (index == 1) { var _ls = new RegExp("(https*://[^/]+)*/*([^:]+):([0-9]+):([0-9]+)").exec(list[1])||[]; _ls[2] = (_ls[2]||"").split(ice.QS)[0]||""
return {view: [html.ITEM, html.SPAN], list: [{text: lex.SP+can.page.unicode.closes+lex.SP}, {text: [(_ls[1] == location.origin? "": _ls[1]||"")+_ls[2]+nfs.DF+_ls[3], "", nfs.PATH], onclick: function(event) {
if (can.onexport.record(can, list[1], web.LINK, {time: list[0], link: list[1], type: list[2], path: nfs.USR_VOLCANOS, file: _ls[2], line: _ls[3]})) { return }
if (vimer) { return can.page.Remove(can, vimer._target), vimer = null }
vimer = can.onappend.plugin(_can, {index: web.CODE_INNER, args: [nfs.USR_VOLCANOS, _ls[2], _ls[3]]}, function(sub) {}, event.target.parentNode)
}}]}
} if (!can.base.isObject(item)) { return item && {text: (index > 0? lex.SP: "")+item} }
return {view: [mdb.DATA, html.SPAN], _init: function(target) {
if (item.tagName) { var detail; var ui = can.page.Append(can, target, [{text: lex.SP},
{text: can.page.unicode.closes+lex.SP, _init: function(target) { can.onmotion.delay(can, function() { ui.toggle = target }) }},
{view: [[html.ITEM, nfs.TARGET], html.SPAN, can.page.tagClass(item)], onclick: function() {
if (detail) { return can.page.Remove(can, detail), detail = null, can.page.Modify(can, ui.toggle, can.page.unicode.closes+lex.SP) }
detail = can.page.AppendData(can, target, "", "", item)._target, detail.click(), can.page.Modify(can, ui.toggle, can.page.unicode.opens+lex.SP)
}},
]) } else { can.page.Append(can, target, [{text: lex.SP}]), can.page.AppendData(can, target, "", "", item) }
}}
})},
]} })) }]); arg && arg[1] && can.page.Select(can, can._output, html.TR, function(tr) { can.page.ClassList.set(can, tr, html.HIDE, tr.innerText.indexOf(arg[1]) == -1) })
can.onappend._status(can, [
{name: mdb.TIME, value: can.base.Time()}, {name: mdb.COUNT, value: can.page.Select(can, can._output, html.TR+html.NOT_HIDE).length+"x1"},
].concat(can.core.List([log.INFO, log.WARN, log.ERROR, chat.ONREMOTE, html.WSS], function(item) { return {name: item, value: stat[item]||"0"} })))
}),
view: shy("网页元素", [mdb.KEY], function(can, msg, arg, cb) { var can = msg._can
if (can.Conf("_target")) {
var ui = can.page.Append(can, can._output, [can.page.AppendView(can, can.Conf("_target"))])
can.onmotion.delay(can, function() { can.page.SelectOne(can, ui._target, html.DIV_ITEM, function(target) { target.click() }) })
} else if (arg[0]) {
can.page.Append(can, can._output, [can.page.AppendView(can, can.page.SelectOne(can, document.body, arg[0]))])
} else {
var ui = can.page.Append(can, can._output, [can.page.AppendView(can, document, "html", [
can.page.AppendView(can, document.head, html.HEAD), can.page.AppendView(can, document.body, html.BODY, null, false, function(target) {
var list = []; for (var p = target; p && p.tagName && p != document.body; p = p.parentNode) {
list.push(p.tagName.toLowerCase()+(p.className? nfs.PT+p.className.replaceAll(lex.SP, nfs.PT).replace(".picker", ""): ""))
} can.Option(mdb.KEY, list.reverse().join(ice.GT))
}),
], true)]); can.onmotion.delay(can, function() { can.page.Select(can, ui._target, "div.item.head,div.item.body", function(target) { target.click() }) })
}
}),
data: shy("网页数据", [mdb.KEY], function(can, msg, arg, cb) { var can = msg._can, root = can.Conf("_target")||can._root
arg[0]? can.page.AppendData(can, can._output, arg[0], arg[0].split(nfs.PT).pop(), can.core.Value(root, arg[0]), function(prefix, value) { can.Option(mdb.KEY, prefix) })._target.click():
can.page.AppendData(can, can._output, "", root._name, root, function(prefix, value) { can.Option(mdb.KEY, prefix) })._target.click()
can.onappend.style(can, "view")
}),
console: shy("网页终端", {
prompt: function(can, msg, arg, meta) { msg.detail = [], msg._can.onimport.grow(msg._can, msg, "only", ["\r", can.base.Time(null, "[%H:%M:%S]"), "can$ "].join("")) },
resize: function(can, msg, arg, meta) { msg.detail = [], meta.prompt(can, msg, arg, meta) },
input: function(can, msg, arg, meta) { can = msg._can, msg.detail = [], can._list = can._list||[]
var text = atob(arg[0]); function grow(text) { can.onimport.grow(can, msg, "only", text) }
if (text == "\r") { var cmd = can._list.join("")
if (!cmd) {
grow("\r\n"), can._list = []
} else { var res = window.eval(cmd)
grow("\r\n"+res+"\r\n"), can._list = []
}
meta.prompt(can, msg, arg, meta)
} else if (arg[0] == "fw==") {
grow("\u0008 \u0008"), can._list.pop()
} else if (arg[0] == "FQ==") {
grow("\u0008 \u0008".repeat(can._list.length)), can._list = []
} else {
grow(text), can._list = (can._list||[]).concat(text)
} }
}, }}, "", target, "title cmd")
}, [ice.CMD], function(can, msg, arg) { msg._can.Option(ice.CMD, "") },
msg.Display("/plugin/local/code/xterm.js")
}), toast: function(can, msg, title, content, fileline, time) { can._toast = can._toast||can.request()
runtime: shy("网页环境", [mdb.KEY], function(can, msg, arg) { can.page.Modify(can, can.toast, [time.split(ice.SP).pop(), title, content].join(ice.SP))
msg.Echo(JSON.stringify({href: location.href, version: window._version, can._toast.Push({time: time, fileline: fileline, title: title, content: content})
height: can.page.height(), width: can.page.width(), },
userAgent: navigator.userAgent, ncmd: function(can, msg, _follow, _cmds) { var NCMD = "ncmd"; can._cmds = can._cmds||can.request()
history: history.length, can._cmds.Push({time: can.base.Time(), follow: _follow, cmds: _cmds})
boot: can.db._boot, can.page.Select(can, can._output, can.core.Keys(html.SPAN, NCMD), function(item) {
daemon: can.misc.sessionStorage(can, "can.daemon"), item.innerHTML = can.Conf(NCMD, parseInt(can.Conf(NCMD)||"0")+1+"")+""
})).Display("/plugin/story/json.js") })
}), },
}) })
})() Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, cb, target) {
can.base.isFunc(cb) && cb()
},
onlogin: function(can, msg) { can.run({}, [], function(msg) { can.onimport._init(can, msg, [], null, can._output) }) },
ontoast: function(can, msg) { can.core.CallFunc(can.onimport.toast, {can: can, msg: msg}) },
onremote: function(can, msg) { can.core.CallFunc(can.onimport.ncmd, {can: can, msg: msg}) },
oncommandfocus: function(can) {
can.page.Select(can, can._output, "div.cmd input", function(target) { target.focus() })
},
_cmd: function(can) {
return can.onappend.float(can, can._cmds, function(value, key, index, line, list) {
var cmds = can.base.Obj(line.cmds); switch (line.follow) {
case "chat.Action": cmds = cmds.slice(2); break
case "chat.Footer": cmds = cmds.slice(2); break
}
switch (cmds[0]) {
case "web.wiki.word": cmds = cmds.slice(5); break
}
can.get("Action", "size", function(msg, top, left, width, height) {
can.onappend.plugin(can, {index: cmds[0], args: cmds.slice(1), height: height-100, width: width}, function(sub) {
sub.run = function(event, cmd, cb) {
can.run(event, can.misc.concat(can, [ctx.ACTION, ice.RUN, cmds[0]], cmd), cb)
}
can.page.Modify(can, sub._target, {style: {top: top+100, left: left}})
can.page.Modify(can, sub._legend, {style: {display: html.BLOCK}})
can.page.Modify(can, sub._output, {style: {"max-width": width}})
can.page.ClassList.add(can, sub._target, chat.FLOAT)
}, document.body)
})
}).first
},
})
Volcanos("onexport", {help: "导出数据", list: [],
height: function(can) { return can._target.offsetHeight },
})

View File

@ -1,50 +1,46 @@
fieldset.Header>div.output { line-height:21px; height:var(--header-height); overflow:hidden; } fieldset.Header {
fieldset.Header>div.output div.item { background-color:var(--panel-output-bg-color); padding:13.5px; height:var(--header-height); float:left; display:flex; align-items:center; } font-size:1.2em;
fieldset.Header>div.output div.item.title:first-child { font-size:var(--legend-font-size); font-style:italic; font-weight:bold; white-space:pre; overflow:hidden; } }
fieldset.Header>div.output div.item.title img { padding:0; height:var(--action-height); width:var(--action-height); margin-right:var(--input-margin); } fieldset.Header {
fieldset.Header>div.output div.item.state { padding:13.5px 10px; float:right; } height:32px; padding:0 5px;
fieldset.Header>div.output div.item.layout>i { margin-left:var(--input-padding); } overflow:hidden;
fieldset.Header>div.output div.item.layout:not(:hover)>i { visibility:hidden; } z-index:10;
fieldset.Header>div.output div.item.layout { padding-right:0; } }
fieldset.Header>div.output div.item.theme { white-space:pre; user-select:none; } fieldset.Header>div.output {
fieldset.Header>div.output div.item.theme>i { margin-right:0; } height:32px; overflow:hidden;
fieldset.Header>div.output div.item.theme>i:last-child { color:var(--disable-fg-color); } }
fieldset.Header>div.output div.item.theme>i.bi-moon-stars:last-child { font-size:12px; } fieldset.Header>div.output>div {
fieldset.Header>div.output div.item.language { white-space:pre; user-select:none; } height:22px; padding:5px;
fieldset.Header>div.output div.item.language>span:last-child { color:var(--disable-fg-color); } cursor:pointer;
fieldset.Header>div.output div.item.usernick>i { margin-left:var(--input-padding); } }
fieldset.Header>div.output div.item.usernick:not(:hover)>i { visibility:hidden; } fieldset.Header>div.output>div:hover {
fieldset.Header>div.output div.item.usernick { padding-right:0; } border-bottom:solid 2px red;
fieldset.Header>div.output div.item.avatar { padding:0; } background-color:#2e515f;
fieldset.Header>div.output div.item.avatar>img { height:var(--header-height); clip-path:circle(40%); } }
fieldset.Header>div.output div.item.search { padding:13.5px 5px; }
fieldset.Header>div.output div.item.search { padding:7px 5px; } fieldset.Header>div.output>div.title {
fieldset.Header>div.output div.item.search>i { color:unset; padding:7px; left:3px; } float:left;
fieldset.Header>div.output div.item.search>input { padding-left:25px; } }
fieldset.Header>div.output div.item.search>span.icon { padding:var(--input-padding) var(--button-padding); } fieldset.Header>div.output>div.state {
fieldset.Header>div.output div.Action>div._tabs { white-space:pre; padding-left:100px; height:100%; overflow:auto; display:flex; flex-wrap:wrap; } float:right;
fieldset.Header>div.output div.Action>div._tabs div.tabs { font-style:italic; padding:13.5px 20px; display:flex; align-items:center; } }
fieldset.Header>div.output div.Action>div._tabs div.tabs:only-child { display:none; } fieldset.Header>div.output>div.state.avatar>img {
body.mobile fieldset.Header>div.output div.item.usernick { display:none; } height:1.4em;
body.mobile fieldset.Header>div.output div.item.search>i { padding:0 10px; } }
body.mobile fieldset.Header>div.output div.item.search>input { width:256px; } fieldset.Header>div.output>div.search {
body.mobile fieldset.Header>div.output div.item.search>input:not(:focus) { border-color:var(--disable-fg-color); } float:left; margin-left:20px;
body:not(.mobile) fieldset.Header>div.output div.title:first-child { width:var(--river-width); } }
body:not(.mobile) fieldset.Header>div.output div.title img { margin-right:var(--button-margin); } fieldset.Header>div.output>div.search>input {
body:not(.mobile) fieldset.Header:not(.all):not(.tabs)>div.output div.title:first-child { padding-left:var(--button-padding); width:unset; } height:25px; margin-top:-5px;
body:not(.width6)>fieldset.Header:not(.all):not(.tabs)>div.output div.item.menu.search { padding-left:0 !important; margin-left:0; } border-radius:0;
body:not(.width6) fieldset.Header.tabview>div.output>div.Action>div.item.store { display:none; } }
body:not(.width6) fieldset.Header.tabview>div.output>div.Action>div.item.dream { display:none; }
body:not(.width6) fieldset.Header.tabview>div.output>div.Action>div.item.desktop { display:none; } fieldset.Header>div.output div.menu {
body:not(.width6) fieldset.Header>div.output>div.Action>div.item.portal { display:none; } height:21px; padding:5px;
body:not(.width6) fieldset.Header>div.output>div.item.language { display:none; } cursor:pointer;
body.width3>fieldset.Header>div.output>div.item.time { display:none; } float:left;
body.width3>fieldset.Header>div.output>div.item.avatar { margin-right:var(--plugin-margin); } }
body.width2>fieldset.Header>div.output div.Action>div.tabs { padding-left:50px; } fieldset.Header>div.output div.menu:hover {
body.width2>fieldset.Header>div.output>div.item.avatar { margin-right:var(--plugin-margin); } border-bottom:solid 2px red;
body.width2>fieldset.Header>div.output>div.item.theme { display:none; } background-color:#2e515f;
body.width2>fieldset.Header>div.output>div.item.time { display:none; } }
body.width2>fieldset.Header:not(.all):not(.tabs)>div.output div.item.title:first-child img { margin-right:0; }
// body.width2>fieldset.Header:not(.all):not(.tabs)>div.output div.item.title:first-child span { display:none; }
body.width2>fieldset.Footer:not(.all):not(.tabs)>div.output div.item.cmd { display:none; }
body.width2>fieldset.Footer:not(.all):not(.tabs)>div.output div.item.title { display:none; }

View File

@ -1,245 +1,235 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, cb, target) {
_init: function(can, msg, target) { can.Conf(aaa.USERNICK, msg.Option(aaa.USERNICK)||msg.Option(ice.MSG_USERNAME)||can.Conf(aaa.USERNICK))
can.onimport._title(can, msg, target), can.onimport._state(can, msg, target), can.onimport._search(can, msg, target)
can.onimport._avatar(can, msg, target), can.onimport._background(can, msg, target) 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._avatar(can, msg, target)
can.onimport._menus(can, msg, target)
can.base.isFunc(cb) && cb(msg)
},
_agent: function(can, msg, target) {
if (can.user.mod.isPod) {
can.onaction.River(can)
can.onaction.Footer(can)
} else if (can.user.isMobile) {
can.onaction.River(can)
can.onaction.Footer(can)
} else if (can.user.isExtension) {
can.onaction.River(can)
}
can.run({}, [chat.AGENT], function(msg) { if (!msg.Option(ssh.SCRIPT)) { return }
can.require(can.base.Obj(msg.Option(ssh.SCRIPT)), function(can) { can.onaction.source(can, msg) })
})
},
_grant: function(can, msg, target) {
if (can.misc.Search(can, chat.GRANT)) {
if (can.user.confirm(chat.GRANT+ice.SP+can.misc.Search(can, chat.GRANT))) {
can.run(event, [ctx.ACTION, chat.GRANT, web.SPACE, can.misc.Search(can, chat.GRANT)])
}
can.misc.Search(can, chat.GRANT, "")
}
}, },
_title: function(can, msg, target) { _title: function(can, msg, target) {
can.core.List(can.base.getValid(can.Conf(chat.TITLE)||msg.result, [ can.user.title(can.misc.Search(can, chat.TITLE)||can.misc.Search(can, ice.POD))
// can.user.title()|| !can.user.isMobile && can.core.List(can.base.getValid(msg.result, can.Conf(chat.TITLE)||["shylinux.com/x/contexts"]), function(item) {
decodeURIComponent((window == top? can.user.info.titles: "")||can.misc.Search(can, ice.POD)||location.host) can.page.Append(can, target, [{view: [chat.TITLE, html.DIV, item], title: "返回主页", onclick: function(event) {
]), function(item) { can.onaction.title(event, can)
can.page.Append(can, target, [{view: [[html.ITEM, chat.TITLE, html.FLEX]], list: [{img: can.misc.ResourceFavicon(can)}, {text: item}], title: "返回主页", onclick: function(event) { can.onaction.title(event, can) }}]) }, onmouseenter: function(event) { var list = msg.Table()
can.user.carte(event, can, {}, can.core.List(list, function(item) { return item.name }), function(event, item, meta, index) {
event.shiftKey? can.user.open(list[index].path): can.user.jumps(list[index].path)
})
}}])
}) })
}, },
_state: function(can, msg, target) { can.core.List(can.base.Obj(can.Conf(chat.STATE)||msg.Option(chat.STATE), [cli.QRCODE, chat.THEME, aaa.LANGUAGE, aaa.USERNICK, aaa.AVATAR, mdb.TIME]).reverse(), function(item) { _state: function(can, msg, target) {
if (can.user.isMobile && can.base.isIn(item, cli.QRCODE, chat.THEME, aaa.LANGUAGE, mdb.TIME)) { return } can.core.List(can.base.Obj(msg.Option(chat.STATE)||can.Conf(chat.STATE), [mdb.TIME, aaa.USERNICK]), function(item) {
can.page.Append(can, target, [{view: [[html.ITEM, chat.STATE, item], "", can.Conf(item)||msg.Option(item)||""], onclick: function(event) { if (item == aaa.AVATAR ) { if (can.user.isLocalFile) { return }
can.core.CallFunc([can.onaction, item], [event, can, item]) can.page.Append(can, target, [{view: can.base.join([chat.STATE, item]), list: [{img: ice.SP}], onmouseenter: function(event) {
}, _init: function(target) { item == mdb.TIME && can.onimport._time(can, target) can.onaction.carte(event, can, [can.page.Format(html.IMG, "/share/local/avatar", 160)])
item == aaa.AVATAR && can.page.Appends(can, target, [{img: lex.SP}]) }}]); return
item == aaa.USERNICK && !can.user.isMobile && can.page.Appends(can, target, [{text: can.Conf(aaa.USERNICK)}, {icon: icon.CHEVRON_DOWN}]) }
item == aaa.LANGUAGE && can.page.Appends(can, target, [{text: "EN"}, {text: " / "}, {text: "中"}])
item == chat.THEME && can.page.Appends(can, target, [{icon: icon.SUN}, {text: " / "}, {icon: icon.MOON}]) can.page.Append(can, target, [{view: [can.base.join([chat.STATE, item]), html.DIV, (can.Conf(item)||"").slice(0, 10)], onmouseenter: function(event) {
item == cli.QRCODE && can.page.Appends(can, target, [{icon: icon.qrcode, title: can.user.trans(can, cli.QRCODE)}]) can.core.CallFunc([can.onaction, item], [event, can, item])
}}]) }, _init: function(target) { item == mdb.TIME && can.onimport._time(can, target) }}])
}) },
_search: function(can, msg, target) { if (!can.user.isTechOrRoot(can)) { return }
can.page.Append(can, target, [{view: [[html.ITEM, chat.STATE]], list: [{icon: mdb.SEARCH}], onclick: function(event) {
can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH}))
}}])
return
can._search = can.onappend.input(can, {type: html.TEXT, _className: "args trans", icon: icon.SEARCH, name: mdb.SEARCH, value: can.misc.Search(can, "_search"), onkeydown: function(event) { can.onkeymap.input(event, can)
event.key == code.ENTER && can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH, word: event.target.value||""}))
}}, "", target, [chat.STATE])
can.onimport.menu(can, mdb.SEARCH, function() { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH, word: can._search.value||""})) })
},
_avatar: function(can, msg) { can.user.isExtension || can.user.isLocalFile || can.page.Modify(can, "div.state.avatar>img", {src: can.onexport.avatar(can)}) },
_background: function(can, msg) { if (can.user.isExtension || can.user.isLocalFile) { return } can.onlayout.background(can, can.onexport.background(can)) },
_language: function(can) { can.page.Select(can, can._output, "div.item.language", function(target) {
can.page.Appends(can, target, can.user.info.language.indexOf("zh") == 0? [{text: "中"}, {text: " / "}, {text: "EN"}]: [{text: "EN"}, {text: " / "}, {text: "中"}])
}) },
_theme: function(can, theme) { return can.ui.diy&&can.ui.diy[theme]||theme },
_const: function(can) { can.core.Item(html.value, function(key, value) { html[key] = can.page.styleValueInt(can, "--"+can.base.replaceAll(key.toLowerCase(), "_", "-"))||value }) },
_time: function(can, target) { can.core.Timer({interval: 100}, function() { can.onimport.time(can, target) }), can.onappend.figure(can, {action: "date"}, target) },
time: function(can, target) { can.onimport.theme(can), target.innerHTML = can.user.time(can, null, can.Conf(mdb.TIME)||"%H:%M:%S %w") },
avatar: function(event, can, avatar) { can.user.isExtension || can.user.isLocalFile || can.runAction(event, aaa.AVATAR, [avatar], function(msg) {
can.user.info.avatar = avatar, can.onimport._avatar(can, msg), can.user.toastSuccess(can)
}) },
background: function(event, can, background) { can.user.isExtension || can.user.isLocalFile || can.runAction(event, aaa.BACKGROUND, [background], function(msg) {
can.user.info.background = background, can.onimport._background(can, msg), can.user.toastSuccess(can)
}) },
language: function(can, language) { can.user.toastConfirm(can, can.user.trans(can, "change language to "+language), aaa.LANGUAGE, function() {
can.runAction(event, aaa.LANGUAGE, [language == ice.AUTO? "": language], function(msg) { can.user.reload(true) })
}) },
theme: function(can, theme, event) { theme && theme != ice.AUTO && can.runAction({}, chat.THEME, [theme])
if (theme) { can.onengine.signal(can, "ontheme", can.request(event, {theme: theme})) }
theme && can.require(["/chat/theme/"+theme+".css"])
theme && can.misc.localStorage(can, "can.theme", can._theme = theme == ice.AUTO? "": theme) && can.onengine.signal(can, chat.ONTHEMECHANGE, can.request(event, {theme: theme}))
theme = can.onexport.theme(can); var list = [html.LIGHT, html.WHITE]
var change = can.page.ClassList.has(can, document.body, theme); can.user.theme(can, theme), change || can.onimport._const(can)
can.page.Select(can, can._output, "div.item.theme>i:first-child", function(target) {
if (list.indexOf(theme) == -1 && list.indexOf(theme[0]) == -1) { target.className = icon.MOON } else { target.className = icon.SUN }
})
can.page.Select(can, can._output, "div.item.theme>i:last-child", function(target) {
if (list.indexOf(theme) == -1 && list.indexOf(theme[0]) == -1) { target.className = icon.SUN } else { target.className = icon.MOON }
}) })
}, },
menu: function(can, cmds, cb, trans) { can.base.isString(cmds) && (cmds = [cmds]) _search: function(can, msg, target) {
return can.page.Append(can, can._output, [{view: cmds[0], list: can.core.List(can.base.getValid(cmds.slice(1), [cmds[0]]), function(item) { var ui = can.onappend.input(can, {type: html.TEXT, name: mdb.SEARCH, onkeydown: function(event) {
return can.base.isString(item)? /* 1.string */ {view: [[html.ITEM, html.MENU, item], "", can.user.trans(can, item, trans)], onclick: function(event) { can.base.isFunc(cb) && cb(event, item, [item]) }}: can.onkeymap.input(event, can); switch (event.key) {
can.base.isArray(item)? /* 2.array */ {view: [[html.ITEM, html.MENU, item[0]]], list: [{text: can.user.trans(can, item[0], trans)}, {icon: icon.CHEVRON_DOWN}], onclick: function(event) { can.onkeymap.prevent(event) case lang.ENTER: can.onengine.signal(can, "onopensearch", can.request(event, {type: "*", word: event.target.value}))
can.onaction.carte(can.request(event, {_style: "header "+item[0]}), can, item.slice(1), function(event, button, meta) { can.base.isFunc(cb) && cb(event, button, item) }, trans) }
}}: /* 3.others */ item }}, "", target, "title search").parentNode
}) }])._target can.user.isMobile && can.page.Modify(can, ui, {style: {float: html.RIGHT}})
},
_background: function(can, msg) { if (can.user.isExtension || can.user.isLocalFile) { return }
msg.Option(aaa.BACKGROUND) && can.onlayout.background(can, "/share/local/background", document.body)
},
_avatar: function(can, msg) { if (can.user.isExtension || can.user.isLocalFile) { return }
// can.page.Modify(can, "div.state.avatar>img", {src: "/share/local/avatar/"})
msg.Option(aaa.AVATAR) && can.page.Modify(can, "div.state.avatar>img", {src: "/share/local/avatar"})
},
_menus: function(can, msg, target) {
can.setHeaderMenu(can.user.mod.isPod||can.user.isMobile||can.user.isExtension? [chat.RIVER]:
can.base.Obj(msg.Option(chat.MENUS)||can.Conf(chat.MENUS), can.onaction._menus), function(event, button) {
can.core.CallFunc(can.onaction[button]||function(event, can) {
can.run(event, [button], function(msg) { can.user.toast(can, "执行成功", can.user.trans(can, button)) })
}, {event: event, can: can, button: button})
})
},
_time: function(can, target) {
can.core.Timer({interval: 500}, function() { can.onimport.time(can, target) })
can.onappend.figure(can, {action: "date", style: {"min-width": 306}}, target, function(sub) {
can.get("Action", "size", function(msg, top) {
can.page.Modify(can, sub._target, {style: {top: top, right: 0, left: null}})
})
}), target.onmouseenter = target.click
},
time: function(can, target) { can.onlayout.topic(can)
target.innerHTML = can.user.time(can, null, "%w %H:%M:%S")
},
topic: function(can, topic) { can.onlayout.topic(can, can._topic = topic) },
background: function(event, can, url) { if (can.user.isExtension || can.user.isLocalFile) { return }
can.run(event, [ctx.ACTION, aaa.BACKGROUND, url], function(msg) { can.onimport._background(can, msg) })
},
avatar: function(event, can, url) { if (can.user.isExtension || can.user.isLocalFile) { return }
can.run(event, [ctx.ACTION, aaa.AVATAR, url], function(msg) { can.onimport._avatar(can, msg) })
},
menu: function(can, cmds, cb, trans) {
return can.page.Append(can, can._output, [{type: cmds[0], list: can.core.List(cmds.slice(1), function(item) {
if (can.base.isString(item)) {
return {view: [html.MENU, html.DIV, can.user.trans(can, item, trans)], onclick: function(event) {
can.base.isFunc(cb) && cb(event, item, cmds)
}}
} else if (can.base.isArray(item)) {
var list = can.core.List(item, function(value, index) { return can.user.trans(can, value, trans) })
return {view: [html.MENU, html.DIV, can.user.trans(can, list[0], trans)], onmouseenter: function(event) {
can.onaction.carte(event, can, list.slice(1), function(event, button, meta, index) {
can.base.isFunc(cb) && cb(event, item[index+1], item)
}, trans)
}}
} else if (can.base.isObject(item)) {
return item
}
}) }]).first
}, },
}) })
Volcanos(chat.ONACTION, {_init: function(can) {}, Volcanos("onaction", {help: "交互数据", list: [], _init: function(can, cb, target) {
onsize: function(can) { can.base.isFunc(cb) && cb()
can.ConfHeight(can._target.offsetHeight), can.ConfWidth(can._target.offsetWidth), can.onimport.theme(can)
}, },
onmain: function(can) { _menus: [["setting", chat.BLACK, chat.WHITE, chat.PRINT, "webpack", "devpack", "toimage"]],
if (window.parent == window && can.misc.Search(can, ice.MSG_SESSID) && can.misc.CookieSessid(can, can.misc.Search(can, ice.MSG_SESSID)) && !can.user.isMailMaster) { _trans: {
"river": "菜单",
"search": "搜索",
"create": "创建",
"share": "共享",
"setting": "设置",
"black": "黑色主题",
"white": "白色主题",
"print": "打印主题",
"toimage": "生成图片",
"shareuser": "共享用户",
"setnick": "设置昵称",
"language": "语言地区",
"chinese": "中文",
"clear": "清除背景",
},
onmain: function(can, msg) {
function init() { can.run({}, [], function(msg) {
can.base.Copy(can.onaction._trans, can.base.Obj(msg.Option(chat.TRANS), {}))
can.onimport._init(can, msg, function(msg) { can.onengine.signal(can, chat.ONLOGIN, msg) }, can._output)
can.search({}, ["River.onmotion.toggle"])
}) }; can.search({}, ["River.onmotion.hidden"])
if (can.misc.Search(can, ice.MSG_SESSID)) {
can.misc.CookieSessid(can, can.misc.Search(can, ice.MSG_SESSID))
return can.misc.Search(can, ice.MSG_SESSID, "") return can.misc.Search(can, ice.MSG_SESSID, "")
} can.user.info.sessid = can.misc.Search(can, ice.MSG_SESSID)
function lang(msg, cb) { can.user.info.language = msg.SearchOrOption(aaa.LANGUAGE)||msg.Option(ice.MSG_LANGUAGE)
can.user.info.language? can.require([can.misc.Resource(can, nfs.SRC_TEMPLATE+web.CHAT_HEADER+"/language/"+can.user.info.language+".js")], cb, function(can, name, sub) { can.base.Copy(can.user._trans, sub._trans) }): cb && cb()
can.onmotion.delay(can, function() { can.onimport._language(can) })
} }
function show(msg) { var p = can.misc.Search(can, "redirect_uri")
if (p && location.pathname == web.BASIC_LOGIN) { return location.replace(can.base.MergeURL(p, ice.MSG_SESSID, can.misc.CookieSessid(can))) } // 登录检查
var p = can.misc.Search(can, ice.BACK); if (p && location.pathname == web.CHAT_SSO) { return location.reload() } can.user.isLocalFile? init(): can.run({}, [chat.CHECK], function(msg) {
can.user.info.nodetype = msg.Option(ice.MSG_NODETYPE) can.Conf(aaa.USERNICK, msg.Option(ice.MSG_USERNICK)||msg.Option(ice.MSG_USERNAME))? init():
can.user.info.nodename = msg.Option(ice.MSG_NODENAME) msg.Option(chat.SSO)? can.user.jumps(msg.Option(chat.SSO)):
can.user.info.userrole = msg.Option(ice.MSG_USERROLE) can.user.login(can, init, msg.Option(aaa.LOGIN))
can.user.info.username = msg.Option(ice.MSG_USERNAME) })
can.user.info.usernick = can.Conf(aaa.USERNICK) },
can.user.info.repos = msg.Option(nfs.REPOS) onstorm_select: function(can, msg, river, storm) { can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm) },
can.user.info.email = msg.Option(aaa.EMAIL) onsearchfocus: function(can) {
can.user.info.avatar = msg.Option(aaa.AVATAR) can.page.Select(can, can._output, "div.search input", function(target) { target.focus() })
can.user.info.background = msg.Option(aaa.BACKGROUND) },
can.user.info.favicon = msg.Option("favicon")
can.user.info.titles = msg.Option("titles")||document.title title: function(event, can) {
lang(msg, function() { can.onmotion.clear(can), can.onimport._init(can, can.request(), can._output), can.onengine.signal(can, chat.ONLOGIN) }) var args = {}; can.core.List([chat.TITLE, chat.TOPIC, chat.LAYOUT], function(key) {
} var value = can.misc.Search(can, key); value && (args[key] = value)
can.run(can.request({}, {_method: http.GET}), [], function(msg) { lang(msg) })
if (msg.Option(ice.MSG_PROCESS) == "_open") { can.user.jumps(can.misc.MergeURL(can, args, true))
// return can.user.jumps(msg.Option("_arg")) },
} river: function(event, can) { can.onaction.River(can) },
can.ui.diy = can.base.Obj(msg.Option("diy"))||{}, can.__theme = can.onimport._theme(can, can.page.theme(function(theme) {
can.onengine.signal(can, chat.ONTHEMECHANGE, can.request(event, {theme: can.__theme = can.onimport._theme(can, theme)})), can.onimport.theme(can) black: function(event, can, button) { can.onlayout.topic(can, button), can.onlayout._init(can) },
})), can.onimport.theme(can, can.misc.Search(can, "theme")||"") white: function(event, can, button) { can.onlayout.topic(can, button), can.onlayout._init(can) },
can.onaction._menus[3] = [aaa.LANGUAGE, ice.AUTO].concat(can.core.List(msg["language.list"], function(item) { return can.base.trimSuffix(item, nfs._JS) })) print: function(event, can, button) { can.onlayout.topic(can, can.base.join([chat.WHITE, button]))
can.user.isMobile && (msg["theme.list"] = ["dark.css", "light.css"]) can.set("River", html.HEIGHT, -1), can.set("Action", html.HEIGHT, -1)
can.onaction._menus[2] = [chat.THEME, ice.AUTO].concat(can.core.List(msg["theme.list"], function(item) { return can.base.trimSuffix(item, nfs._CSS) })) },
can.require(can.core.List(msg["theme.list"], function(item) { return nfs.SRC_TEMPLATE+web.CHAT_HEADER+"/theme/"+item }), function() { webpack: function(event, can) {
can.user.info.titles = msg.Option("titles")||document.title can.user.input(event, can, [{name: mdb.NAME, value: can.user.title()}], function(ev, button, meta, list) {
if (can.base.beginWith(location.pathname, nfs.WIKI_PORTAL, web.CHAT_CMD+web.WIKI_PORTAL, web.CHAT_CMD+web.CHAT_OAUTH_CLIENT)) { return show(msg) } can.core.Item(Volcanos.meta.pack, function(key, msg) {
if (location.pathname == nfs.PS && can.base.beginWith(msg.Option(ice.MAIN)||"", nfs.WIKI_PORTAL, web.CHAT_CMD+web.WIKI_PORTAL)) { return show(msg) } can.core.List(["_event", "_can", "_xhr", ice.MSG_SESSID, ""], function(key) { delete(msg[key]) })
msg.Option(mdb.PLUGIN) && can.onappend.plugin(can, {space: msg.plugin[1], index: msg.Option(mdb.PLUGIN)}, function(sub) { can.onmotion.hidden(can, sub._target) }, document.body) })
msg.Option(nfs.SCRIPT) && can.require(can.base.Obj(msg.Option(nfs.SCRIPT)), function(can) { can.onaction.source(can, msg) }) var msg = can.request(event, {
var tool = can._root.Action._conf.tool name: meta.name, content: JSON.stringify(Volcanos.meta.pack),
if (can.Conf(aaa.USERNICK, (msg.Option(aaa.USERNICK)||msg.Option(ice.MSG_USERNICK)||msg.Option(ice.MSG_USERNAME)).slice(0, 8)) river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM),
|| can.misc.Search(can, web.SHARE) || tool && can.base.isIn(can.user.info._cmd = tool[0]._command, "web.chat.oauth.client", web.PORTAL, aaa.OFFER, aaa.APPLY)) { return show(msg) } })
can.onlayout._init(can), can.user.login(can, function() { can.onengine.signal(can, chat.ONMAIN, msg) }, msg)
var toast = can.user.toast(can, "打包中...", code.WEBPACK, 1000000)
can.run(event, [code.WEBPACK], function(msg) {
toast.close(), can.user.toast(can, "打包成功", code.WEBPACK)
can.user.download(can, "/share/local/"+msg.Result(), name+".html")
}) })
}) })
}, },
onstorm_select: function(can, river, storm) { can.Conf(chat.RIVER, river), can.Conf(chat.STORM, storm) }, toimage: function(event, can, button) { can.onmotion.toimage(event, can, document.title, document.body) },
onaction_cmd: function(can) { can.onappend.style(can, html.HIDE), can.onmotion.delay(can, function() { can.onimport._const(can) }) },
onsearch_focus: function(can) { can._search && can._search.focus() },
onlayout: function(can, layout, before) { can.user.isMobile || can.page.ClassList.del(can, can._target, before), can.page.ClassList.add(can, can._target, layout) },
onshare: function(can, msg, args) { can.user.share(can, msg, [ctx.ACTION, chat.SHARE].concat(args||[])) },
onwebpack: function(can, msg) { can.user.input(msg._event, can, [{name: mdb.NAME, value: can.user.title()}], function(data) {
can.core.Item(Volcanos.meta.pack, function(key, msg) { can.core.List(["_event", "_can", "_xhr", ""], function(key) { delete(msg[key]) }) })
can.runAction(can.request({}, {args: "name,river,storm,title,theme,layout", _toast: "打包中...", content: JSON.stringify(Volcanos.meta.pack),
name: data.name, river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM), theme: can._theme, title: can.user.title(), layout: can.getAction(html.LAYOUT),
}), code.WEBPACK, [], function(msg) { can.user.download(can, web.SHARE_LOCAL+msg.Result(), name, nfs.HTML), can.user.toastSuccess(can, "打包成功", code.WEBPACK) })
}) },
title: function(event, can) { var args = {}; can.core.List(can.onaction._params, function(key) { var value = can.misc.Search(can, key); value && (args[key] = value) }) carte: function(event, can, list, cb, trans) { can.user.carte(event, can, can.onaction, list, cb) },
var msg = can.request(event); can.onengine.signal(can, "ontitle", msg), can.core.List(msg.Append(), function(key) { args[key] = msg.Append(key) }) share: function(event, can, args) {
can.user.jumps(can.misc.MergeURL(can, args, true)) can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE].concat(args||[],
[chat.RIVER, can.Conf(chat.RIVER), chat.STORM, can.Conf(chat.STORM)]))
}, },
avatar: function(event, can) { if (can.user.isMobile) { return can.onaction.usernick(event, can) }
var src = can.onexport.avatar(can); can.onaction.carte(can.request(event, {_style: "header avatar"}), can, ["<img src='"+src+"'>"]) usernick: function(event, can) {
can.onaction.carte(event, can, ["shareuser", "setnick", [aaa.LANGUAGE, aaa.CHINESE, aaa.ENGLISH], cli.CLEAR, aaa.LOGOUT])
}, },
usernick: function(event, can) { can.onaction.carte(can.request(event, {_style: "header usernick"}), can, can.onaction._menus) }, shareuser: function(event, can) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE, mdb.TYPE, aaa.LOGIN]) },
shareuser: function(event, can) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE, mdb.TYPE, aaa.LOGIN, mdb.NAME, can.user.title()]) }, setnick: function(event, can) {
theme: function(event, can) { can.page.Select(can, can._output, "div.item.theme>i:first-child", function(target) { var ui = can.user.input(event, can, [{name: aaa.USERNICK, value: can.Conf(aaa.USERNICK)}], function(ev, button, data, list, args) {
can.onimport.theme(can, can.onimport._theme(can, target.className == icon.SUN? html.DARK: html.LIGHT), event) can.run(event, [aaa.USERNICK, list[0]], function(msg) {
}) }, can.page.Select(can, can._output, can.core.Keys(html.DIV, aaa.USERNICK), function(item) {
qrcode: function(event, can) { can.user.share(can, can.request(event, {link: location.href, _handle: ice.TRUE}), [ctx.ACTION, cli.QRCODE]) }, can.page.Modify(can, item, can.Conf(aaa.USERNICK, list[0]))
language: function(event, can) { can.onimport.language(can, can.user.info.language.indexOf("zh") == 0? "en-us": "zh-cn") }, }), can.user.toastSuccess(can)
email: function(event, can) { can.user.input(can.request(event, {to: can.user.info.email, subject: can.user.title()}), can, [{name: "to", _trans: "收件人", need: "must"}, "subject","content"], function(args) { }, true)
can.runAction(event, aaa.EMAIL, args, function() { can.user.toastSuccess(can) })
}) },
toimage: function(event, can) { can.onmotion.clearCarte(can), can.user.toimage(can, can.user.title(), can._target.parentNode) },
webpack: function(event, can) { can.onengine.signal(can, chat.ONWEBPACK, can.request(event)) },
setnick: function(event, can) { can.user.input(event, can, [{name: aaa.USERNICK, value: can.Conf(aaa.USERNICK)}], function(list) { can.runAction(event, aaa.USERNICK, [list[0]], function(msg) {
can.page.Select(can, can._output, can.core.Keys(html.DIV, aaa.USERNICK), function(item) { can.page.Modify(can, item, can.Conf(aaa.USERNICK, list[0])) }), can.user.toastSuccess(can)
}) }) },
setavatar: function(event, can) { can.user.input(event, can, [{name: aaa.AVATAR, value: can.Conf(aaa.AVATAR), action: mdb.ICONS}], function(list) { can.runAction(event, aaa.AVATAR, [list[0]], function(msg) {
can.page.Select(can, can._output, can.core.Keys(html.DIV, aaa.AVATAR)+" "+html.IMG, function(item) { item.src = can.misc.Resource(can, list[0]) }), can.user.toastSuccess(can)
}) }) },
setbackground: function(event, can) { can.user.input(event, can, [{name: aaa.BACKGROUND, value: can.Conf(aaa.BACKGROUND), action: mdb.ICONS}], function(list) { can.runAction(event, aaa.BACKGROUND, [list[0]], function(msg) {
}) }) },
clear: function(event, can) { can.onimport.background(event, can, "") },
logout: function(event, can) { can.user.logout(can) },
share: function(event, can, args) { can.user.share(can, can.request(event), [ctx.ACTION, chat.SHARE].concat(args||[])) },
carte: function(event, can, list, cb, trans) { return can.user.carte(event, can, can.onaction, list, cb, null, trans) },
_params: [log.DEBUG, chat.TITLE],
_menus: [
cli.QRCODE, "shareuser",
[chat.THEME], [aaa.LANGUAGE],
// [nfs.SAVE, aaa.EMAIL, web.TOIMAGE, code.WEBPACK],
[aaa.USER, "setnick", "setavatar", "setbackground", web.CLEAR, aaa.LOGOUT],
],
_trans: kit.Dict("shareuser", "共享用户", cli.QRCODE, "生成链接",
chat.THEME, "界面主题", aaa.LANGUAGE, "语言地区",
nfs.SAVE, "保存网页", aaa.EMAIL, "发送邮件", web.TOIMAGE, "生成图片", code.WEBPACK, "打包页面",
aaa.USER, "用户信息", "setnick", "设置昵称", "setavatar", "设置头像", "setbackground", "设置背景", aaa.PASSWORD, "修改密码", web.CLEAR, "清除背景", aaa.LOGOUT, "退出登录",
"change language to zh-cn", "切换语言为中文",
"change language to en-us", "切换语言为英文",
"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, {
language: function(can) { return can.user.info.language },
avatar: function(can) { return can.misc.Resource(can, can.user.info.avatar == "void"? "": can.user.info.avatar) },
background: function(can) { return can.user.info.background == "void"? "": can.user.info.background },
theme: function(can) { return can._theme || can.misc.SearchOrConf(can, chat.THEME) || can.__theme || "" },
height: function(can) { return can._target.offsetHeight },
})
Volcanos(chat.ONPLUGIN, {
location: shy("请求地址", {copy: function(can) { can.user.copy(msg._event, can, location.href) }}, [web.LINK, ice.LIST, ice.COPY], function(can, msg, cb) {
can.runAction(can.request({}, kit.Dict(web.LINK, location.href)), web.SHARE, [], function(res) {
msg.Echo(res.Append(mdb.TEXT)).Status(kit.Dict(web.LINK, res.Append(mdb.NAME))), can.base.isFunc(cb) && cb(msg)
}) })
}), can.user.isMobile && can.page.Modify(can, ui._target, {style: {top: 40, right: 0, left: ""}})
sessionStorage: shy("会话存储", { },
create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.sessionStorage(can, name, value) }), chinese: function(event, can) { can.misc.Search(can, aaa.LANGUAGE, "zh") },
remove: shy(function(can, name) { name && can.misc.sessionStorage(can, name, "") }), english: function(event, can) { can.misc.Search(can, aaa.LANGUAGE, "en") },
prunes: shy(function(can, name) { can.core.Item(can.misc.sessionStorage(can), function(key, value) { can.misc.sessionStorage(can, key, "") }) }), clear: function(event, can) { can.onimport.background(event, can, ""), can.onimport.avatar(event, can, ""), can.user.reload(true) },
modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.sessionStorage(can, msg.Option(mdb.NAME), arg[1]) } else { logout: function(event, can) { can.user.logout(can) },
can.misc.sessionStorage(can, arg[1], msg.Option(mdb.VALUE)), can.misc.sessionStorage(can, msg.Option(mdb.NAME), "")
} }), River: function(can) { can.search({}, ["River.onmotion.toggle"]) },
}, [web.FILTER, ice.LIST, mdb.CREATE, mdb.PRUNES], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() }) Footer: function(can) { can.search({}, ["Footer.onmotion.toggle"]) },
can.core.Item(can.misc.sessionStorage(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) })
}),
localStorage: shy("本地存储", {
create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.localStorage(can, name, value) }),
remove: shy(function(can, name) { name && can.misc.localStorage(can, name, "") }),
modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.localStorage(can, msg.Option(mdb.NAME), arg[1]) } else {
can.misc.localStorage(can, arg[1], msg.Option(mdb.VALUE)), can.misc.localStorage(can, msg.Option(mdb.NAME), "")
} }),
}, [web.FILTER, ice.LIST, mdb.CREATE], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() })
can.core.Item(can.misc.localStorage(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) })
}),
cookie: shy("会话参数", {
create: shy([mdb.NAME, mdb.VALUE], function(can, name, value) { can.misc.Cookie(can, name, value) }),
remove: shy(function(can, name) { name && can.misc.Cookie(can, name, "") }),
modify: shy(function(can, msg, arg) { if (arg[0] == mdb.VALUE) { can.misc.Cookie(can, msg.Option(mdb.NAME), arg[1]) } else {
can.misc.Cookie(can, arg[1], msg.Option(mdb.VALUE)), can.misc.Cookie(can, msg.Option(mdb.NAME), "")
} }),
}, [web.FILTER, ice.LIST, mdb.CREATE], function(can, msg, arg) { msg.Defer(function() { msg.PushAction(mdb.REMOVE).StatusTimeCount() })
can.core.Item(can.misc.Cookie(can), function(name, value) { can.base.contains(name, arg[0]) && msg.Push(mdb.NAME, name).Push(mdb.VALUE, value) })
}),
language: shy("语言地区", {_init: function(can) { can.Option(aaa.LANGUAGE, can.user.info.language||ice.AUTO) }}, ["language:select=auto,zh,en", ctx.RUN], function(can, msg, arg) { can.onimport.language(can, arg[0]) }),
avatar: shy("用户头像", function(can, sub, cb) { can.page.Append(can, sub._output, [{img: can.user.info.avatar, style: kit.Dict(html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth())}]) }),
background: shy("背景图片", function(can, sub, cb) { can.page.Append(can, sub._output, [{img: can.user.info.background, style: kit.Dict(html.MAX_HEIGHT, sub.ConfHeight(), html.MAX_WIDTH, sub.ConfWidth())}]) }),
theme: shy("界面主题", {_init: function(can) { can.Option(chat.THEME, can.getHeader(chat.THEME)) },
save: function(can, sup) { can.user.downloads(can, sup._themes[can.Option(chat.THEME)], can.Option(chat.THEME), nfs.CSS) },
}, ["theme:select=auto,dark,light,print,white,black", ctx.RUN, nfs.SAVE], function(can, msg, arg) {
if (arg[0] == ice.AUTO) { arg[0] = "", can._theme = "" } can.misc.localStorage(can, "can.theme", arg[0]), can.onimport.theme(can, arg[0])
}),
title: shy("网页标题", [chat.TITLE], function(can, msg, arg) { msg.Echo(can.user.title(arg[0])) }),
logout: shy("退出登录", kit.Dict(aaa.LOGOUT, shy("退出", function(can) { can.user.logout(can._root.Header) })), [aaa.LOGOUT]),
}) })
Volcanos("onexport", {help: "导出数据", list: [],
height: function(can) { return can._target.offsetHeight },
topic: function(can) { return can._topic },
})

View File

@ -1,36 +1,29 @@
fieldset.River { width:var(--river-width); float:left; position:relative; } fieldset.River {
fieldset.River>div.action:not(.hide) { margin-top:var(--plugin-margin); width:100%; position:absolute; } float:left; overflow:auto;
fieldset.River>div.action div.item.notice input { border:0; } }
fieldset.River>div.action div.item:hover input { background-color:var(--notice-bg-color); color:var(--notice-fg-color); } fieldset.River>div.output div.item {
fieldset.River>div.output { transition:all .3s; } border-left:solid 3px #00ffae;
fieldset.River>div.output div.item { font-family:var(--legend-font-family); padding:var(--legend-padding); border-left:#00ffae solid 3px; } padding:3px 16px;
fieldset.River>div.output div.item.select { color:var(--panel-hover-fg-color); } }
fieldset.River>div.output div.item:hover { color:var(--panel-hover-fg-color); } fieldset.River>div.output div.item.select {
fieldset.River>div.output div.item>i:first-child { margin-right:var(--button-margin); } background-color:#2e515f;
fieldset.River>div.output div.list div.item { border-left:#ccdc4c solid 3px; } }
fieldset.River>div.output div.list { margin-left:var(--legend-padding); } fieldset.River>div.output div.item:hover {
fieldset.River>div.output { margin:var(--river-margin) 0; margin-bottom:20px; } background-color:#2e515f;
fieldset.River>div.toggle { rotate:90deg; right:calc(50% - 5px); } }
fieldset.River>div.toggle.prev { top:0; } fieldset.River>div.output div.list {
fieldset.River>div.toggle.next { bottom:-52px; } margin-left:8px; padding-left:5px;
fieldset.River:not(:hover)>div.toggle { visibility:hidden; } }
fieldset.River:not(.all):not(.tabs):not(.page) { width:var(--header-height); } fieldset.River>div.output div.list div.item {
fieldset.River:not(.all):not(.tabs):not(.page)>div.action { flex-direction:column; overflow:hidden; } border-left:solid 3px #ccdc4c;
fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item { margin-right:0; } background-color:#073540b5;
fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item.share { display:none; } }
fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item.refresh { display:none; } fieldset.River>div.output div.list div.item.select {
fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item>input { display:none; } background-color:#2e515f;
fieldset.River:not(.all):not(.tabs):not(.page)>div.action div.item>span { display:unset; } }
fieldset.River:not(.all):not(.tabs):not(.page)>div.output div.item { padding:var(--button-padding); } fieldset.River>div.output div.list div.item:hover {
fieldset.River:not(.all):not(.tabs):not(.page)>div.output div.item>span { display:none; } background-color:#2e515f;
fieldset.River:not(.all):not(.tabs):not(.page)>div.output>div.item>i:last-child { display:none; } }
fieldset.River:not(.all):not(.tabs):not(.page)>div.output>div.item>i:first-child { font-size:24px; } body.mobile fieldset.River {
fieldset.River:not(.all):not(.tabs):not(.page)>div.output div.item>i:first-child { margin-right:0; } z-index:10;
fieldset.River:not(.all):not(.tabs):not(.page)>div.output>div.list { margin-left:var(--input-margin); } }
fieldset.River.page { display:none; }
fieldset.River.tabs>div.action:not(.hide) { margin-top:0; }
fieldset.River.tabview>div.action:not(.hide) { margin-top:calc(var(--plugin-margin) + var(--plugin-padding)); }
fieldset.River.tabview>div.output div.item { display:flex; align-items:center; justify-content:center; }
body.void fieldset.River>div.action { display:none; }
body.mobile fieldset.River>div.output { margin-top:16px; }
body.mobile fieldset.River>div.toggle.prev { top:-52px; }

View File

@ -1,166 +1,283 @@
(function() { const CAN_RIVER = "can.river", CAN_STORM = "can.storm" Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
Volcanos(chat.ONIMPORT, { if (msg.Option(ice.MSG_RIVER) == "_share") { return can.onmotion.hidden(can) }
_init: function(can, msg) { can.onimport._main(can, msg), can.onappend.style(can, html.FLEX, can._action) can.onmotion.clear(can), can.river_list = {}, can.storm_list = {}
var select; can.page.Appends(can, can._output, msg.Table(function(item, index) {
return can.onimport._river(can, item, function(target) { (index == 0 || item.hash == can._main_river) && (select = target) }) can.onimport._main(can, msg), can.onimport._menu(can, msg)
})), select && select.click(), can.onimport._menu(can, msg) var select; can.page.Append(can, can._output, msg.Table(function(item, index) {
return can.onimport._river(can, item, function(target) {
(index == 0 || item.hash == can._main_river) && (select = target)
})
})), select && select.click()
}, },
_main: function(can, msg) { can.ui = {river_list: {}, storm_list: {}, sublist: {}} _main: function(can, msg) { can._main_river = "project", can._main_storm = "studio"
var ls = can.misc.SearchHash(can); msg.Table(function(item) { item.main && (can._main_river = item.hash) }) if (can.user.isExtension) { var args = Volcanos.meta.args
can._main_river = ls[0]||can.misc.SearchOrConf(can, chat.RIVER)||msg.Option(ice.MSG_RIVER)||can._main_river||(can.misc.Search(can, ice.MSG_DEBUG) == ice.TRUE? "project": "profile") can._main_river = args.river||"product", can._main_storm = args.storm||"chrome"
can._main_storm = ls[1]||can.misc.SearchOrConf(can, chat.STORM)||msg.Option(ice.MSG_STORM)
},
_river: function(can, meta, cb) { return {view: html.ITEM, title: meta.name, list: [{icon: meta.icon}, {text: meta.name}, {icon: icon.CHEVRON_DOWN}], _init: function(target) { can.ui.river_list[meta.hash] = target, cb(target) },
onclick: function(event) { can.onaction.storm(event, can, meta.hash) }, oncontextmenu: function(event) { can.onaction.carte(event, can, can.onaction._menu, meta.hash) },
} },
_storm: function(can, meta, river) { return {view: html.ITEM, title: meta.name, list: [{icon: meta.icon}, {text: meta.name}], _init: function(target) { can.ui.storm_list[can.core.Keys(river, meta.hash)] = target },
onclick: function(event) { can.onaction.action(event, can, river, meta.hash) }, oncontextmenu: function(event) { can.onaction.carte(event, can, can.ondetail._menu, river, meta.hash) },
} },
_menu: function(can, msg) { can.user.isMobile || can.user.mod.isPod? can.onmotion.hidden(can, can._action): can.onappend._action(can, can.onaction.list, can._action) },
})
Volcanos(chat.ONACTION, {list: [mdb.CREATE, web.SHARE, web.REFRESH],
_init: function(can) {
can.db.storm_list = {}, can.onmotion.hidden(can)
var next = can.page.unicode.next, prev = can.page.unicode.prev
can._prev = can.page.Append(can, can._target, [{view: [[html.TOGGLE, mdb.PREV], "", prev], onclick: function(event) {
can._output.scrollBy && can._output.scrollBy(0, -10000)
}}])._target
can._next = can.page.Append(can, can._target, [{view: [[html.TOGGLE, mdb.NEXT], "", next], onclick: function(event) {
can._output.scrollBy && can._output.scrollBy(0, 10000)
}}])._target
can._output.onscroll = function() { can.onexport.scroll(can) }
},
onlogin: function(can, msg) { can.run(can.request({}, {_method: http.GET}), [], function(msg) { if (msg.Option(ice.MSG_RIVER)) { return can.page.Remove(can, can._target) }
can.onimport._init(can, msg); if (can.user.isMobile || can.user.isExtension) { return can.page.ClassList.add(can, can._target, ice.AUTO) }
can.onmotion.toggle(can, can._target, true), can.onlayout._init(can)
}) },
onaction_touch: function(can, msg) { can.user.isMobile && can.onmotion.hidden(can) },
onaction_notool: function(can, msg, river, storm) { can.ondetail["addcmd"](msg._event, can, "addcmd", river, storm) },
onsearch: function(can, msg, arg) { if (arg[0] == chat.STORM) { can.onexport.storm(can, msg, arg) } },
onlayout: function(can, layout, before) { can.page.ClassList.del(can, can._target, before), can.page.ClassList.add(can, can._target, layout) },
create: function(event, can) { can.user.input(can.request(event, {title: "创建群组"}), can, [
{name: mdb.TYPE, values: [aaa.TECH, aaa.VOID], _trans: "类型"},
{name: mdb.NAME, value: "hi", _trans: "群名", need: "must"},
{name: mdb.ICON, value: "", _trans: "图标"},
{name: mdb.TEXT, value: "hello", _trans: "简介"},
], function(args) { can.runAction(event, mdb.CREATE, args, function(msg) { can.misc.Search(can, {river: msg.Result()}) }) }) },
share: function(event, can) { can.core.CallFunc(can.ondetail.share, {event: event, can: can}) },
onsize: function(can, height) { var margin = 68, _margin = margin
can.page.style(can, can._output, html.MARGIN, "0px", html.HEIGHT, "", html.MAX_HEIGHT, "")
if (can.user.isMobile || !can.user.isTechOrRoot(can)) { margin = 16 }
if (can._output.offsetHeight < height-margin) {
margin += (height-margin-can._output.offsetHeight)/4
} else {
can.page.style(can, can._output, html.MAX_HEIGHT, height-margin-16)
} }
can.page.style(can, can._output, html.MARGIN, margin+"px 0px "+(margin-_margin)+"px") if (can.user.isMobile) { can._main_river = "product", can._main_storm = "office" }
can._output.scrollTop = can._scrollTop if (can.user.isWeiXin) { can._main_river = "service", can._main_storm = "wx" }
can.onexport.scroll(can)
can._main_title = can.misc.Search(can, chat.TITLE)||msg.Option(ice.MSG_TITLE)||Volcanos.meta.args.title||can.misc.Search(can, ice.POD)||can._main_title
can._main_river = can.misc.Search(can, chat.RIVER)||msg.Option(ice.MSG_RIVER)||Volcanos.meta.args.river||can._main_river
can._main_storm = can.misc.Search(can, chat.STORM)||msg.Option(ice.MSG_STORM)||Volcanos.meta.args.storm||can._main_storm
}, },
refresh: function(event, can) { can.misc.Search(can, {river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM)}) }, _menu: function(can, msg) { if (can.user.mod.isPod) { return }
storm: function(event, can, river) { can.onmotion.select(can, can._output, html.DIV_ITEM, can.ui.river_list[river]) can.setHeaderMenu(can.base.Obj(msg.Option(chat.MENUS), can.Conf(chat.MENUS)||can.ondetail._menus), function(event, button) {
function _menu(list) { can.onlayout._init(can), can.page.ClassList.set(can, can.ui.river_list[river], "open", can.page.isDisplay(list)) } can.core.CallFunc([can.ondetail, button], [event, can, button, can.Conf(chat.RIVER), can.Conf(chat.STORM)])
var list = can.ui.sublist[river]; if (list) { return can.onmotion.toggle(can, list), _menu(list) } })
can.run({}, [river, chat.STORM], function(msg) { var next = can.ui.river_list[river].nextSibling },
if (msg.Length() == 0) { return can.user.isLocalFile? can.user.toastFailure(can, "miss data"): can.onengine.signal(can, chat.ONACTION_NOSTORM, can.request({}, {river: river})) } _carte: function(can, list, river, storm) { if (can.user.isMobile) { return }
can.db.storm_list[river] = msg.Table() if (can.core.Value(can._root, can.core.Keys(chat.RIVER, river))) { return }
var _main_storm; msg.Table(function(item) { item.main && (_main_storm = item.hash) }), _main_storm = can._main_storm || _main_storm || (
can.user.info.nodetype == web.WORKER? web.DESKTOP: can.misc.Search(can, ice.MSG_DEBUG) == ice.TRUE? "studio": (can.user.info.nodetype == web.SERVER? web.DREAM: "desktop") can.onaction.carte(event, can, list, function(event, button, module) {
) module[button](event, can, button, river, storm)
})
},
_river: function(can, meta, cb) {
return {text: [meta.name, html.DIV, html.ITEM], onclick: function(event) {
can.onaction.storm(event, can, meta.hash)
}, onmouseenter: function(event) {
can.onimport._carte(can, can.ondetail.list, meta.hash)
}, _init: function(target) { cb(target)
can.river_list[meta.hash] = target
}}
},
_storm: function(can, meta, river) {
return {text: [meta.name, html.DIV, html.ITEM], onclick: function(event) {
can.onaction.action(event, can, river, meta.hash)
can.user.title(can._main_title||meta.name)
}, onmouseenter: function(event) {
can.onimport._carte(can, can.ondetail.sublist, river, meta.hash)
}, _init: function(target) {
can.storm_list[can.core.Keys(river, meta.hash)] = target
}}
},
})
Volcanos("onengine", {help: "解析引擎", list: [], _engine: function(event, can, msg, panel, cmds, cb) {
var list = can._root.river
cmds.length == 0 && can.core.Item(list, function(key, value) {
if (can.core.Item(value.storm).length == 0) { return }
msg.Push({hash: key, name: can.user.language(can) == "en"? key: value.name}) // 群组列表
}); if (cmds.length != 1 && cmds[1] != chat.STORM) { return false }
var river = list[cmds[0]]; if (!river) { return false }
can.core.Item(river.storm, function(key, value) {
msg.Push({hash: key, name: can.user.language(can) == "en"? key: value.name}) // 应用列表
}), can.base.isFunc(cb) && cb(msg); return true
}})
Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, cb, target) {
can.onengine.plugin(can, "info", shy("信息", {}, ["text", "list", "back"], function(msg, cmds) {
msg.Echo(JSON.stringify(can))
}))
can.onengine.plugin(can, "log", shy("日志", {}, ["text", "list", "back"], function(msg, cmds) {
console.log(cmds[0])
msg.Option(ice.MSG_DISPLAY, "/plugin/story/pie.js")
}))
can.onengine.plugin(can, "pie", shy("比例图", {}, ["list", "back"], function(msg, cmds) {
msg.Option(ice.MSG_DISPLAY, "/plugin/story/pie.js")
msg.Push("value", 200)
msg.Push("value", 300)
msg.Push("value", 400)
}))
can.base.isFunc(cb) && cb()
},
onlogin: function(can, msg) {
can.onappend._action(can, can.Conf(ctx.ACTION)||can.onaction.list)
can.run({}, [], function(msg) { can.onimport._init(can, msg, [], null, can._output) })
},
onsearch: function(can, msg, word) {
if (word[0] == "*" || word[0] == chat.STORM) { can.onexport.storm(can, msg, word) }
},
onstorm_select: function(can, msg, river, storm) { var args = {river: river, storm: storm}
if (can.user.isExtension) { localStorage.setItem(ctx.ARGS, JSON.stringify(args)) }
},
onaction_touch: function(can, msg) {
can.onmotion.float.del(can, chat.CARTE)
can.user.isMobile && can.onmotion.hidden(can)
},
onaction_notool: function(can, msg, river, storm) {
can.ondetail["添加工具"](msg._event, can, "添加工具", river, storm)
},
carte: function(event, can, list, cb) {
can.user.carteRight(event, can, can.ondetail, list, cb)
},
storm: function(event, can, river) { can.sublist = can.sublist||{}
can.onmotion.select(can, can._output, "div.item", can.river_list[river])
var list = can.sublist[river]; if (list) { return can.onmotion.toggle(can, list) }
can.run({}, [river, chat.STORM], function(msg) {
var select = 0; list = can.page.Append(can, can._output, [{view: html.LIST, list: msg.Table(function(item, index) { var select = 0; list = can.page.Append(can, can._output, [{view: html.LIST, list: msg.Table(function(item, index) {
river == can._main_river && (item.hash == _main_storm) && (select = index) river == can._main_river && item.hash == can._main_storm && (select = index)
return can.onimport._storm(can, item, river) return can.onimport._storm(can, item, river)
}) }])._target, next && can._output.insertBefore(list, next), can.ui.sublist[river] = list, _menu(list), list.children.length > 0 && list.children[select].click() }) }]).first, list.children.length > 0 && list.children[select].click()
event.target.nextSibling && can._output.insertBefore(list, event.target.nextSibling)
can.sublist[river] = list
}) })
}, },
action: function(event, can, river, storm) { action: function(event, can, river, storm) {
can._scrollTop = can._output.scrollTop can.page.Modify(can, can.sublist[river], {style: {display: html.BLOCK}})
can.page.Select(can, can._output, [html.DIV_LIST, html.DIV_ITEM], function(target) { can.page.ClassList.del(can, target, html.SELECT) }) can.onmotion.select(can, can._output, "div.item", can.river_list[river])
can.onmotion.toggle(can, can.ui.sublist[river], true) can.onmotion.select(can, can._output, "div.list div.item", can.storm_list[can.core.Keys(river, storm)])
can.onmotion.select(can, can.ui.sublist[river], html.DIV_ITEM, can.ui.storm_list[can.core.Keys(river, storm)])
can.onmotion.select(can, can._output, html.DIV_ITEM, can.ui.river_list[river]) can.onengine.signal(can, "onstorm_select", can.request(event, {
var list = can.db.storm_list[river]; river: can.Conf(chat.RIVER, river), storm: can.Conf(chat.STORM, storm),
can.user.isMobile && can.onmotion.hidden(can, can._root.Footer._target, list.length > 1) }))
can.user.isMobile && can.onmotion.delay(can, function() {
var menu = can.setFooterMenu(list, function(event, button, list) { can.onaction.action(event, can, river, button) })
can.page.SelectChild(can, menu, html.DIV_ITEM, function(target, index) { can.page.ClassList.set(can, target, html.SELECT, list[index].hash == can.Conf("storm")) })
}, 300), can.onengine.signal(can, chat.ONSTORM_SELECT, can.request(event, {river: can.Conf(chat.RIVER, river), storm: can.Conf(chat.STORM, storm)}))
}, },
carte: function(event, can, list, river, storm) { can.onkeymap.prevent(event); if (can.core.Value(can._root, can.core.Keys(chat.RIVER, river))) { return }
can.request(event, {river: river, storm: storm}); storm? can.user.carteRight(event, can, can.ondetail, list): can.user.carteRight(event, can, can.onaction, list) create: function(event, can) {
}, can.user.trans(can, {"public": "公开群", "protected": "内部群", "private": "私有群"})
_menu: ["addapp", "rename", "remove"], can.user.input(event, can, [
_trans: {addapp: "添加应用", rename: "重命名群组", remove: "删除群组"}, {name: mdb.TYPE, values: [chat.PUBLIC, chat.PROTECTED, chat.PRIVATE], _trans: "类型"},
addapp: function(event, can, button, river) { can.ondetail.create(event, can, button, river) }, {name: mdb.NAME, value: "hi", _trans: "群名"}, {name: mdb.TEXT, value: "hello", _trans: "简介"},
rename: function(event, can, button, river) { can.user.input(event, can, [mdb.NAME, mdb.ICON], function(args) { ], function(event, button, meta, list, args) {
can.runAction(event, mdb.MODIFY, [mdb.HASH, river].concat(args), function(msg) { can.page.Modify(can, can.ui.river_list[river], args[1]), can.user.toastSuccess(can) }) can.run(event, [ctx.ACTION, mdb.CREATE].concat(args), function(msg) {
}) }, can.misc.Search(can, {river: msg.Result()})
remove: function(event, can, button, river) { can.runAction(event, mdb.REMOVE, [mdb.HASH, river], function(msg) { can.misc.Search(can, {river: "", storm: ""}) }) }, })
onaction_nostorm: function(can, msg, river) { can.ondetail.create({}, can, mdb.CREATE, river) },
onaction_remove: function(can, msg, river, storm, id) { can.run(can.request({}), [river, storm, chat.STORM, ctx.ACTION, mdb.DELETE, mdb.ID, id], function() { }) },
})
Volcanos(chat.ONDETAIL, {
_menu: ["share", "savearg", "addcmd", "rename", "remove"],
_trans: {share: "共享应用", savearg: "保存参数", addcmd: "添加工具", rename: "重命名应用", remove: "删除应用"},
share: function(event, can, button, river, storm) { can.onmotion.share(event, can, [{name: chat.TITLE, value: can.user.title()}, {name: chat.THEME, values: [ice.AUTO, html.DARK, html.LIGHT, cli.WHITE, cli.BLACK]}], [mdb.TYPE, chat.STORM, chat.RIVER, river, chat.STORM, storm]) },
savearg: function(event, can, button, river, storm) { can.getAction(ctx.ARGS, function(args, sub, next, index, array) { var toast = can.user.toast(can, (index+1)+nfs.PS+array.length, button, 10000, (index+1)*100/array.length)
can.run({}, [river, storm, chat.STORM, ctx.ACTION, mdb.MODIFY, mdb.ID, sub.Conf(mdb.ID), ctx.ARGS, JSON.stringify(args)], function() {
can.onmotion.delay(can, function() { toast.close(), next(), index == array.length-1 && can.user.toastSuccess(can) })
}) })
}) }, },
addcmd: function(event, can, button, river, storm) { can.user.input(can.request(event, {title: "添加工具"}), can, [ refresh: function(event, can) {
{name: web.SPACE, _trans: "空间"}, var args = {river: can.Conf(chat.RIVER), storm: can.Conf(chat.STORM),
{name: ctx.INDEX, need: "must", _trans: "命令"}, {name: ctx.ARGS, _trans: "参数"}, topic: can.getHeader(chat.TOPIC), layout: can.getAction(chat.LAYOUT),
{name: mdb.ICON, _trans: "图标"}, {name: ctx.STYLE, _trans: "样式"}, {name: ctx.DISPLAY, _trans: "脚本"}, }
], function(args) { can.run({}, [river, storm, chat.STORM, ctx.ACTION, mdb.INSERT].concat(args), function(msg) { if (can.user.isExtension) { localStorage.setItem(ctx.ARGS, JSON.stringify(args)) }
can.onengine.signal(can, chat.ONSTORM_SELECT, can.request(event, {river: can.Conf(chat.RIVER, river), storm: can.Conf(chat.STORM, storm), refresh: ice.TRUE})) can.misc.Search(can, args)
}) }) }, },
rename: function(event, can, button, river, storm) { can.user.input(event, can, [mdb.NAME, mdb.ICON], function(args) {
can.run(event, [river, storm, chat.STORM, ctx.ACTION, mdb.MODIFY].concat(args), function() { can.page.Modify(can, can.ui.storm_list[can.core.Keys(river, storm)], args[1]), can.user.toastSuccess(can) })
}) },
remove: function(event, can, button, river, storm) { can.run(event, [river, storm, chat.STORM, ctx.ACTION, mdb.REMOVE], function(msg) { can.misc.Search(can, {river: river, storm: ""}) }) },
create: function(event, can, button, river) { can.user.input(can.request(event, {title: "添加应用"}), can, [
{name: mdb.NAME, value: "hi", _trans: "名称", need: "must"},
{name: mdb.ICON, value: "", _trans: "图标"},
{name: mdb.TEXT, value: "hello", _trans: "简介"},
], function(args) { can.run({}, [river, chat.STORM, ctx.ACTION, mdb.CREATE].concat(args), function(msg) { can.misc.Search(can, {river: river, storm: msg.Result()}) }) }) },
}) })
Volcanos(chat.ONEXPORT, { Volcanos("ondetail", {help: "菜单交互",
list: ["共享群组", "添加应用", "添加设备", "添加用户", "重命名群组", "删除群组"],
sublist: ["共享应用", "添加工具", "保存参数", "重命名应用", "删除应用"],
_menus: [
["create", "创建群组", "添加应用", "添加工具", "添加设备", "创建空间"],
["share", "共享群组", "共享应用", "共享工具", "共享主机", "访问空间"],
],
"创建群组": function(event, can) { can.onaction.create(event, can) },
"共享群组": function(event, can, button, river) {
can.onmotion.share(event, can, [{name: chat.TITLE, value: river}], [mdb.TYPE, chat.RIVER])
},
"添加应用": function(event, can, button, river) { can.ondetail.create(event, can, button, river) },
"共享应用": function(event, can, button, river, storm) {
can.onmotion.share(event, can, [{name: chat.TITLE, value: storm}], [mdb.TYPE, chat.STORM])
},
"添加工具": function(event, can, button, river, storm) {
can.user.select(event, can, ctx.COMMAND, "context,command", function(item, next) {
can.run({}, [river, chat.STORM, ctx.ACTION, mdb.INSERT, mdb.HASH, storm].concat([ice.POD, "", ice.CTX, item[0], ice.CMD, item[1]]), function(msg) {
next()
})
}, function() {
can.misc.Search(can, {river: river, storm: storm})
})
},
"共享工具": function(event, can, button, river, storm) {
can.user.select(event, can, mdb.PLUGIN, "name,context,command,argument", function(item, next) {
can.user.share(can, can.request(event), [river, ctx.ACTION, chat.SHARE, mdb.TYPE, chat.FIELD,
mdb.NAME, item[2], mdb.TEXT, item[3], chat.TITLE, item[0], chat.RIVER, river, chat.STORM, storm,
])
})
},
"添加设备": function(event, can, button, river) {
can.user.select(event, can, web.SPACE, "type,name,text", function(item, next) {
can.run({}, [river, chat.NODE, ctx.ACTION, mdb.INSERT, mdb.TYPE, item[0], mdb.NAME, item[1]], function(msg) {
next()
})
})
},
"共享主机": function(event, can, button, river, storm) {
can.run(event, [ctx.ACTION, aaa.INVITE], function(msg) {
can.user.toast(can, {
title: "共享主机", duration: -1, width: -300,
content: msg.Result(), action: [cli.CLOSE],
})
})
},
"创建空间": function(event, can, button, river, storm) { can.request(event, {action: button})
can.user.input(event, can, [{name: "name", value: "hi"}, {name: "repos"}, {name: "template"}], function(event, button, data, list, args) {
can.run(event, [ctx.ACTION, cli.START].concat(args, chat.RIVER, river), function(msg) {
var link = can.misc.MergeURL(can, {_path: "/chat/pod/"+can.core.Keys(can.misc.Search(can, ice.POD), msg.Option(mdb.NAME))})
can.user.toast(can, link), can.user.open(link)
})
})
},
"访问空间": function(event, can, button, river, storm) {
can.user.select({river: river}, can, web.SPACE, "time,type,name,text")
},
"添加用户": function(event, can, button, river) {
can.user.select(event, can, chat.USER, "usernick,username", function(item, next) {
can.run({}, [river, chat.USER, ctx.ACTION, mdb.INSERT, aaa.USERNAME, item[0]], function(msg) {
next()
})
})
},
"重命名群组": function(event, can, button, river) {
can.user.input(event, can, [mdb.NAME], function(event, button, meta, list) {
can.run(can.request(event, {hash: river})._event, [ctx.ACTION, mdb.MODIFY, mdb.NAME, meta.name], function(msg) {
can.misc.Search(can, {river: river})
})
})
},
"删除群组": function(event, can, button, river) {
can.run(can.request(event, {hash: river})._event, [ctx.ACTION, mdb.REMOVE], function(msg) { can.misc.Search(can, {}) })
},
"保存参数": function(event, can, button, river, storm) {
can.getAction(ctx.ARGS, function(item, next, index, array) { var msg = can.request({}, {hash: storm, id: item.dataset.id})
var toast = can.user.toast(can, (index+1)+ice.PS+array.length, button, 10000, (index+1)*100/array.length)
can.run(msg._event, [river, chat.STORM, ctx.ACTION, mdb.MODIFY, ice.ARG, item.dataset.args], function(msg) {
can.core.Timer(200, function() {
toast.close(), next(), index == array.length-1 && can.user.toastSuccess(can, button)
})
})
})
},
"重命名应用": function(event, can, button, river, storm) {
can.user.input(event, can, [mdb.NAME], function(ev, button, meta, list, args) {
can.run(can.request(event, {hash: storm})._event, [river, chat.STORM, ctx.ACTION, mdb.MODIFY].concat(args), function(msg) {
can.misc.Search(can, {river: river, storm: storm})
})
})
},
"删除应用": function(event, can, button, river, storm) {
can.run(can.request(event, {hash: storm})._event, [river, chat.STORM, ctx.ACTION, mdb.REMOVE], function(msg) {
can.misc.Search(can, {river: river})
})
},
create: function(event, can, button, river) {
can.user.trans(can, {"public": "公开应用", "protected": "群组应用", "private": "个人应用"})
can.user.input(event, can, [
{name: mdb.TYPE, values: [chat.PUBLIC, chat.PROTECTED, chat.PRIVATE], _trans: "类型"},
{name: mdb.NAME, value: "hi", _trans: "名称"}, {name: mdb.TEXT, value: "hello", _trans: "简介"},
], function(event, button, meta, list, args) {
can.run({}, [river, chat.STORM, ctx.ACTION, mdb.CREATE].concat(args), function(msg) {
can.misc.Search(can, {river: river, storm: msg.Result()})
})
})
},
})
Volcanos("onexport", {help: "导出数据", list: [],
width: function(can) { return can._target.offsetWidth }, width: function(can) { return can._target.offsetWidth },
storm: function(can, msg, arg) { can.core.Item(can._root.river, function(river, value) { can.core.Item(value.storm, function(storm, item) { if (arg[1] != "" && storm.indexOf(arg[1]) == -1 && item.name.indexOf(arg[1]) == -1) { return } storm: function(can, msg, word) {
msg.Push({ctx: ice.CAN, cmd: can._name, type: river, name: storm, text: shy("跳转", function(event) { can.onaction.action(event, can, river, storm) })}) var fields = (msg.Option(ice.MSG_FIELDS)||"ctx,cmd,type,name,text").split(",")
}) }) }, can.core.Item(can._root.river, function(river, value) {
scroll: function(can) { can.onmotion.delayOnce(can, function() { can.core.Item(value.storm, function(storm, item) {
if (can._output.offsetHeight == can._output.scrollHeight) { if (word[1] != "" && word[1] != storm && word[1] != item.name) { return }
can.onmotion.hidden(can, can._prev), can.onmotion.hidden(can, can._next)
} else { var data = {ctx: "web.chat", cmd: chat.STORM,
can.onmotion.toggle(can, can._prev, can._output.scrollTop > 10) type: river, name: storm, text: shy("跳转", function(event) {
can.onmotion.toggle(can, can._next, can._output.scrollTop+can._output.offsetHeight < can._output.scrollHeight-10) can.onaction.action(event, can, river, storm)
} }),
}) }, }; can.core.List(fields, function(key) { msg.Push(key, data[key]||"") })
}) })
Volcanos(chat.ONENGINE, {
_engine: function(event, can, msg, panel, cmds, cb) {
function right(role) { if (!role || role == aaa.VOID) { return true }
return can.core.List(can.core.Split(can.user.info.userrole||aaa.VOID), function(userrole) {
if (can.base.isIn(userrole, role, aaa.TECH, aaa.ROOT)) { return true }
}).length > 0
}
if (typeof can.river == code.FUNCTION) { can.river = can.river(can) } var list = can.river
cmds.length == 0 && can.core.ItemOrder(list, mdb.ORDER, function(key, value) { if (!value) { return }
if (value.debug && can.misc.Search(can, ice.MSG_DEBUG) != ice.TRUE) { return }
if (value.nodetype && value.nodetype != can.user.info.nodetype) { return }
if (right(value.type)) {
can.core.Item(value.storm).length > 0 && msg.Push({hash: key, name: can.user.isEnglish(can)? key: value.name, icon: value.icon||"", main: value.main||false})
}
}) })
if (cmds.length != 1 && cmds[1] != chat.STORM) { return false } var river = list[cmds[0]]; if (!river) { return false }
can.core.ItemOrder(river.storm, mdb.ORDER, function(key, value) { if (!value) { return }
if (value.nodetype && value.nodetype != can.user.info.nodetype) { return }
if (right(value.type)) {
msg.Push({hash: key, name: can.user.isEnglish(can)? key: value.name||(can.user.trans(can, key)+" "+key), icon: value.icon||icon[key]||"", main: value.main||false})
}
}), can.base.isFunc(cb) && cb(msg); return true
}, },
}) })
})()

View File

@ -1,3 +1,31 @@
fieldset.Search { padding:var(--plugin-padding); position:fixed; left:var(--project-width); top:var(--header-height); } fieldset.Search {
fieldset.Search>div.output>div.profile { max-width:unset; } background:#041a25bd; padding:10px;
fieldset.Search>div.output table.content { width:100%; } left:0px; top:26px;
position:fixed;
display:none;
}
body.white fieldset.Search table {
color:white;
}
fieldset.Search input.word {
width:-webkit-fill-available;
}
fieldset.Search div.output {
overflow:auto;
}
fieldset.Search div.output div.content {
overflow:auto;
}
fieldset.Search div.output div.content a {
color:yellow;
}
fieldset.Search div.output div.content table {
min-width:400px;
}
fieldset.Search div.output div.display {
max-height:200px;
overflow:auto;
}
fieldset.Search div.output div.profile {
overflow:auto;
}

View File

@ -1,76 +1,118 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
_init: function(can, msg) { can.onmotion.clear(can, can.ui.content) can.list = msg.Table(), can.onmotion.clear(can, can.ui.content)
var table = can.onappend.table(can, msg, function(value, key, index, data) { return {text: [can.base.isFunc(value) && value.help || value, html.TD], onclick: function(event) { var table = can.onappend.table(can, msg, function(value, key, index, line, array) { can.Status(mdb.TOTAL, index+1)
can.page.tagis(event.target, html.A) || can.onaction[can.db.type == mdb.FOREACH || event.ctrlKey? mdb.PLUGIN: mdb.SELECT](event, can, data) return {text: [key == mdb.TEXT && can.base.isFunc(line.text) && line.text.help || value, html.TD], onclick: function(event) {
}} }, can.ui.content, msg.append); can.onmotion.story.auto(can), can.onimport._size(can) can.onaction[can.type == "*"||event.ctrlKey? chat.PLUGIN: mdb.SELECT](event, can, index)
can.onmotion.toggle(can, can._status, can.db.type != mdb.FOREACH) && can.onappend._status(can, can.base.Obj(msg.Option(ice.MSG_STATUS), []).concat({name: mdb.SELECT, value: "0"})) }}
can.onmotion.focus(can, can.ui.filter), msg.Length() == 1 && can.ui.profile.innerHTML == "" && can.page.Select(can, table, html.TD)[0].click() }, can.ui.content, can.core.List((msg.Option("sort")||"ctx,cmd,type,name,text").split(ice.FS), function(item) {
return list.indexOf(item)
})); table && can.page.Modify(can, can.ui.display, {style: {width: table.offsetWidth}})
can.onappend._status(can, can.base.Obj(msg.Option("_status"), []).concat({name: "selected", value: "0"}))
can.getActionSize(function(msg, height) {
can.page.Modify(can, can.ui.profile, kit.Dict(html.MAX_HEIGHT, height-(table&&table.offsetHeight||0)))
})
msg.Length() == 1 && can.page.Select(can, table, html.TD)[0].click()
}, },
_size: function(can) { can.ui && can.ui.content && can.getActionSize(function(left, top, width, height) { _word: function(can, msg, cmds, fields) { can.type = cmds[0]
can.page.style(can, can._target, {left: left||0, top: top||0, width: width}) var cb = can.onaction[cmds[1]]; if (cb) { cb({}, can); return }
can.page.style(can, can._output, html.MAX_HEIGHT, height -= 2*10+(can.user.isMobile? 2: 1)*html.ACTION_HEIGHT+can.onexport.statusHeight(can))
can.core.List([can.ui.content, can.ui.display], function(target) { can.page.style(can, target, html.MAX_WIDTH, can.ConfWidth(width-2*10)) }) var res = can.request({}, {
can.ConfHeight(can.base.Min(height-can.ui.content.offsetHeight-can.ui.display.offsetHeight, height/2)) word: cmds, fields: fields.join(ice.FS), sort: msg.Option("sort"),
}) }, river: msg.Option(chat.RIVER), index: msg.Option("index"),
_input: function(can, msg, arg, fields) { if (can.base.contains(arg[1], ";")) { arg = can.core.Split(arg[1], "\t ;", "\t ;") } })
can.run(can.request({}, {fields: fields.join(mdb.FS)}, msg), arg, function(res) { can.db.type = arg[0]
res.Option(ice.ARG, arg), can.onengine.signal(can, chat.ONSEARCH, res), can.onimport._init(can, res) can.onengine.signal(can, chat.ONSEARCH, res)
}), can.onmotion.toggle(can, can._target, true) can.run(res._event, cmds, function(res) { can.onimport._init(can, res, fields) })
can.onmotion.show(can), can.onmotion.focus(can, can.ui.word)
}, },
select: function(can, msg, cmds, cb) { can.ui.filter.value = cmds[1], can.ui.input = function(event, word) { cmds[1] = word||cmds[1]; can.onimport._input(can, msg, cmds, fields) }
var fields = (cmds[2]||msg.Option(ice.MSG_FIELDS)||"ctx,cmd,type,name,text").split(mdb.FS); can.page.Appends(can, can.ui.display, [{th: fields}]), can.onmotion.hidden(can, can.ui.display), can.onmotion.clear(can, can.ui.profile) select: function(can, msg, cmds, cb) { can.ui.word.value = cmds[1]
can.ui.done = function() { can.base.isFunc(cb) && cb(can.onexport.select(can)), can.onmotion.hidden(can) }, can.db = {}, can._plugins = [], can.onimport._input(can, msg, cmds, fields) var fields = (cmds[2]||msg.Option(ice.MSG_FIELDS)||"ctx,cmd,type,name,text").split(ice.FS)
can.page.Appends(can, can.ui.display, [{th: fields}]), can.cb = function() {
can.base.isFunc(cb) && cb(can.onexport.select(can)), can.onmotion.hide(can)
}
can.input = function(event, word) { cmds[1] = word||cmds[1]
can.onimport._word(can, msg, cmds, fields)
}, can.onimport._word(can, msg, cmds, fields)
can.getActionSize(function(msg, top, left, width, height) {
can.page.Modify(can, can._target, {style: {top: top, left: left}})
can.page.Modify(can, can._output, {style: kit.Dict(html.MAX_HEIGHT, height-71, html.MAX_WIDTH, width)})
})
}, },
}) })
Volcanos(chat.ONACTION, {_init: function(can) { can.onmotion.hidden(can) }, list: [cli.CLOSE, web.CLEAR, cli.DONE], Volcanos("onaction", {help: "交互操作", list: [cli.CLEAR, cli.CLOSE, cli.DONE], _init: function(can, cb, target) {
onsize: function(can, msg, height, width) { can.onimport._size(can), can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth(), true) }) }, can.onmotion.hidden(can, can._target)
onlogin: function(can, msg) { can.ui = can.page.Append(can, can._output, [chat.CONTENT, {view: [[chat.DISPLAY, chat.CONTENT], html.TABLE]}, chat.PROFILE]) can.base.isFunc(cb) && cb()
can.onappend._action(can, (can.Conf(html.ACTION)||can.onaction.list).concat({type: html.TEXT, _className: "args trans", name: html.FILTER, icon: icon.search, _init: function(target) { can.ui.filter = target }, onkeydown: function(event) {
if (event.key == code.ESCAPE) { return event.target.blur() }
if (event.key == code.ENTER) { can.onkeymap.prevent(event); if (event.shiftKey) { return can.page.SelectOne(can, can.ui.content, [html.TBODY, html.TR, html.TD], function(target) { target.click() }) }
return event.ctrlKey? can.onaction.done(event, can): can.ui.input(event, event.target.value)
} if (event.ctrlKey) { return event.key == "0"? can.onaction.clear(event, can): can.onkeymap.selectCtrlN(event, can, can.ui.content, [html.TBODY, html.TR], function(target) { target.firstChild.click() }) }
event.key.length == 1 && can.onmotion.delayOnce(can, function() {
can.onmotion.tableFilter(can, can.ui.content, event.target.value)
}, 100, can._delay_filter = can._delay_filter||[])
}}), null, null, null, 10)
var key = can.misc.Search(can, "_search"); key && can.onmotion.delay(can, function() { can.onaction.onopensearch(can, can.request({}), "*", key) }, 1000)
}, },
onopensearch: function(can, msg, type, word) { can.onimport.select(can, msg, [type||mdb.FOREACH, word||""]) }, onlogin: function(can, msg) {
close: function(event, can) { can.onmotion.hidden(can) }, can.onappend._action(can, can.Conf(html.ACTION)||can.onaction.list)
can.ui = can.page.Append(can, can._output, [
{input: ["word", function(event) { can.onkeymap.input(event, can)
if (event.key == lang.ESCAPE) { can.onmotion.hide(can) }
if (event.key == lang.ENTER) { can.onkeymap.prevent(event)
if (event.shiftKey) { var first = can.page.Select(can, can.ui.content, html.TR)[1]
return can.onaction[can.type == "*"? chat.PLUGIN: html.SELECT](event, can, first.dataset.index)
}
if (event.ctrlKey) { return can.onaction[cli.DONE](event, can) }
can.input(event, event.target.value)
}
can.page.Select(can, can.ui.content, html.TR, function(tr, index) {
if (index == 0) { return }
var has = false; can.page.Select(can, tr, html.TD, function(td) {
has = has || td.innerText.indexOf(event.target.value) > -1
})
can.page.ClassList.set(can, tr, html.HIDDEN, !has)
})
}]},
{view: chat.CONTENT}, {view: html.STATUS}, {view: [chat.DISPLAY, html.TABLE]},{view: chat.PROFILE},
]), can.page.ClassList.add(can, can.ui.display, chat.CONTENT)
},
onopensearch: function(can, msg, type, word) { can.onimport.select(can, msg, [type||"*", word||""]) },
clear: function(event, can) { can.onmotion.clear(can, can.ui.profile) }, clear: function(event, can) { can.onmotion.clear(can, can.ui.profile) },
done: function(event, can) { can.base.isFunc(can.ui.done) && can.ui.done() }, done: function(event, can) { can.base.isFunc(can.cb) && can.cb() },
select: function(event, can, data) { if (can.base.isFunc(data.text)) { return can.onmotion.hidden(can), data.text(event) } close: function(event, can) { can.onmotion.hide(can) },
function show() { can.page.style(can, can.ui.content, html.MAX_HEIGHT, "")
can.page.style(can, can.ui.content, html.MAX_HEIGHT, can._output.offsetHeight-can.ui.display.offsetHeight) select: function(event, can, index) { var line = can.list[index]
can.Status(mdb.SELECT, can.page.Select(can, can.ui.display, html.TR).length-1) if (can.base.isFunc(line.text)) { return can.onmotion.hide(can), line.text(event) }
if (line.ctx == "web.chat" && line.cmd == "/search") {
return can.onimport.select(can, msg, [line.type, line.name, line.text], can.cb)
} }
var fields = can.page.Select(can, can.ui.display, html.TH, function(item) { return item.innerText }); can.onmotion.toggle(can, can.ui.display, true)
var ui = can.page.Append(can, can.ui.display, [{td: can.core.List(fields, function(item) { return data[item] }), onclick: function(event) { var fields = can.page.Select(can, can.ui.display, html.TH, function(item) { return item.innerText })
can.page.Remove(can, ui._target), show() can.page.Append(can, can.ui.display, [{td: can.core.List(fields, function(item) {
}}]); show() return line[item]
}), data: {index: index}, onclick: function(event) { can.page.Remove(can, event.target.parentNode)
can.Status("selected", can.page.Select(can, can.ui.display, html.TR).length-1)
}}]), can.Status("selected", can.page.Select(can, can.ui.display, html.TR).length-1)
}, },
plugin: function(event, can, data) { if (can.base.isFunc(data.text)) { return can.onmotion.hidden(can), data.text(event) }
var cmd = data.cmd == ctx.COMMAND? can.core.Keys(data.type, data.name.split(lex.SP)[0]): can.core.Keys(data.ctx, data.cmd) plugin: function(event, can, index) { var line = can.list[index]
var meta = {type: chat.STORY, index: cmd||msg.Option(mdb.INDEX), args: cmd == web.WIKI_WORD? [data.name]: []} if (can.base.isFunc(line.text)) { return can.onmotion.hide(can), line.text(event) }
if (data.type == cli.OPENS) { return can.runAction(event, cli.OPENS, [data.text], null, true) }
if (data.type == ssh.SHELL) { meta = {index: web.CODE_XTERM, args: [data.text]} } var cmd = line.cmd == ctx.COMMAND? can.core.Keys(line.type, line.name.split(ice.SP)[0]): can.core.Keys(line.ctx, line.cmd)
if (data.type == ctx.INDEX) { meta = {index: data.text.split(mdb.FS)[0], args: data.text.split(mdb.FS).slice(1) } } can.onappend.plugin(can, {type: chat.PLUGIN, index: cmd||msg.Option(mdb.INDEX)}, function(sub, meta) {
if (data.type == nfs.FILE) { meta = {index: web.CODE_VIMER, args: can.misc.SplitPath(can, data.text)} } can.getActionSize(function(msg, height, width) { height -= can.ui.content.offsetHeight+204
if (data.type == nfs.SHY) { meta = {index: web.WIKI_WORD, args: data.text} } can.page.Modify(can, sub._output, {style: kit.Dict(html.MAX_HEIGHT, height-26, html.MAX_WIDTH, width-40)})
if (data.type == ice.CMD) { meta = {index: data.name, args: can.core.Split(data.text)} } sub.Conf(html.HEIGHT, height+28), sub.Conf(html.WIDTH, width-60)
function plugin(meta) { can.onappend.plugin(can, meta, function(sub) { can._plugins = (can._plugins||[]).concat(sub) })
can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, can.ui.profile) }, 500)
sub.onimport.size(sub, can.ConfHeight(), can.ConfWidth()-1, true) sub.run = function(event, cmds, cb) { var msg = can.request(event)
}, can.ui.profile) } can.run(event, can.misc.concat(can, [ctx.ACTION, ice.RUN, meta.index], cmds), cb, true)
if (data.ctx == ice.NFS && data.cmd == nfs.PACK) { var ls = can.misc.SplitPath(can, data.text) }
can.runAction(event, ctx.RUN, [web.CODE_VIMER, ctx.ACTION, mdb.RENDER, data.type, ls[1], ls[0]], function(msg) { }, can.ui.profile)
msg.Table(function(meta) { plugin(meta) }), can.onappend.board(can, msg.Result(), can.ui.profile) })
} else {
plugin(meta)
}
}, },
}) })
Volcanos(chat.ONEXPORT, {statusHeight: function(can) { return can.db && can.db.type == mdb.FOREACH? 0: html.ACTION_HEIGHT }, Volcanos("onexport", {help: "导出数据", list: [],
select: function(can) { return can.page.Select(can, can.ui.display, html.TR, function(tr) { return can.page.Select(can, tr, html.TD, function(td) { return td.innerHTML }) }).slice(1) }, select: function(can) {
return can.page.Select(can, can.ui.display, html.TR, function(tr) {
return can.page.Select(can, tr, html.TD, function(td) { return td.innerHTML })
}).slice(1)
},
}) })

View File

@ -1,17 +1,36 @@
Volcanos(chat.ONACTION, { Volcanos("onaction", {help: "控件交互", list: [], _init: function(can, meta, cb, target) {
run: function(event, can) { can.run(can.request(event, {_method: http.POST})) }, refresh: function(event, can) { can.run(can.request(event, {_method: http.GET})) }, can.base.isFunc(cb) && cb(); switch (meta.type) {
list: function(event, can) { can.sup.isSimpleMode() || can.run(can.request(event, {_toast: event.isTrusted? ice.PROCESS: "" , _method: http.GET})) }, back: function(event, can) { can.sup.onimport.back(event, can.sup) }, case html.SELECT: meta.value && (target.value = meta.value); break
onclick: function(event, can) { can.Conf(mdb.TYPE) == html.BUTTON && can.run(event, [ctx.ACTION, can.Conf(mdb.NAME)].concat(can.sup.Input())), can.onkeymap.prevent(event) }, case html.BUTTON: meta.action == ice.AUTO && target.click(); break
onchange: function(event, can) { if (can.Conf(mdb.TYPE) != html.SELECT) { return } }
can.sup.onexport.session && can.sup.onexport.session(can.sup, "action:"+can.Conf(mdb.NAME), event.target.value)
can.run(can.request(event, {_toast: event.isTrusted? can.user.trans(can, ice.PROCESS, "处理"): "" , _method: http.GET}))
}, },
onkeydown: function(event, can) { can.onkeymap.input(event, can, event.target); if (can.Conf(mdb.TYPE) == html.TEXTAREA && !event.ctrlKey) { return } run: function(event, can) {
if (event.key == code.ENTER) { return can.onkeymap.prevent(event), can.run(event), can.onmotion.focus(can, event.target) } var title = can.sup._name+ice.SP+can.sup.Input([], true)
if (!event.ctrlKey) { return } switch (event.key) { var toast = can.user.toast(can, "执行中...", title, -1)
case "m": can.CloneField(); break can.run(event, [], function() { toast.close(), can.user.toastSuccess(can) })
},
list: function(event, can) { can.run(event) },
back: function(event, can) { can.sup.onimport._back(can.sup) },
refresh: function(event, can) { can.run(event) },
onclick: function(event, can) {
if (can.Conf(mdb.TYPE) == html.BUTTON) { can.run(event, [ctx.ACTION, can.Conf(mdb.NAME)].concat(can.sup.Input())) }
},
onchange: function(event, can) {
if (can.Conf(mdb.TYPE) == html.SELECT) { can.run(event) }
},
onkeydown: function(event, can) { can.onkeymap.input(event, can, event.target)
if (can.Conf(mdb.TYPE) == html.TEXTAREA) { if (!event.ctrlKey) { return } }
if (event.key == lang.ENTER) {
can.run(event), can.onmotion.focus(can, event.target)
can.onkeymap.prevent(event)
} if (!event.ctrlKey) { return }
switch (event.key) {
case "b": can.CloneInput(); break case "b": can.CloneInput(); break
default: can.onkeymap.selectOutput(event, can.sup); return case "m": can.CloneField(); break
default: return
} can.onkeymap.prevent(event) } can.onkeymap.prevent(event)
}, },
}) })

View File

@ -1,54 +0,0 @@
Volcanos(chat.ONFIGURE, {color: {
_load: function(event, can, cb, target, name, value) {
if (target._done && target.value) { return can.onmotion.hidden(can, can._target, can.Status("total") > 0)} target._done = true
can.onmotion.focus(can, target), can.onmotion.hidden(can, can._target)
can.runAction(event, mdb.INPUTS, [name, value||""], function(msg) {
name == ctx.INDEX && can.core.Item(can.onengine.plugin.meta, function(key) { msg.Push(ctx.INDEX, can.core.Keys(ice.CAN, key)) })
can._show(can, msg, cb, target, name)
})
},
_show: function(can, msg, cb, target, name) {
if (msg.Length() == 0 || msg.Length() == 1 && msg.Append(name) == target.value && target.value != "") { return can.onmotion.hidden(can) }
if (can.base.isIn(msg.append[msg.append.length-1], ctx.ACTION, "cb")) { msg.append = msg.append.slice(0, -1) } var list = {}
msg.Option(ice.TABLE_CHECKBOX, "")
can.onmotion.clear(can), can.onappend.table(can, msg, function(value, key, index, item) { value = item[key]
if (msg.append.length == 1 && index < 100 && list[value]) { return } list[value] = true
return {text: [value, html.TD, value == ""? html.HR: ""], style: msg.append && msg.append.length == 1? kit.Dict(html.MIN_WIDTH, target.offsetWidth-16): {}, onclick: function(event) {
can.page.style(can, target, html.BACKGROUND_COLOR, value)
can.close(); if (msg.cb && msg.cb[index]) { return msg.cb[index](value) }
var _cb = can.Conf("select"); if (_cb) { return _cb(target.value = value) } can.base.isFunc(cb) && cb(can, value, target.value)
}, _init: function(target) {
if (key == mdb.NAME) {
can.page.style(can, target.parentNode, html.BACKGROUND_COLOR, value)
}
}}
})
can.showIcons = function(value, icons, title) { can.ui = can.ui||{}
if (!can.ui.img) {
can.ui.img = can.page.insertBefore(can, [{type: html.IMG}], target)
can.ui.span = can.page.insertBefore(can, [{type: html.SPAN}], target)
can.onappend.style(can, mdb.ICONS, can.page.parentNode(can, target, html.TR))
can.page.style(can, target, html.COLOR, html.TRANSPARENT)
target._clear = function() { can.ui.img.src = can.misc.Resource(can, "usr/icons/icebergs.png"), can.ui.span.innerHTML = "" }
}
can.ui.img.src = can.misc.Resource(can, icons), can.ui.span.innerText = title||value
target.value = value, can.onmotion.hidden(can, can._target)
}
can.core.CallFunc([can.oninputs, "_show"], {event: event, can: can, msg: msg, target: target, name: name})
var style = msg.Option(ice.MSG_DISPLAY)? can.base.ParseURL(msg.Option(ice.MSG_DISPLAY)).style||name: name
can.core.CallFunc([can.sup.sub, "oninputs", style], {event: event, can: can, msg: msg, target: target, name: name})
can.layout(msg)
},
onfocus: function(event, can, meta, target, cbs, mod) { meta._force && mod.onclick(event, can, meta, target, cbs) },
onclick: function(event, can, meta, target, cbs) { (target.value == "" || meta._force) && cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return }
sub.sup = can._fields? can.sup: can
meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value)
}) },
onblur: function(event, can, sub, cb) { sub && can.onmotion.delay(can, sub.close, 300) },
onkeyup: function(event, can, meta, cb, target, sub, last) { if (event.key == code.TAB) { return }
if (event.key == code.ENTER) { return meta._enter && (!can.page.tagis(event.target, html.TEXTAREA) || event.ctrlKey) && meta._enter(event, target.value)? sub && sub.close(): last(event) }
if (!sub) { return } can.onmotion.toggle(can, sub._target, true)
sub.hidden() || can.onkeymap.selectCtrlN(event, can, sub._output, "tr:not(.hidden)>td:first-child", function(td) { return meta.select && (sub.close(), meta.select(target.value = td.innerText)), cb(sub, td.innerText, target.value), td })
|| can.onmotion.delayOnce(can, function() { can.onkeymap.selectInputs(event, sub, function() { sub._load(event, sub, cb, target, meta.name) }, target) }, target.value.length < 3? 500: 150)
},
}})

13
plugin/input/date.css Normal file
View File

@ -0,0 +1,13 @@
fieldset.input.date div.action div.space {
clear:both; width:0;
}
fieldset.input.date div.output td.prev {
color:gray;
}
fieldset.input.date div.output td.next {
color:gray;
}
fieldset.input.date div.output td {
padding:2px 12px;
}

View File

@ -1,47 +1,60 @@
Volcanos(chat.ONFIGURE, {date: { Volcanos("onfigure", {help: "控件详情", list: [], date: {onclick: function(event, can, meta, cb, target) { cb(function(can, cbs) {
onclick: function(event, can, meta, target, cbs) { cbs(function(can, cb) { if (can._output.innerHTML) { return } function set(now) { target.value = can.user.time(can, now), can.close(), meta && meta.action == ice.AUTO && can.run({}) }
const TODAY = "today", YEAR = "year", MONTH = "month", HOUR = "hour", MINUTE = "minute", SECOND = "second"
var today = new Date(), now = can.base.Date((target.value||"").trim()); function _cb(_now) { cb(can, can.user.time(can, now = _now), target.value) } // 添加控件
can.base.Copy(can._trans, kit.Dict(TODAY, "今天", mdb.NEXT, "下一月", mdb.PREV, "上一月")) var now = target.value? new Date(target.value): new Date()
var meta = kit.Dict(cli.CLOSE, function() { can.close() }, can.onmotion.clear(can, can._action), can.onappend._action(can, [cli.CLOSE,
HOUR, function(event, can, button, value) { now.setHours(parseInt(value)||0), show(now) }, ["hour"].concat(can.core.List(24)), ["minute"].concat(can.core.List(0, 60, 5)), ["second"].concat(can.core.List(0, 60, 5)),
MINUTE, function(event, can, button, value) { now.setMinutes(parseInt(value)||0), show(now) }, "今天", "", "上一月", ["year"].concat(can.core.List(now.getFullYear() - 10, now.getFullYear() + 10)),
SECOND, function(event, can, button, value) { now.setSeconds(parseInt(value)||0), show(now) }, ["month"].concat(can.core.List(1, 13)), "下一月",
TODAY, function() { show(today) }, ], can._action, { close: function(event) { can.close() },
mdb.PREV, function() { now.setMonth(now.getMonth()-1), show(now) }, "hour": function(event, can, key, value) { now.setHours(parseInt(value)||0), show(now) },
YEAR, function(event, can, button, value) { now.setFullYear(parseInt(value)), show(now) }, "minute": function(event, can, key, value) { now.setMinutes(parseInt(value)||0), show(now) },
MONTH, function(event, can, button, value) { now.setMonth(parseInt(value)-1), show(now) }, "second": function(event, can, key, value) { now.setSeconds(parseInt(value)||0), show(now) },
mdb.NEXT, function() { now.setMonth(now.getMonth()+1), show(now) } "今天": function(event) { now = new Date(), set(show(now)) },
)
var ui = can.page.Append(can, can._action, ["time", "date"]) "上一月": function(event) { now.setMonth(now.getMonth()-1), show(now) },
can.onappend._action(can, [cli.CLOSE, [HOUR].concat(can.core.List(24)), [MINUTE].concat(can.core.List(0, 60, 5)), [SECOND].concat(can.core.List(0, 60, 5)), TODAY], ui.time, meta) "year": function(event, can, key, value) { now.setFullYear(parseInt(value)), show(now) },
can.onappend._action(can, [mdb.PREV, [YEAR].concat(can.core.List(now.getFullYear() - 10, now.getFullYear() + 10)), [MONTH].concat(can.core.List(1, 13)), mdb.NEXT], ui.date, meta) "month": function(event, can, key, value) { now.setMonth(parseInt(value)-1), show(now) },
can._table = can.page.Appends(can, can._output, [{view: [chat.CONTENT, html.TABLE], list: [{type: html.TBODY}]}]).tbody "下一月": function(event) { now.setMonth(now.getMonth()+1), show(now) },
can.page.Append(can, can._output, [{text: "请先选择时间,再选择日期"}])
target.value == "" && (now.setMinutes(now.getMinutes()>30? 30: 0), now.setSeconds(0)) "随机": function(event) { now.setDate((Math.random() * 100 - 50) + now.getDate()), show(now) },
function show(now) { can.Action(YEAR, now.getFullYear()), can.Action(MONTH, now.getMonth()+1) "前一年": function(event) { now.setFullYear(now.getFullYear()-1), show(now) },
can.Action(HOUR, now.getHours()), can.Action(MINUTE, parseInt(now.getMinutes()/30)*30), can.Action(SECOND, 0) "后一年": function(event) { now.setFullYear(now.getFullYear()+1), show(now) },
can.page.Appends(can, can._table, can.date.List(can, function(event, day) { })
day.setHours(can.Action(HOUR)), day.setMinutes(can.Action(MINUTE)), day.getSeconds(can.Action(SECOND)), _cb(day), can.close()
}, now)) can.onmotion.clear(can, can._status)
var l = can.date.solar2lunar(now); can.page.Appends(can, can._status, [{view: "today", inner: [l.gzYear, l.Animal+"年", l.cnMonth, l.cnDay, l.lunarFestival||l.festival||l.Term, l.Astro].join(lex.SP)}]) can._table = can.page.Appends(can, can._output, [{view: [chat.CONTENT, html.TABLE]}]).first
return now var today = new Date(); function show(now) {
} show(now), can._show = function(d) { d? _cb(show(now = new Date(now.getTime()+d*24*3600*1000))): _cb(show(now)) } // 设置控件
})}, can.Action("year", now.getFullYear())
onfocus: function(event, can, meta, target, cbs, mod) { can.Action("month", now.getMonth()+1)
if (target._selectonly) { can.onmotion.delay(can, function() { target.blur() }) } can.Action("hour", now.getHours())
}, can.Action("minute", parseInt(now.getMinutes()/5)*5)
onblur: function(event, can, sub, cb, target) { can.Action("second", parseInt(now.getSeconds()/5)*5)
if (target._selectonly) { return }
}, // 设置组件
onkeydown: function(event, can, meta, cb, target, sub, last) { if (sub && sub.hidden()) { return last(event) } switch (event.key) { can.page.Appends(can, can._table, [{th: ["日", "一", "二", "三", "四", "五", "六"]}])
case "n": can.page.SelectInput(can, sub._action, mdb.NEXT, function(target) { target.click(), sub._show() }); break var tr; function add(day, type) { if (day.getDay() == 0) { tr = can.page.Append(can, can._table, [{type: html.TR}]).last }
case "p": can.page.SelectInput(can, sub._action, mdb.PREV, function(target) { target.click(), sub._show() }); break can.page.Append(can, tr, [{text: [day.getDate(), html.TD, can.base.Time(today, "%y-%m-%d") == can.base.Time(day, "%y-%m-%d")? html.SELECT: type],
case "t": can.page.SelectInput(can, sub._action, "today", function(target) { target.click(), sub._show() }); break dataset: {date: day.getTime()}, onclick: function(event) {
case "j": sub._show(7); break set(now = new Date(parseInt(event.target.dataset.date)))
case "k": sub._show(-7); break },
case "h": sub._show(-1); break }])
case "l": sub._show(1); break }
default: last(event); return
} can.onkeymap.prevent(event) }, // 时间区间
} }) var one = new Date(now); one.setDate(1)
var end = new Date(now); end.setMonth(now.getMonth()+1), end.setDate(1)
var head = new Date(one); head.setDate(one.getDate()-one.getDay())
var tail = new Date(end); tail.setDate(end.getDate()+7-end.getDay())
// 时间序列
for (var day = new Date(head); day < one; day.setDate(day.getDate()+1)) { add(day, mdb.PREV) }
for (var day = new Date(one); day < end; day.setDate(day.getDate()+1)) { add(day, mdb.MAIN) }
for (var day = new Date(end); end.getDay() != 0 && day < tail; day.setDate(day.getDate()+1)) { add(day, mdb.NEXT) }
return now
} show(now), can.onlayout.figure(event, can), can.base.isFunc(cbs) && cbs(can)
})}} }, [""])

View File

@ -1,31 +0,0 @@
Volcanos(chat.ONFIGURE, {icon: {
_load: function(event, can, cb, target, name, value) {
can.runAction(event, ctx.RUN, ["web.chat.icon"], function(msg) { can._show(can, msg, cb, target, name) })
},
_show: function(can, msg, cb, target, name) { can.onmotion.clear(can)
var table = can.page.Append(can, can._output, [{type: html.TABLE}])._target, tr
msg.Table(function(value, index) { if (index%10 == 0) { tr = can.page.Append(can, table, [{type: html.TR}])._target }
can.page.Append(can, tr, [{type: html.TD, inner: value.icon, title: value.name, onclick: function() {
can.close(), can.base.isFunc(cb) && cb(can, value.name, target.value)
target._icon.className = value.name
}}])
}), can.layout(msg)
},
onfocus: function(event, can, meta, target, cbs, mod) { meta._force && mod.onclick(event, can, meta, target, cbs) },
onclick: function(event, can, meta, target, cbs) { cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return }
target._icon = target._icon || can.page.insertBefore(can, [{type: "i"}], target)
meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value)
}) },
onblur: function(event, can, sub, cb) { sub && can.onmotion.delay(can, sub.close, 300) },
onkeyup: function(event, can, sub, cb) { if (!sub) { return }
can.page.Select(can, sub._output, html.TD, function(target) {
can.onmotion.hidden(can, target, target.title.indexOf(event.target.value) > -1)
})
can.page.Select(can, sub._output, html.TR, function(target) {
can.onmotion.hidden(can, target, can.page.Select(can, target, html.TD, function(target) {
if (!can.page.ClassList.has(can, target, html.HIDE)) { return target }
}).length > 0)
})
},
}})

View File

@ -1,18 +0,0 @@
Volcanos(chat.ONFIGURE, {icons: {
_load: function(event, can, cb, target, name, value) {
can.runAction(event, mdb.INPUTS, [mdb.ICONS], function(msg) { can._show(can, msg, cb, target, name) })
},
_show: function(can, msg, cb, target, name) { var table = can.page.Appends(can, can._output, [{type: html.TABLE}])._target, tr
msg.Table(function(value, index) { if (index%5 == 0) { tr = can.page.Append(can, table, [{type: html.TR}])._target }
can.page.Append(can, tr, [{type: html.TD, title: value.icons, list: [{img: can.misc.Resource(can, value.icons), style: {width: 60, height: 60}}], onclick: function() {
can.close(), can.base.isFunc(cb) && cb(can, value.icons, target.value), target._icon.src = can.misc.Resource(can, value.icons)
}}])
}), can.layout(msg)
},
onfocus: function(event, can, meta, target, cbs, mod) { meta._force && mod.onclick(event, can, meta, target, cbs) },
onclick: function(event, can, meta, target, cbs) { cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return }
target._icon = target._icon || can.page.insertBefore(can, [{img: can.misc.Resource(can, "usr/icons/icebergs.png") }], target)
meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value)
}) },
onblur: function(event, can, sub, cb) { sub && can.onmotion.delay(can, sub.close, 300) },
}})

View File

@ -1,19 +0,0 @@
Volcanos(chat.ONFIGURE, {img: {
_init: function(can, meta, target) { target.value == meta.value && (target.value = ""); var images = can.core.Split(target.value)
var count = parseInt(meta.value||"1"), width = target.parentNode.offsetWidth; for (var n = 1; n < 10; n++) { if (n*n >= count) { width = (width/n-10); break } }
// function add(target, hash) { target._hash = hash, can.page.Appends(can, target, [{img: can.base.MergeURL(can.misc.MergeURL(can, {_path: web.SHARE_CACHE+hash}, true), {pod: meta.space||undefined}), height: width, width: width}]) }
function add(target, hash) { target._hash = hash, can.page.Appends(can, target, [{img: hash, height: width, width: width}]) }
function set() { target.value = can.page.SelectChild(can, target.parentNode, html.DIV, function(target) { return target._hash }).join(mdb.FS) }
can.onmotion.hidden(can, target), can.onappend.style(can, html.FLEX, target.parentNode)
for (var i = 0; i < count; i++) {
can.page.Append(can, target.parentNode, [{view: html.FLEX, style: {
"clear": i%n == 0? "both": "none", height: width, width: width,
}, _init: function(target) {
if (images[i] && images[i].length > 10) { add(target, images[i]) } else { can.page.Append(can, target, [{text: "+"}]) }
target.onclick = function(event) { can.misc.Event(event, can, function(msg) {
can.user.upload(event, can, function(msg) { add(target, msg.Result()), set() }, true)
})}
} }])
}
},
}})

View File

@ -1,79 +1,57 @@
Volcanos(chat.ONFIGURE, {key: { Volcanos("onfigure", {help: "控件详情", list: [], key: {
_load: function(event, can, cb, target, name, value) { _init: function(can, msg, target) { var call = arguments.callee
if (target._done && target.value) { return can.onmotion.hidden(can, can._target, can.Status("total") > 0)} target._done = true can.onmotion.clear(can), can.onappend.table(can, msg, function(value, key, index, line) {
can.onmotion.focus(can, target), can.onmotion.hidden(can, can._target) return {text: [value, html.TD], onclick: function(event) { target.value = line[key]
can.runAction(event, mdb.INPUTS, [name, value||""], function(msg) { if (msg.Option(ice.MSG_PROCESS) != ice.PROCESS_AGAIN) { return can.close() }
name == ctx.INDEX && can.core.Item(can.onengine.plugin.meta, function(key) { msg.Push(ctx.INDEX, can.core.Keys(ice.CAN, key)) }) can.run(event, [ctx.ACTION, mdb.INPUTS, can.Conf(mdb.NAME), target.value], function(msg) {
can._show(can, msg, cb, target, name) call(can, msg, target)
})
}}
}) })
}, },
_show: function(can, msg, cb, target, name) { _show: function(can, meta, cbs, target) {
// msg.Option(ice.TABLE_CHECKBOX, "") can.run(event, [ctx.ACTION, mdb.INPUTS, meta.name, target.value], function(msg) {
if (msg.Option(ice.TABLE_CHECKBOX) == ice.TRUE) { target._hold = true if (msg.Length() == 0) { return can.close() }
can.onappend._action(can, [html.CANCEL, html.CONFIRM, msg.Length() > 5? html.FILTER: ""], can._action, { target._can && target._can.close(), target._can = can
cancel: function() { can.onmotion.focus(can, target), can.onmotion.hidden(can, can._target) }, can.onfigure.key._init(can, msg, target), can.Status(mdb.TOTAL, msg.Length())
confirm: function() { var list = msg.Table() target._msg = msg, can.base.isFunc(cbs) && cbs(can)
can.base.isFunc(cb) && cb(can, can.page.Select(can, can._output, html.TR, function(target) { })
if (can.page.ClassList.has(can, target, html.SELECT)) {
return list[target.dataset.index][msg.append[0]] },
} onfocus: function(event, can, meta, cb, target) { if (target._figure) { return } target._figure = {}; cb(function(can, cbs) {
}).join(","), target.value) target._figure = can.onlayout.figure(event, can, can._target, false, {top: can.page.offsetTop(target)+target.offsetHeight, left: can.page.offsetLeft(target)})
can.onmotion.focus(can, target), can.onmotion.hidden(can, can._target) can.onfigure.key._show(can, meta, cbs, target), can.onmotion.focus(can, target)
}, target.click()
}) },
onblur: function(event, can, meta, cb, target) {
can.core.Timer(100, function() {
delete(target._figure), target._can && target._can.close()
})
},
onclick: function(event, can, meta, cb, target) { if (target._figure) { target._figure = can.onlayout.figure(event, can, can.core.Value(target, "_can._target")||{}); return } target._figure = {}; cb(function(can, cbs) {
target._figure = can.onlayout.figure(event, can)
can.onfigure.key._show(can, meta, cbs, target)
}) },
onkeydown: function(event, can, meta, cb, target, last) {
if (target._figure && target._can) { can = target._can
switch (event.key) { case lang.ENTER: can.close(); return }
can.onmotion.selectTableInput(event, can, target, function() {
can.run(event, [ctx.ACTION, mdb.INPUTS, meta.name, target.value], function(msg) {
can.onfigure.key._init(can, msg, target), can.Status(mdb.TOTAL, msg.Length())
target._msg = msg
})
}) })
} }
if (msg.Length() == 0 || msg.Length() == 1 && msg.Append(name) == target.value && target.value != "") { return can.onmotion.hidden(can) } switch (event.key) {
if (can.base.isIn(msg.append[msg.append.length-1], ctx.ACTION, "cb")) { msg.append = msg.append.slice(0, -1) } var list = {} case lang.ESCAPE: event.target.blur(); return
can.onmotion.clear(can), can.onappend.table(can.sup, msg, function(value, key, index, item) { value = item[key] case lang.TAB:
if (msg.append.length == 1 && index < 100 && list[value]) { return } list[value] = true if (event.target.tagName == "TEXTAREA") {
return {text: [value, html.TD, [value == ""? html.HR: "", key]], style: msg.append && msg.append.length == 1? kit.Dict(html.MIN_WIDTH, target.offsetWidth-16): {}, onclick: function(event) { can.onkeymap.insertText(event.target, "\t")
can.onengine.signal(can, "onevent", can.request(event)) can.onkeymap.prevent(event)
can.close(); if (msg.cb && msg.cb[index]) { return msg.cb[index](value) } return
var _cb = can.Conf("select"); if (_cb) { return _cb(target.value = value) } can.base.isFunc(cb) && cb(can, value, target.value) }
}, _init: function(target) {
can.onappend.style(can, "i-"+index, target.parentNode)
// can.onappend.style(can, "s-"+can.base.replaceAll(item[name], "/", "_"), target.parentNode)
}}
}, can._output)
can.showIcons = function(value, icons, title) { can.ui = can.ui||{}
if (!can.ui.img) {
can.ui.img = can.page.insertBefore(can, [{type: html.IMG}], target)
can.ui.span = can.page.insertBefore(can, [{type: html.SPAN}], target)
can.onappend.style(can, mdb.ICONS, can.page.parentNode(can, target, html.TR))
can.page.style(can, target, html.COLOR, html.TRANSPARENT)
target._clear = function() { can.ui.img.src = can.misc.Resource(can, "usr/icons/icebergs.png"), can.ui.span.innerHTML = "" }
}
can.ui.img.src = can.misc.Resource(can, icons), can.ui.span.innerText = title||value
target.value = value, can.onmotion.hidden(can, can._target)
} }
can.core.CallFunc([can.oninputs, "_show"], {event: event, can: can, msg: msg, target: target, name: name}) can.base.isFunc(last) && last(event, can)
var display = msg.Option(ice.MSG_DISPLAY)? can.base.ParseURL(msg.Option(ice.MSG_DISPLAY)): {name: name}
if (display.title && !msg[display.title]) { display.title = msg.append[1] }
display.style && can.core.CallFunc([can.sup.sub, "oninputs", display.style], {event: event, can: can, msg: msg, target: target, name: display.name||name, title: display.title})
can.layout(msg)
},
onfocus: function(event, can, meta, target, cbs, mod) {
// can.onengine.signal(can, "onevent", can.request(event));
if (target._selectonly) { can.onmotion.delay(can, function() { target.blur() }) }
meta._force && mod.onclick(event, can, meta, target, cbs)
},
onclick: function(event, can, meta, target, cbs) {
// can.onengine.signal(can, "onevent", can.request(event));
if (target._selectonly) { can.onmotion.delay(can, function() { target.blur() }) }
(target.value == "" || meta._force || target._selectonly) && cbs(function(sub, cb) { if (sub.Status(mdb.TOTAL) > 0) { return }
sub.sup = can._fields? can.sup: can
meta.msg && meta.msg.Length() > 0? sub._show(sub, meta.msg, cb, target, meta.name): sub._load(event, sub, cb, target, meta.name, target.value)
}) },
onblur: function(event, can, sub, cb, target) {
if (target._hold) { return }
if (target._selectonly) { return }
// can.onengine.signal(can, "onevent", can.request(event, {query: can.page.getquery(can, target)+","+target.value}))
sub && can.onmotion.delay(can, sub.close, 300)
},
onkeyup: function(event, can, meta, cb, target, sub, last) { if (event.key == code.TAB) { return }
if (event.key == code.ENTER) { return meta._enter && (!can.page.tagis(event.target, html.TEXTAREA) || event.ctrlKey) && meta._enter(event, target.value)? sub && sub.close(): last(event) }
if (!sub) { return } can.onmotion.toggle(can, sub._target, true)
sub.hidden() || can.onkeymap.selectCtrlN(event, can, sub._output, "tr:not(.hidden)>td:first-child", function(td) { return meta.select && (sub.close(), meta.select(target.value = td.innerText)), cb(sub, td.innerText, target.value), td })
|| can.onmotion.delayOnce(can, function() { can.onkeymap.selectInputs(event, sub, function() { sub._load(event, sub, cb, target, meta.name) }, target) }, target.value.length < 3? 500: 150)
}, },
}}) }})

View File

@ -1,27 +0,0 @@
fieldset.keyboard>div.output>br { clear:both; }
fieldset.keyboard>div.output>div.key {
font-size:24px; text-align:center;
background-color:green; color:white; padding:0; margin:5px;
height:40px; width:40px; float:left;
cursor:pointer;
}
fieldset.keyboard>div.output>div.key:hover { background-color:red; }
fieldset.keyboard>div.output>div.key.double { font-size:16px; white-space:pre; }
fieldset.keyboard>div.output>div.key.special { font-size:16px; background-color:red; }
fieldset.keyboard>div.output>div.key.special:hover { background-color:green; }
fieldset.keyboard>div.output>div.key.special.hold { background-color:green; }
fieldset.keyboard>div.output>div.key.tail { width:70px; }
fieldset.keyboard>div.output>div.key.Tab { width:60px; }
fieldset.keyboard>div.output>div.key.Ctrl { width:70px; }
fieldset.keyboard>div.output>div.key.Shift { width:90px; }
fieldset.keyboard>div.output>div.key.Cmd { width:60px; }
fieldset.keyboard>div.output>div.key.Alt { width:60px; }
fieldset.keyboard>div.output>div.key.Space { width:300px; }
fieldset.keyboard>div.output>div.key.Shift.tail { width:140px; }
fieldset.keyboard>div.output>div.key.Enter { width:110px; }
fieldset.keyboard>div.output>div.key.Backspace { width:90px; }
fieldset.keyboard>div.output>div.key>span { margin-top:2px; display:block; }
fieldset.keyboard>div.output>div.key.special>span { margin-top:10px; }
// table.content td input { width:50px; }
// body.mobile table.content td input { width:80px; }

View File

@ -1,54 +0,0 @@
Volcanos(chat.ONFIGURE, {keyboard: {
_init: function(can, meta, target) { can.onfigure.keyboard[target.value] && (target.value = "") },
onclick: function(can, meta, target, cbs) { cbs(function(sub) { var msg = can.request()
can.page.style(can, can._output, html.MIN_WIDTH, sub[meta.value||"_normal"](sub, msg))
can.onfigure.keyboard._show(sub, msg, target)
}) },
_show: function(can, msg, target) { can.require(["/plugin/input/keyboard.css"]), can.onmotion.clear(can, can._output)
msg.Table(function(item) { item.type == html.HEAD && can.page.Append(can, can._output, html.BR)
function add(value) { target.value += value, target.focus(), can.user.toast(can, value||item.name) }
function hold() { can.page.ClassList.add(can, div, "hold") }
var div = can.page.Append(can, can._output, [{view: item.type+lex.SP+item.name+(item.name.indexOf(lex.NL)>-1? " double": item.name.length>1? " special": ""), list: [{text: [item.name]}], onclick: function(event) {
switch (item.name) {
case web.CLEAR: target.value = "", target.focus(); break
case cli.CLOSE: can.close(); break
case code.ESC: can.close(); break
case code.CTRL: can._ctrl = !can._ctrl, hold(); break
case code.SHIFT: can._shift = !can._shift, hold(); break
case code.BACKSPACE: target.value = target.value.slice(0, -1), add(""); break
case code.ENTER: break
default: can._shift = can._shift||event.shiftKey
if (item.name == code.TAB) {
add(lex.TB)
} else if (item.name == code.SPACE) {
add(lex.SP)
} else if (item.name.indexOf(lex.NL) > -1) { var ls = can.core.Split(item.name, lex.NL, lex.NL, lex.NL)
add(can._shift? ls[0]: ls[1])
} else {
add(can._shift? item.name.toUpperCase(): item.name)
} can._shift = false, can._ctrl = false, can.page.Select(can, can._output, "div.hold", function(target) { can.page.ClassList.del(can, div, "hold") })
}
} }])._target
})
},
_number: function(can, msg) {
can.core.List([
["1", "2", "3"],
["4", "5", "6"],
["7", "8", "9"],
], function(list) { can.core.List(list, function(item, index) {
msg.Push(can.base.isObject(item)? item: {type: [mdb.KEY, (index == 0? html.HEAD: "")].join(lex.SP), name: item})
}) }); return 150
},
_normal: function(can, msg) {
can.core.List([[code.ESC, "close", "clear"],
["~\n`", "!\n1", "@\n2", "#\n3", "$\n4", "%\n5", "^\n6", "&\n7", "*\n8", "(\n9", ")\n0", "_\n-", "+\n=", code.BACKSPACE],
[code.TAB, "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "{\n[", "}\n]", "|\n\\"],
[code.CTRL, "a", "s", "d", "f", "g", "h", "j", "k", "l", ":\n;", "\"\n'", code.ENTER],
[code.SHIFT, "z", "x", "c", "v", "b", "n", "m", "<\n,", ">\n.", "?\n/", code.SHIFT],
[code.CTRL, code.CMD, code.ALT, code.SPACE, code.ALT, code.CMD, code.CTRL],
], function(list) { can.core.List(list, function(item, index) {
msg.Push(can.base.isObject(item)? item: {type: [mdb.KEY, index == 0? html.HEAD: index == list.length-1? "tail": ""].join(lex.SP), name: item})
}) }); return 750
}
}})

View File

@ -1,8 +1,9 @@
Volcanos(chat.ONFIGURE, {province: { Volcanos("onfigure", {help: "控件详情", list: [], province: {onclick: function(event, can, meta, cb, target) { cb(function(can, cbs) {
onclick: function(event, can, meta, target, cbs) { cbs(function(can, cb) { can.require(["/require/shylinux.com/x/echarts/echarts.js", "/require/shylinux.com/x/echarts/china.js"], function() {
can.require(["/require/shylinux.com/x/echarts/echarts.js", "/require/shylinux.com/x/echarts/china.js"], function() { var china_chart = echarts.init(can.page.Append(can, can._output, [{type: html.DIV, style: {width: 600, height: 400}}]).first)
var chart = echarts.init(can.page.Appends(can, can._output, [{type: html.DIV, style: {width: can.page.width()/2, height: can.page.height()/2}}])._target) china_chart.setOption({geo: {map: 'china'}}), china_chart.on(html.CLICK, function (params) {
chart.setOption({geo: {map: 'china'}}), chart.on(html.CLICK, function(params) { target.value = params.name, can.close() }) target.value = params.name, can.close()
}), can.onappend._action(can, [cli.CLOSE], can._action, {close: function() { can.close() }}) }), can.Status(mdb.TOTAL, 34), can.onlayout.figure(event, can), can.base.isFunc(cbs) && cbs(can)
}) }, })
}}) }) }}, })

View File

@ -1,13 +1,25 @@
fieldset.layout legend { display:none; } fieldset.div div.output td {
fieldset.layout fieldset.plugin { padding:0; margin:0; } vertical-align:top;
}
fieldset.div div.output td { vertical-align:top; } fieldset.div div.output fieldset.span>fieldset {
fieldset.div div.output fieldset.span>div.output>fieldset { overflow:auto; float:left; } float:left; overflow:auto;
}
fieldset.panel.cmd.main fieldset.div>legend { display:none; } fieldset.panel.cmd.main fieldset.div {
fieldset.panel.cmd.main fieldset.div>form.option { display:none; } padding:0;
fieldset.panel.cmd.main fieldset.div>div.action { display:none; } margin:0;
fieldset.panel.cmd.main fieldset.div div.project { display:none; } }
fieldset.panel.cmd.main fieldset.div div.profile { display:none; } fieldset.panel.cmd.main fieldset.div>legend {
fieldset.panel.cmd.main fieldset.div>div.status { display:none; } display:none;
}
fieldset.panel.cmd.main fieldset.div>form.option {
display:none;
}
fieldset.panel.cmd.main fieldset.div>div.action {
display:none;
}
fieldset.panel.cmd.main fieldset.div div.project {
display:none;
}
fieldset.panel.cmd.main fieldset.div div.profile {
display:none;
}

View File

@ -1,65 +1,95 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
var meta = {}; msg.Table(function(value) { meta[value.key] = value.value }) var meta = {}; msg.Table(function(value) { meta[value.key] = value.value })
can._list = can.base.Obj(meta.text, {meta: {name: meta.name||html.DIV}, list: []}) can._meta = can.base.Obj(meta.text, {meta: {name: meta.name||"hi"}, list: []})
can.sup._keys = can.sup._keys||can._list.meta.name
can.onimport.layout(can, can._output)
can.base.isFunc(cb) && cb(msg) can.base.isFunc(cb) && cb(msg)
},
_item: function(can, keys, item, target, width, height) { width = width||item.meta.width, height = height||item.meta.height
var ui = can.page.Append(can, target, [{view: [html.ITEM, html.DIV, item.meta.name||html.DIV], onclick: function(event) {
can.onmotion.select(can, can.ui.project, html.DIV_ITEM, event.target), can.current = event.target, can.onimport._profile(can, keys, item.meta)
}, _add: function(data) { item.list.push(data), can.onimport._list(can, keys, item, ui.list, width, height) }}, {view: html.LIST}])
var field = can.onappend.field(can, item.meta.index? chat.PLUGIN: html.LAYOUT, item.meta, target._target) can.ui = can.page.Appends(can, target, [{view: [chat.LAYOUT, html.TABLE], list: [{type: html.TR, list: [
can.page.style(can, ui.list._target = field.output, {width: width, height: height}) {type: html.TD, list: [{view: chat.PROJECT}]},
item.meta.style && can.page.ClassList.add(can, ui.list._target, item.meta.style) {type: html.TD, list: [{view: chat.DISPLAY}]},
{type: html.TD, list: [{view: chat.PROFILE}]},
]}] }]), can.ui.project._fieldset = can.ui.display
item.meta.index && can.onappend.plugin(can, can.base.Copy({}, item.meta), function(sub) { can.onimport._item(can, can._meta, can.ui.project, can.onimport._size(can)).click()
can.page.style(can, sub._output, {width: width, height: height-2*html.ACTION_HEIGHT})
}, target._target, field.fieldset)
can.onimport._list(can, keys, item, ui.list, width, height)
can.sup._keys == keys && ui.item.click()
}, },
_list: function(can, keys, item, target, width, height) { _size: function(can) {
if (item.meta.style == html.SPAN) { width = width / item.list.length } else { height = height / item.list.length } var width = can.Conf(html.WIDTH)-260, height = can.Conf(html.HEIGHT)-100
can.onmotion.clear(can, target), can.onmotion.clear(can, target._target) if (can.Conf("auto.cmd")) {
can.core.List(item.list, function(item) { can.onimport._item(can, can.core.Keys(keys, item.meta.name), item, target, width, height) }) width = can.Conf(html.WIDTH), height = can.Conf(html.HEIGHT)
}, can.onmotion.hidden(can, can.ui.project)
_profile: function(can, keys, meta) { can.onmotion.clear(can, can.ui.profile) can.onmotion.hidden(can, can.ui.profile)
var msg = can.request({}); msg.Push(mdb.KEY, "keys"), msg.Push(mdb.VALUE, keys) can.onmotion.hidden(can, can._option)
can.core.List(can.core.Split("name,index,args,style,display,height,width"), function(k) { can.onmotion.hidden(can, can._action)
msg.Push(mdb.KEY, k), msg.Push(mdb.VALUE, meta[k])
}), can.sup._keys = keys
can.onappend.table(can, msg, function(value, key, index, line, array) {
return {text: [value, html.TD], ondblclick: function(event) { var target = event.target
key == mdb.VALUE && can.onmotion.modify(can, event.target, function(event, value, old) {
target.innerText = meta[line.key] = value, can.onimport.layout(can)
}, {name: line.key})
}}
}, can.ui.profile)
},
layout: function(can, target) { target = target||can._output
can.onmotion.clear(can, target), can.onappend.layout(can, null, "", target), can.ui.project._target = can.ui.content
var width = can.ConfWidth()-320, height = can.ConfHeight()
if (can.isCmdMode()) {
width = can.page.width(), height = can.page.height(), can.user.title(can._list.meta.name)
} else if (can.isFullMode()) {
width = can.ConfWidth(), height = can.ConfHeight()
can.onmotion.toggle(can, can.ui.project, false)
} else {
can.onmotion.toggle(can, can.ui.profile, true)
} }
can.onimport._item(can, can._list.meta.name, can._list, can.ui.project, width, height) if (can.user.mod.isCmd || can.user.mod.isDiv) {
width = window.innerWidth, height = window.innerHeight
can.page.Modify(can, can._output, {style: {width: width, height: height}})
}
return width
}, },
}, [""]) _item: function(can, node, target, width) { width = width||node.meta.width
Volcanos(chat.ONACTION, { var ui = can.page.Append(can, target, [{view: [html.ITEM, html.DIV, node.meta.name||"hi"]}, {view: [html.LIST]}])
ui.list._fieldset = can.onimport._plugin(can, node.meta, target._fieldset, width)
var msg = can.request({}); msg.Push(node.meta, "", true)
ui.item.onclick = function(event) {
can.onmotion.select(can, can.ui.project, "div.item", ui.item)
can.current = ui.item, can.onmotion.clear(can, can.ui.profile)
can.onappend.table(can, msg, function(value, key, index, line, array) {
return {text: [value, html.TD], ondblclick: function(event) {
key == "value" && can.onmotion.modifys(can, event.target, function(event, value, old) {
node.meta[line.key] = value
})
}}
}, can.ui.profile)
}
ui.item._add = function(data) {
if (node.meta.style == html.SPAN) { width = width * node.list.length }
node.list.push(data)
if (node.meta.style == html.SPAN) { width = width / node.list.length }
can.onmotion.clear(can, ui.list), can.onmotion.clear(can, ui.list._fieldset)
can.core.List(node.list, function(node) { can.onimport._item(can, node, ui.list, width) })
}
if (node.meta.style == html.SPAN) { width = width / node.list.length }
can.core.List(node.list, function(node) { can.onimport._item(can, node, ui.list, width) })
return ui.item
},
_plugin: function(can, meta, target, width) {
var size = {width: width, height: meta.height}
var field = can.onappend.field(can, chat.LAYOUT, {}, target).fieldset
can.page.ClassList.add(can, field, meta.style)
can.page.Modify(can, field, {style: size})
meta.index && can.run(event, [ctx.ACTION, ctx.COMMAND, meta.index], function(msg) {
can.onappend._init(can, can.base.Copy({
feature: can.base.Obj(msg.Append("meta")),
inputs: can.base.Obj(msg.Append("list")),
args: meta.args,
name: meta.name,
}, size), ["/plugin/state.js"], function(sub) {
can.page.Modify(can, sub._output, {style: size})
sub.run = function(event, cmds, cb) {
can.run(event, can.misc.concat(can, [ctx.ACTION, ice.RUN, meta.index], cmds), cb, true)
}
}, target, field)
}, true)
return field
},
}, ["/plugin/local/chat/div.css"])
Volcanos("onaction", {help: "操作数据", list: [],
"添加": function(event, can) { "添加": function(event, can) {
can.user.input(event, can, [mdb.NAME, ctx.INDEX, ctx.ARGS, ctx.STYLE, html.HEIGHT, html.WIDTH], function(data) { can.user.input(event, can, [mdb.NAME, ctx.INDEX, ctx.ARGS, ctx.STYLE, html.HEIGHT, html.WIDTH], function(event, button, data, list, args) {
can.current._add({meta: data, list: []}) can.current._add({meta: data, list: []})
}) })
}, },
"保存": function(event, can) { var msg = can.request(event, can.Option()) "保存": function(event, can) { var msg = can.request(event, can.Option())
can.runAction(event, mdb.MODIFY, [mdb.TEXT, JSON.stringify(can._list)]) can.run(event, [mdb.MODIFY, mdb.TEXT, JSON.stringify(can._meta)], function(msg) {
can.user.toastSuccess(can)
}, true)
},
"预览": function(event, can) {
can.onmotion.share(event, can, [], [mdb.LINK, can.misc.MergeURL(can, {_path: "/chat/div/"+can.Option("hash")})])
}, },
}) })
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,13 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.db.current = msg.TableDetail()
// can.Conf("_width") && can.sup.onimport.size(can.sup, can.Conf("_height"), can.Conf("_width"), false)
can.page.style(can, can._output, "overflow-y", html.HIDDEN)
can.ui.target = can.page.Appends(can, can._output, [{type: html.IFRAME, src: can.db.current.link, height: can.ConfHeight(), width: can.ConfWidth()}])._target
can.sup.onexport.link = function() { return can.base.beginWith(can.db.current.link, "/")? location.origin+can.db.current.link: can.db.current.link }
},
layout: function(can) {
var item = can.db.current; can.sup.onexport.title(can, item.name||item.link.split(mdb.QS)[0])
can.page.style(can, can.ui.target, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth())
},
})
Volcanos(chat.ONACTION, {open: function(event, can) { can.user.open(can.db.current.link) }})

View File

@ -1,2 +0,0 @@
fieldset.keyboard div.output div.item { float:left; margin:5px; }
fieldset.keyboard div.output div.space { clear:both; }

View File

@ -1,24 +0,0 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg) { can.onmotion.clear(can)
var data = msg.TableDetail(), list = can.base.Obj(data.list), meta = can.base.Obj(data.meta)
var ui = can.page.Append(can, can._output, ["global", "option", "legend"]); can.user.trans(can, meta._trans)
can.onimport._input(can, [
{type: html.BUTTON, name: "清屏", cmds: "onmotion.clearFloat"},
{type: html.TEXT},
{type: html.BUTTON, name: "下一个", cmds: ["ctrl", "next"]},
{type: html.BUTTON, name: "上一个", cmds: ["ctrl", "prev"]},
{type: html.BUTTON, name: "确定", cmds: ["ctrl", "ok"]},
], data, ui.global)
can.onimport._input(can, list, data, ui.option), can.onimport._input(can, can.sup.onaction.list, data, ui.legend)
},
_input: function(can, item, data, target) { item = can.base.isObject(item)? item: {type: html.BUTTON, name: item}
if (can.base.isArray(item)) { return can.page.Append(can, target, [{view: "space"}]), can.core.List(item, function(item) { can.onimport._input(can, item, data, target) }) }
item._init = item._init||function(target) { switch (target.type) {
case html.TEXT: target.onkeydown = function(event) { can.misc.Event(event, can, function(msg) { if (event.key == code.ENTER) {
can.runAction(can.request(event, data), web.SPACE, [ctx.ACTION, item.name, target.value], function() {})
} })}; break
case html.BUTTON: target.onclick = function(event) { can.misc.Event(event, can, function(msg) {
can.runAction(can.request(event, data), web.SPACE, [ctx.ACTION].concat(item.cmds||item.name), function() {})
})}; break
} }, can.onappend.input(can, item, "", target)
},
}, [""])

View File

@ -0,0 +1,36 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.ui = can.onlayout.display(can, target)
can.ui.canvas = can.page.Append(can, can.ui.display, [{type: "canvas", width: 320, height: 240, style: {display: "none"}}]).first
can.onappend.table(can, msg, function(value, key, index, line, array) {
return {text: [value, "td"], onclick: function(event) {
can.sup.onaction.change(event, can.sup, key, value, function(msg) {
can.run(event)
})
}}
}, can.ui.content)
can.onappend.board(can, msg.Result(), can.ui.display)
can.base.isFunc(cb) && cb(msg)
},
})
Volcanos("onaction", {help: "操作数据", list: [], _init: function(can, msg, list, cb, target) {
},
open: function(event, can) {
navigator.getUserMedia({video: {width: 320, height: 240}}, function(stream) {
var video = can.page.Append(can, can.ui.content, "video")
video.srcObject = stream, video.play()
can.ui.video = video
}, function(error) {
can.misc.Log("open camera", error)
})
},
snapshot: function(event, can) {
can.ui.canvas.getContext("2d").drawImage(can.ui.video, 0, 0)
can.page.Append(can, can.ui.display, [{type: "img", src: can.ui.canvas.toDataURL('image/webp')}])
},
})
Volcanos("onexport", {help: "导出数据", list: [],
})

View File

View File

@ -1,30 +1,34 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg) { var height = 0.6 Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.from = can.onimport._plugin(can, nfs.DIR, html.LEFT, height, "from", "to") can.onmotion.clear(can)
can.to = can.onimport._plugin(can, nfs.DIR, html.RIGHT, height, "to", "from") can.from = can.onimport._plugin(can, nfs.DIR, html.LEFT, "from", "to")
can.onmotion.delay(can, function() { can.to = can.onimport._plugin(can, nfs.DIR, html.RIGHT, "to", "from")
can.from_trash = can.onimport._plugin(can, nfs.TRASH, html.LEFT, 1-height, "from") can.onimport._plugin(can, nfs.TRASH, html.LEFT, "from")
can.to_trash = can.onimport._plugin(can, nfs.TRASH, html.RIGHT, 1-height, "to") can.onimport._plugin(can, nfs.TRASH, html.RIGHT, "to")
}, 100)
}, },
_plugin: function(can, index, pos, height, from, to) { _plugin: function(can, index, pos, from, to) {
return can.onappend.plugin(can, {type: chat.STORY, space: can.Option(from), index: index}, function(sub) { return can.onappend.plugin(can, {type: chat.STORY, index: index}, function(sub) {
sub._legend.innerHTML = can.Option(from)+nfs.PT+index, can.page.style(can, sub._target, {float: pos, clear: pos}) can.page.Modify(can, sub._target, {style: {float: pos, clear: pos}})
sub.onexport.output = function() { sub.onimport.size(sub, can.ConfHeight()*height-20, can.ConfWidth()/2-20, false) } sub.Conf(html.WIDTH, can.Conf(html.WIDTH)/2)
sub.onimport.size(sub, can.ConfHeight()*height-20, can.ConfWidth()/2-20, false) sub._legend.innerHTML = can.Option(from)+ice.SP+index
sub.run = function(event, cmds, cb) { var msg = can.request(event); msg.Option("from", can.Option(from)), msg.Option("to", can.Option(to)) can.page.Modify(can, sub._output, {style: {"max-width": can.Conf(html.WIDTH)/2}})
sub.run = function(event, cmds, cb) {
if (can.onaction[cmds[1]]) { return can.onaction[cmds[1]](can, from, to, event, cmds, cb) } if (can.onaction[cmds[1]]) { return can.onaction[cmds[1]](can, from, to, event, cmds, cb) }
can.runActionCommand(event, index, cmds, function(msg) { cb && cb(msg)
if (cmds[0] == ctx.ACTION) { var msg = sub.request(event, {_pod: can.Option(from)})
if (!to) { can[from].Update() } else { can[from+"_trash"].Update() } can.run(event, can.misc.concat(can, [ctx.ACTION, ice.RUN, index], cmds), cb, true)
}
})
} }
}) })
}, },
}) })
Volcanos(chat.ONACTION, { Volcanos("onaction", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
send: function(can, from, to, event, cmds, cb) { var msg = can.request(event, {_handle: ice.TRUE}) },
msg.Option("from_path", can[from].Option(nfs.PATH)), msg.Option("to_path", can[to].Option(nfs.PATH)) send: function(can, from, to, event, cmds, cb) { var _from = can[from], _to = can[to]
can.run(event, cmds, function() { can[to].Update() }) var path = can.request(event).Option(nfs.PATH)
var msg = can.request(event, {_handle: ice.TRUE,
from: can.Option(from), from_path: path,
to: can.Option(to), to_path: _to.Option(nfs.PATH)+path.split(ice.PS).pop(),
})
can.run(event, cmds, function() { _to.Update() }, true)
}, },
}) })

28
plugin/local/chat/wx.js Normal file
View File

@ -0,0 +1,28 @@
Volcanos("onaction", {source: function(can, msg) {
can.require(["https://res.wx.qq.com/open/js/jweixin-1.6.0.js"], function(can) {
wx.config({debug: msg.Option("debug") == ice.TRUE,
appId: msg.Option("appid"), signature: msg.Option("signature"),
nonceStr: msg.Option("noncestr"), timestamp: msg.Option("timestamp"),
jsApiList: can.core.Item({
scanQRCode: function(cb) { wx.scanQRCode({needResult: cb? 1: 0, scanType: ["qrCode","barCode"], success: function (res) {
can.base.isFunc(cb) && cb(res.resultStr, can.base.ParseJSON(res.resultStr))
} }) },
getLocation: function(cb) { wx.getLocation({type: "gcj02", success: function (res) {
can.base.isFunc(cb) && cb({type: "gcj02", name: "当前位置", text: "当前位置", latitude: parseInt(res.latitude*100000), longitude: parseInt(res.longitude*100000) })
} }) },
openLocation: function(msg) { wx.openLocation({
latitude: parseInt(msg.Option("latitude"))/100000,
longitude: parseInt(msg.Option("longitude"))/100000,
name: msg.Option(mdb.NAME), address: msg.Option(mdb.TEXT),
scale: msg.Option("scale")||14, infoUrl: msg.Option(mdb.LINK),
}) },
chooseImage: function(cb, count) { wx.chooseImage({count: count||9, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: function (res) {
can.base.isFunc(cb) && cb(res.localIds)
} }) },
}, function(key, value) { return can.user.agent[key] = value, key }),
})
wx.error(function(err) { can.user.toast(err, "wx load") })
wx.ready(function() { can.misc.Log("ready") })
})
}})

View File

@ -1,107 +1,195 @@
fieldset.inner>div.output div.content { position:relative; } fieldset.inner>div.action div.tabs {
fieldset.inner>div.output div.content td.text { height:var(--code-line-height); } border:solid 2px red; padding:2px;
fieldset.inner>div.output div.content td.text span.keyword { color:var(--code-keyword); box-shadow:var(--keyword-box-shadow); } }
fieldset.inner>div.output div.content td.text span.comment { color:var(--code-comment); } fieldset.inner>div.action div.tabs.over {
fieldset.inner>div.output div.content td.text span.function { color:var(--code-function); } background-color:blue;
fieldset.inner>div.output div.content td.text span.constant { color:var(--code-constant); } }
fieldset.inner>div.output div.content td.text span.string { color:var(--code-string); box-shadow:var(--keyword-box-shadow); } fieldset.inner>div.action div.tabs.select {
fieldset.inner>div.output div.content td.text span.package { color:var(--code-package); } background-color:green;
fieldset.inner>div.output div.content td.text span.datatype { color:var(--code-datatype); } }
fieldset.inner>div.output div.content td.text span.object { color:var(--code-object); }
fieldset.inner>div.output>div.project { font-family:var(--code-font-family); } fieldset.inner>div.output {
fieldset.inner>div.output>div.project div.list { border-left:none; } color:white;
fieldset.inner>div.output>div.project div.item.select:not(:hover) { background-color:unset; } }
fieldset.inner>div.output>div.layout>div.tabs>div.tabs>div.tabs { border-top:var(--box-border3); border-top-color:transparent; } fieldset.inner>div.output>table.layout div.toggle.project {
fieldset.inner>div.output>div.layout>div.tabs>div.tabs>div.tabs.select { box-shadow:var(--legend-box-shadow); background-color:var(--output-bg-color); border-top:var(--box-notice3); } min-width:15px; font-size:24px;
fieldset.inner>div.output>div.layout>div.tabs>div.tabs>div.tabs:hover { box-shadow:var(--legend-box-shadow); background-color:var(--output-bg-color); } }
fieldset.inner>div.output>div.layout>div.path { font-size:var(--code-font-size); display:none; } fieldset.inner>div.output>table.layout div.toggle.profile {
fieldset.inner>div.output>div.layout>div.path:not(.hide) { box-shadow:var(--legend-box-shadow); font-style:italic; cursor:pointer; justify-content:flex-start; align-items:center; } min-width:15px; font-size:24px;
fieldset.inner>div.output>div.layout>div.path>a { padding:var(--input-padding); } }
fieldset.inner>div.output>div.layout>div.path>a:hover { background-color:var(--hover-bg-color); } fieldset.inner>div.output>table.layout div.toggle.display {
fieldset.inner>div.output>div.layout>div.path>span { padding:var(--input-padding); white-space:pre; } height:15px; font-size:24px;
fieldset.inner>div.output>div.layout>div.path>span:hover { background-color:var(--hover-bg-color); } margin-top:-17px;
fieldset.inner>div.output>div.layout>div.path>span._space:hover { background-color:unset; } }
fieldset.inner>div.output>div.layout>div.path>span.view { font-style:normal; font-size:22px; padding:0 var(--input-padding); } fieldset.inner>div.output div.project {
body.windows fieldset.inner>div.output>div.layout>div.path>span.view { font-size:18px; } max-width:180px; overflow:auto;
fieldset.inner>div.output>div.layout>div.display h1 { border-bottom:var(--box-border); margin:var(--title-margin) 0; } }
fieldset.inner>div.output>div.layout>div.display h2 { border-bottom:var(--box-border); margin:var(--title-margin) 0; } fieldset.inner>div.output div.content {
fieldset.inner>div.output>div.layout>div.display pre>code { padding-left:var(--table-padding); border-left:var(--box-notice3); display:block; } position:relative;
fieldset.inner>div.output>div.layout>div.display div.code { white-space:unset; padding:var(--table-padding); } padding-right:25px;
fieldset.inner>div.output>div.layout>div.display div.status { position:sticky; bottom:0; } font-size:1.2rem; font-family:monospace;
fieldset.inner>div.output>div.layout>div.display div.status>div { padding:var(--input-padding); float:left; } overflow:auto;
fieldset.inner>div.output>div.layout>div.layout { justify-content:flex-start; } color:white;
fieldset.inner>div.output>div.layout>div.layout>div.profile h1 { border-bottom:var(--box-border); margin:var(--title-margin) 0; } }
fieldset.inner>div.output>div.layout>div.layout>div.profile h2 { border-bottom:var(--box-border); margin:var(--title-margin) 0; } fieldset.inner>div.output div.content table.layout {
fieldset.inner>div.output>div.layout>div.layout>div.profile pre>code { padding-left:var(--table-padding); border-left:var(--box-notice3); display:block; } width:-webkit-fill-available;
fieldset.inner>div.output>div.layout>div.layout>div.profile>div.code { white-space:unset; padding:var(--table-padding); } }
fieldset.inner>div.output>div.layout>div.layout>div.profile>div.status { background-color:var(--output-bg-color); height:var(--action-height); overflow:auto; position:sticky; bottom:0; } fieldset.inner>div.output div.content tr.select {
fieldset.inner>div.output>div.layout>div.layout>div.profile fieldset>form.option>div.item.text input { max-width:80px; } background-color:#0000ff6b;
fieldset.inner>div.output>div.layout>div.layout>div.profile fieldset>div.action>div.item.text input { max-width:80px; } }
fieldset.inner>div.output>div.layout>div.layout>div.profile div.status>div { font-style:italic; font-size:var(--status-font-size); padding:var(--input-padding); float:left; } fieldset.inner>div.output div.content tr.select td.line {
fieldset.inner>div.output>div.layout>div.layout>div.content div.tips { color:var(--disable-fg-color); font-style:italic; line-height:var(--code-line-height); position:absolute; top:0; right:10px; } background-color:blue;
fieldset.inner>div.output>div.layout>div.layout>fieldset.story { box-shadow:unset; } border:solid 1px red;
fieldset.inner.cmd>div.output>div.layout>div.tabs:not(.hide) { background-color:var(--plugin-bg-color); height:var(--code-tabs-height); display:flex; } border-right:solid 2px red;
fieldset.inner.cmd>div.output>div.layout>div.tabs>div { height:var(--code-tabs-height); } }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.icon>div.icon { font-size:26px; line-height:32px; padding:2px 5px; position:sticky; top:0; } fieldset.inner>div.output div.content td.line:hover {
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.tabs { justify-content:flex-start; flex-grow:1; flex-wrap:wrap; overflow:auto; display:flex; } background-color:green;
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.tabs:hover { background-color:unset; color:unset; } }
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.tabs>div.tabs { padding:var(--input-padding) var(--button-padding); height:var(--code-tabs-height); display:flex; align-items:center; } fieldset.inner>div.output div.content td.line {
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head { display:flex; flex-direction:row-reverse; flex-shrink:0; } text-align:right; padding:0 6px;
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div { padding:0 var(--input-padding); display:flex; align-items:center; flex-shrink:0; } border-right:solid 2px red;
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>div.output div.content td.text {
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.avatar { padding:0; } text-align:left; height:20px;
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.qrcode i { margin-top:3px; } padding-left:10px;
fieldset.inner.cmd>div.output>div.layout>div.tabs>div.head>div.avatar>img { height:32px; clip-path:circle(40%); } white-space:pre;
fieldset.inner.cmd>div.output>div.layout>div.path:not(.hide) { display:flex; } tab-size:4;
fieldset.inner.cmd>div.output>div.layout>div.plug { box-shadow:var(--th-box-shadow); background-color:var(--plugin-bg-color); height:var(--action-height); overflow:auto; } }
fieldset.inner.cmd>div.output>div.layout>div.plug>legend { padding:0 var(--input-padding); padding-right:0; margin-right:0; float:right; } fieldset.inner>div.output div.content td.text span.comment {
fieldset.inner.cmd>div.output>div.layout>div.plug>legend:hover { box-shadow:var(--notice-box-shadow); } color:cyan; background-color:blue;
fieldset.inner.cmd>div.output>div.layout>div.plug>legend>span.remove { padding:0 var(--input-padding); } }
fieldset.inner.cmd>div.output>div.layout>div.plug>legend>span.remove:hover { background-color:var(--hover-bg-color); } fieldset.inner>div.output div.content td.text span.keyword {
fieldset.inner.cmd>div.output>div.layout>div.plug>legend:not(:hover)>span.remove { visibility:hidden; } color:yellow; font-weight:bold;
fieldset.inner fieldset.plug.can._plugin.search>form.option>div.item.value input { width:var(--project-width); } }
fieldset.inner fieldset.plug.can._plugin.search>form.option>div.item.filter input { width:var(--project-width); } fieldset.inner>div.output div.content td.text span.function {
fieldset.inner fieldset.plug.can._plugin.search>div.output>table.content tr td { cursor:pointer; } color:cyan; font-weight:bold;
fieldset.inner.float>div.output>div.layout>div.path { font-size:var(--code-font-size); display:flex; } }
fieldset.Action.tabview fieldset.plugin.inner>div.output>div.layout>div.path:not(.hide) { font-size:var(--code-font-size); display:flex; } fieldset.inner>div.output div.content td.text span.datatype {
fieldset.inner:not(.monaco)>div.output div.content>tr.line * { font-family:var(--code-font-family); font-size:var(--code-font-size); } color:lightgreen; font-weight:bold;
fieldset.inner.plugin>div.output>div.layout>div.layout div.content tr.line.select>td.line { background-color:var(--notice-bg-color); color:white; } }
fieldset.vimer.plugin>div.output>div.layout>div.layout div.content tr.line.select>td.line { background-color:unset; color:unset; } fieldset.inner>div.output div.content td.text span.constant {
div.carte.inner.mode.float div.item { padding:var(--input-padding); } color:magenta;
div.carte.inner.path.float div.item { padding:var(--input-padding); } }
div.carte.inner.path.float div.item.private { color:var(--disable-fg-color); } fieldset.inner>div.output div.content td.text span.string {
div.input.inner.find.float div.action div.item { margin:var(--input-margin); } color:magenta;
div.input.inner.find.float div.action div.item.text input { width:var(--project-width); } }
div.input.inner.find.float div.action div.item.close span { display:none; } fieldset.inner>div.output div.display>div.action>div.item {
div.input.inner.find.float div.action div.item.replace input { border:var(--box-danger); }
div.input.inner.open.float td:first-child { display:none; }
div.input.inner.open.float div.item.text input[type=text] { width:100% !important; }
div.input.inner.open.float td:nth-child(2) { display:none; }
tr.line>td.line { border-right:var(--box-border); cursor:pointer; -webkit-user-select:none; }
tr.line>td.line { text-align:right; line-height:var(--code-line-height); padding:0 var(--button-padding); position:sticky; left:0; }
tr.line>td.text { white-space:pre; line-height:var(--code-line-height); padding-left:var(--input-padding); width:100%; }
tr.line:hover { background-color:var(--hover-bg-color); }
tr.line.delete { background-color:#3c2626; }
tr.line.insert { background-color:#283e2d; }
body div.input.inner.find.float div.action>div.item {
float:left; float:left;
} }
body div.input.inner.find.float div.action>div.item>input { fieldset.inner>div.output div.profile>div.action>div.item {
min-width:unset; float:left;
} }
body.light tr.line.delete { background-color:#ffeef0; } fieldset.inner>div.output div.profile>div.output {
body.light tr.line.insert { background-color:#e6ffed; } clear:both; overflow:auto;
body.white tr.line.delete { background-color:#e6ffed; } }
body.white tr.line.insert { background-color:#ffeef0; } fieldset.inner>div.output div.profile>div.output>fieldset {
body.width2 fieldset.inner>div.output>div.layout>div.path span.mode { display:none; } margin:0; padding:0;
body.mobile fieldset.inner>div.output>div.layout>div.path span.func { display:none; } }
body.mobile fieldset.inner>div.output>div.layout>div.path span.mode { display:none; } fieldset.inner>div.output div.profile>div.output>fieldset>legend {
body.light fieldset.inner.cmd>div.output>div.layout>div.tabs>div.tabs>div.tabs { margin-right:var(--button-margin); } float:left;
body:not(.mobile) fieldset.inner>div.output>div.layout>fieldset.plug { bottom:var(--action-height); } }
body:not(.windows) fieldset.inner>div.output>div.project * { font-family:var(--code-font-family); font-size:var(--code-font-size); } fieldset.inner>div.output div.display>div.output {
body:not(.windows) fieldset.inner>div.output>div.layout>div.tabs { font-family:var(--code-font-family); font-size:var(--code-font-size); } clear:both; overflow:auto;
body:not(.windows) fieldset.inner>div.output>div.layout>div.path { font-family:var(--code-font-family); font-size:var(--code-font-size); } }
body.windows fieldset.inner.cmd>div.output>div.layout>div.tabs>div.icon>div.icon { font-size:20px !important; padding-top:6px; } fieldset.inner>div.output div.display {
body.windows fieldset.inner>div.output>div.layout>div.path span.view { margin-top:0; } border:solid 1px greenyellow;
body.windows fieldset.inner>div.output>div.layout>div.path span.view { font-style:normal; } }
fieldset.inner div.output fieldset.toolkit {
position:absolute;
bottom:0px; right:0px;
}
fieldset.inner>div.output fieldset.toolkit>div.output>fieldset {
display:none; margin:0;padding:0;
}
fieldset.inner>div.output fieldset.toolkit>div.output>fieldset.select {
display:block;
}
fieldset.inner>div.output fieldset.toolkit>div.output>fieldset>legend {
float:left;
}
fieldset.inner>div.output fieldset.toolkit>div.status {
/* height:32px; overflow:auto; */
}
fieldset.inner>div.output fieldset.toolkit>div.status>legend {
float:right; padding:4px; cursor:pointer;
padding:4px 4px; border-left:solid 2px red;
background:#0d969f8a;
}
fieldset.inner>div.output fieldset.toolkit>div.status>legend.select {
background:green;
}
fieldset.inner>div.output fieldset.toolkit>div.status>legend:hover {
background:green;
}
fieldset.inner>div.status {
height:26px; overflow:auto;
}
fieldset.Action fieldset.inner>div.status legend {
float:right;
font-size:1.1rem;
/* padding:4px; */
cursor:pointer;
/* padding:4px 4px; */
border-left:solid 2px red;
background:#0d969f8a;
padding:0px 10px;
}
fieldset.Action fieldset.inner>div.status legend.select {
background-color:red;
}
fieldset.inner>div.status legend.select {
background:green;
}
fieldset.inner>div.status legend:hover {
background:green;
}
fieldset.inner.full>legend {
display:none;
}
fieldset.inner.full>div.action {
display:none;
}
fieldset.inner.full>form.option {
display:none;
}
fieldset.inner.full>div.status {
display:none;
}
fieldset.inner.full>div.status {
display:none;
}
fieldset.inner.full>div.output div.profile>div.action {
display:none;
}
fieldset.inner.full>div.output div.display>div.action {
display:none;
}
body.white fieldset.inner>div.output div.project {
color:#a2dad2;
}
body.white fieldset.inner>div.output div.content {
background-color:#013b675c;
}
body.white fieldset.inner>div.output div.content tr {
background-color:#e1f1ff00;
}
body.white fieldset.inner>div.output div.content tr.select {
background-color:#0000ff6b;
}
body.white fieldset.inner>div.output div.content td.text span.string {
color:#a703a7;
}
.unselectable {
-webkit-touch-callout:none;
-webkit-user-select:none;
-khtml-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
-o-user-select:none;
user-select:none;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
Volcanos("onimport", {help: "导入数据", _init: function(can, args, cb) {
can.onimport.toolkit(can, {index: "web.code.favor"}, function(sub) {
sub.run = function(event, cmds, cb) { var msg = can.request(event)
if (can.misc.runAction(can, msg, cmds, cb, kit.Dict(
code.INNER, function(cmds) {
can.onimport.tabview(can, msg.Option(nfs.PATH), msg.Option(nfs.FILE), msg.Option(nfs.LINE))
},
))) { return }
can.run(event, can.misc.concat(can, [ctx.ACTION, code.FAVOR], cmds), function(msg) { var sub = msg._can
sub.onmotion.clear(sub), sub.onappend.table(sub, msg, function(value, key, index, line) {
if (msg.append.length == 2 && msg.append[0] == mdb.KEY && msg.append[1] == mdb.VALUE) {
if (key == mdb.VALUE) { key = line.key }
}
if (key != ctx.ACTION) { value = sub.page.replace(sub, value, ice.PWD, "") }
return {text: ["", html.TD], list: [{text: [value, html.DIV]}], onclick: function(event) { var target = event.target
if ([mdb.ZONE, mdb.ID].indexOf(key) > -1) { return sub.onaction.change(event, sub, key, value) }
if (target.tagName == "INPUT" && target.type == html.BUTTON) { var msg = sub.request(event, line, sub.Option())
return sub.run(event, [ctx.ACTION, target.name], function(msg) { sub.run() }, true)
}
line.line && can.onimport.tabview(can, line.path, line.file.replace(ice.PWD, ""), parseInt(line.line))
}}
}, sub._output), sub.onappend._status(sub, msg.Option(ice.MSG_STATUS)), can.Status("标签数", msg.Length())
}, true)
}, can.base.isFunc(cb) && cb(sub)
})
}})

View File

@ -1,6 +1,59 @@
Volcanos(chat.ONIMPORT, {list: [mdb.VALUE, "close:button"], Volcanos("onimport", {help: "导入数据", _init: function(can, args, cb) { var history = []; const SEARCH = "can.code.inner.search"
_init: function(can, msg) { msg.Defer(function() { can.onappend.scroll(can) }), can.page.style(can, can._output, html.VISIBILITY, "") function show(msg, word) { if (!msg) { return } history.push(msg); var sub = msg._can; sub.Option("word", word||msg._word)
can.onappend.table(can, msg), can.onappend.board(can, msg), can.onmotion.highlight(can, can.Option(mdb.VALUE, msg.Option(mdb.VALUE))) !sub.page.ClassList.has(sub, sub._legend, "select") && can.ui.search.select()
can.page.Select(can, can._option, "input[name=value]", function(target) { can.onmotion.hidden(can, target) }) sub.onmotion.clear(sub), sub.onappend.table(sub, msg, function(value, key, index, line) {
}, return {text: ["", html.TD], list: [{text: [can.page.replace(can, value, ice.PWD, ""), html.DIV]}], onclick: function(event) {
}) line.line && can.onimport.tabview(can, can.Option(nfs.PATH), line.file.replace(ice.PWD, ""), parseInt(line.line))
}}
}, sub._output), sub.onappend.board(sub, msg.Result()), sub.onappend._status(sub, msg.Option(ice.MSG_STATUS)), can.Status("标签数", msg.Length())
}
can.onengine.plugin(can, SEARCH, shy("搜索", {}, [
{type: html.TEXT, name: "word", value: cli.MAIN, onkeydown: function(event, can) {
can.onmotion.selectTable(event, can.sup, event.target, function(tr) {
can.page.Select(can, tr, html.TD, function(td, index) { index == 0 && td.click() })
tr.scrollIntoView(), can._output.scrollTop -= 60
})
if (event.key == lang.ENTER) { can.sup.Update(event, [ctx.ACTION, event.ctrlKey? nfs.GREP: nfs.TAGS, can.sup.Option("word")]) }
if (event.key == lang.ESCAPE) { event.target.blur() }
}},
{type: html.TEXT, name: "filter", value: "", onkeydown: function(event, can) {
can.onmotion.selectTableInput(event, can.sup, event.target)
if (event.key == lang.ENTER) { can.sup.Update(event, [ctx.ACTION, event.ctrlKey? nfs.GREP: nfs.TAGS, can.sup.Option("word")]) }
if (event.key == lang.ESCAPE) { event.target.blur() }
}},
{type: html.BUTTON, name: nfs.TAGS},
{type: html.BUTTON, name: nfs.GREP},
{type: html.BUTTON, name: cli.MAKE},
{type: html.BUTTON, name: "history"},
{type: html.BUTTON, name: "last", _trans: "返回"},
], function(msg, cmds, cb) { if (can.misc.runAction(can, msg, cmds, cb, kit.Dict(
"history", function(cmds) {
can.core.List(can.history, function(item) {
msg.Push(nfs.FILE, item.file)
msg.Push(nfs.LINE, item.line)
msg.Push(mdb.TEXT, item.text)
})
show(msg)
},
nfs.TAGS, function(cmds) { msg.Option(kit.Dict(ice.MSG_HANDLE, ice.TRUE, ice.MSG_FIELDS, "file,line,text"))
can.run(msg._event, [ctx.ACTION, mdb.SEARCH, can.parse, cmds[0], can.Option(nfs.PATH)], function(msg) { var sub = msg._can
can.page.style(can, sub._output, html.MAX_HEIGHT, can.ConfHeight()/4), show(msg, msg._word = cmds[0])
can.page.ClassList.has(sub, sub._target, html.SELECT) || sub._legend.click()
can.onmotion.focus(can, msg._can._inputs["word"]._target)
}, true)
},
nfs.GREP, function(cmds) { msg.Option(kit.Dict(ice.MSG_HANDLE, ice.TRUE, ice.MSG_FIELDS, "file,line,text", nfs.PATH, can.Option(nfs.PATH)))
can.run(msg._event, [ctx.ACTION, nfs.GREP, cmds[0]], function(msg) { var sub = msg._can
can.page.style(can, sub._output, html.MAX_HEIGHT, can.ConfHeight()/4), show(msg, msg._word = cmds[0])
can.page.ClassList.has(sub, sub._target, html.SELECT) || sub._legend.click()
can.onmotion.focus(can, msg._can._inputs["word"]._target)
}, true)
},
"last", function(cmds) { history.pop(), show(history.pop()) },
))) { return } can.run(msg._event, cmds, function(msg) { show(msg) }, true) }))
can.onimport.toolkit(can, {index: SEARCH}, function(sub) {
can.ui.search = sub, can.base.isFunc(cb) && cb(sub)
can.ui.search._show = show
})
}})

View File

@ -0,0 +1,22 @@
Volcanos("onimport", {help: "导入数据", _init: function(can, args, cb) { var SESS = "web.code.sess"
can.onimport.toolkit(can, {index: SESS}, function(sub) {
sub.run = function(event, cmds, cb) { var msg = can.request(event)
if (can.misc.runAction(can, msg, cmds, cb, kit.Dict(
nfs.SAVE, function(cmds) {
can.run(event, [ctx.ACTION, ice.RUN, SESS].concat([ctx.ACTION, mdb.CREATE,
"tool", JSON.stringify(can.onexport.tool(can)),
"tabs", JSON.stringify(can.onexport.tabs(can)),
]), cb, true)
},
nfs.LOAD, function(cmds) {
can.onimport.sess(can, {
tool: JSON.parse(msg.Option("tool")),
tabs: JSON.parse(msg.Option("tabs")),
})
},
))) { return }
can.run(event, [ctx.ACTION, ice.RUN, SESS].concat(cmds), cb, true)
}, can.base.isFunc(cb) && cb(sub)
})
}})

View File

@ -1,397 +0,0 @@
Volcanos(chat.ONSYNTAX, {
makefile: {prefix: {"#": code.COMMENT}, split: {operator: "($?.,):+="}, keyword: {
"export": code.KEYWORD,
"if": code.KEYWORD, "else": code.KEYWORD, "endif": code.KEYWORD,
"ifeq": code.KEYWORD, "ifneq": code.KEYWORD,
"ifdef": code.KEYWORD, "ifndef": code.KEYWORD,
"define": code.KEYWORD, "endef": code.KEYWORD,
"shell": code.KEYWORD,
"PHONY": code.FUNCTION,
}, include: ["sh"], func: function(can, push, text, indent) { var ls = can.core.Split(text, "", ":=")
if (indent == 0 && ls[1] == ":" && ls[2] != "=") { push(text) }
}, parse: function(can, text, wrap) { var ls = can.core.Split(text, "", ":=")
if (ls[1] == ":" && ls[2] != "=" && can.base.beginWith(text, ls[0])) { return wrap(text, code.OBJECT) }
}},
man: {prefix: {
"NAME": code.KEYWORD,
"SYNOPSIS": code.KEYWORD,
"DESCRIPTION": code.KEYWORD,
"AUTHOR": code.KEYWORD,
"COPYRIGHT": code.KEYWORD,
"LIBRARY": code.KEYWORD,
"STANDARDS": code.KEYWORD,
"SEE ALSO": code.KEYWORD,
"HISTORY": code.KEYWORD,
"BUGS": code.KEYWORD,
}},
vim: {prefix: {"\"": "comment"}, keyword: {
"source": code.KEYWORD,
"finish": code.KEYWORD,
"set": code.KEYWORD,
"let": code.KEYWORD,
"end": code.KEYWORD,
"if": code.KEYWORD,
"else": code.KEYWORD,
"elseif": code.KEYWORD,
"endif": code.KEYWORD,
"for": code.KEYWORD,
"in": code.KEYWORD,
"continue": code.KEYWORD,
"break": code.KEYWORD,
"endfor": code.KEYWORD,
"try": code.KEYWORD,
"catch": code.KEYWORD,
"finally": code.KEYWORD,
"endtry": code.KEYWORD,
"call": code.KEYWORD,
"function": code.KEYWORD,
"return": code.KEYWORD,
"endfunction": code.KEYWORD,
"autocmd": code.KEYWORD,
"command": code.KEYWORD,
"execute": code.KEYWORD,
"nnoremap": code.KEYWORD,
"cnoremap": code.KEYWORD,
"inoremap": code.KEYWORD,
"colorscheme": code.KEYWORD,
"highlight": code.KEYWORD,
"syntax": code.KEYWORD,
"has": code.FUNCTION,
"type": code.FUNCTION,
"empty": code.FUNCTION,
"exists": code.FUNCTION,
"executable": code.FUNCTION,
}}, vimrc: {link: "vim"},
c: {
prefix: {
"//": code.COMMENT,
"/*": code.COMMENT,
"*": code.COMMENT,
"*/": code.COMMENT,
"#": code.KEYWORD,
},
regexp: {
"^u_\\w $": code.DATATYPE,
"^\\w+_t$": code.DATATYPE,
"^\\w+_pt$": code.DATATYPE,
"^[-]*\\d+$": code.CONSTANT,
"^[A-Z0-9_]+$": code.CONSTANT,
},
keyword: {
"#include": code.KEYWORD, "#error": code.KEYWORD, "#line": code.KEYWORD,
"#define": code.KEYWORD, "#undef": code.KEYWORD, "#ifndef": code.KEYWORD, "#ifdef": code.KEYWORD,
"#if": code.KEYWORD, "#elif": code.KEYWORD, "#else": code.KEYWORD, "#endif": code.KEYWORD,
"if": code.KEYWORD, "else": code.KEYWORD,
"for": code.KEYWORD, "while": code.KEYWORD, "do": code.KEYWORD, "break": code.KEYWORD, "continue": code.KEYWORD,
"switch": code.KEYWORD, "case": code.KEYWORD, "default": code.KEYWORD,
"return": code.KEYWORD, "goto": code.KEYWORD,
"void": code.DATATYPE, "char": code.DATATYPE, "int": code.DATATYPE, "float": code.DATATYPE, "double": code.DATATYPE,
"unsigned": code.DATATYPE, "signed": code.DATATYPE, "short": code.DATATYPE, "long": code.DATATYPE,
"struct": code.DATATYPE, "union": code.DATATYPE, "enum": code.DATATYPE,
"auto": code.DATATYPE, "register": code.DATATYPE, "volatile": code.DATATYPE, "const": code.DATATYPE,
"static": code.DATATYPE, "extern": code.DATATYPE, "typedef": code.DATATYPE,
"sizeof": code.FUNCTION, "defined": code.FUNCTION,
},
}, h: {link: "c"},
sh: {prefix: {"#": code.COMMENT}, suffix: {" {": code.COMMENT}, split: {operator: "{[($.,:;&<|>=)]}"}, regexp: {"[A-Z0-9_]+": code.CONSTANT, "ish_[A-Za-z0-9_]+": code.FUNCTION},
keyword: {
"source": code.KEYWORD, "return": code.KEYWORD, "exit": code.KEYWORD,
"require": code.KEYWORD, "request": code.KEYWORD,
"local": code.KEYWORD, "export": code.KEYWORD,
"if": code.KEYWORD, "then": code.KEYWORD, "elif": code.KEYWORD, "else": code.KEYWORD, "fi": code.KEYWORD,
"for": code.KEYWORD, "while": code.KEYWORD, "do": code.KEYWORD, "done": code.KEYWORD, "continue": code.KEYWORD, "break": code.KEYWORD,
"case": code.KEYWORD, "in": code.KEYWORD, "esac": code.KEYWORD,
"true": code.CONSTANT, "false": code.CONSTANT,
"history": code.FUNCTION, "alias": code.FUNCTION, "complete": code.FUNCTION, "compgen": code.FUNCTION, "bind": code.FUNCTION,
"printf": code.FUNCTION, "echo": code.FUNCTION, "eval": code.FUNCTION, "test": code.FUNCTION, "trap": code.FUNCTION, "shift": code.FUNCTION,
"set": code.FUNCTION, "xargs": code.FUNCTION,
"/dev/null": code.CONSTANT, "/dev/stdout": code.CONSTANT, "/dev/stderr": code.CONSTANT,
"mkdir": code.FUNCTION, "rmdir": code.FUNCTION, "mktemp": code.FUNCTION, "du": code.FUNCTION, "df": code.FUNCTION,
"cd": code.FUNCTION, "ls": code.FUNCTION, "ln": code.FUNCTION, "mv": code.FUNCTION, "rm": code.FUNCTION, "cp": code.FUNCTION,
"groupadd": code.FUNCTION, "useradd": code.FUNCTION, "chown": code.FUNCTION, "sudo": code.FUNCTION,
"curl": code.FUNCTION, "wget": code.FUNCTION, "apk": code.FUNCTION, "yum": code.FUNCTION,
"cat": code.FUNCTION, "head": code.FUNCTION, "tail": code.FUNCTION,
"grep": code.FUNCTION, "cut": code.FUNCTION, "sed": code.FUNCTION, "tr": code.FUNCTION,
"make": code.FUNCTION, "file": code.FUNCTION, "vim": code.FUNCTION, "gcc": code.FUNCTION, "git": code.FUNCTION, "go": code.FUNCTION,
"docker": code.FUNCTION,
},
func: function(can, push, text) { if (can.base.endWith(text, "() {")) { var ls = can.core.Split(text, "\t (){"); push(ls[0]) } },
}, configure: {link: "sh"},
shy: {
prefix: {
"#": code.COMMENT,
"~": code.COMMENT,
},
regexp: {"[A-Z_0-9]+": code.CONSTANT},
keyword: {
"source": code.KEYWORD, "return": code.KEYWORD,
"command": code.KEYWORD, "config": code.KEYWORD,
"create": code.FUNCTION, "modify": code.FUNCTION, "insert": code.FUNCTION,
"spide": code.DATATYPE, "serve": code.DATATYPE, "dream": code.DATATYPE,
"user": code.DATATYPE,
"title": code.KEYWORD, "navmenu": code.KEYWORD, "premenu": code.KEYWORD, "chapter": code.KEYWORD, "section": code.KEYWORD, "endmenu": code.KEYWORD,
"refer": code.KEYWORD, "brief": code.KEYWORD, "spark": code.KEYWORD, "shell": code.KEYWORD, "parse": code.KEYWORD,
"order": code.KEYWORD, "table": code.KEYWORD, "chart": code.KEYWORD, "label": code.KEYWORD, "chain": code.KEYWORD, "sequence": code.KEYWORD,
"field": code.KEYWORD, "image": code.KEYWORD, "video": code.KEYWORD, "audio": code.KEYWORD,
"style": code.KEYWORD,
"inner": code.KEYWORD,
"project": code.KEYWORD,
"product": code.KEYWORD,
"material": code.KEYWORD,
"publish": code.KEYWORD,
"username": code.FUNCTION, "usernick": code.FUNCTION,
"repos": code.FUNCTION, "binary": code.FUNCTION,
"language": code.FUNCTION, "avatar": code.FUNCTION,
},
func: function(can, push, text, indent, opts) { var ls = can.core.Split(text, "\t ")
opts.chapter = opts.chapter||0
if (ls[0] == "chapter") { opts.chapter++, opts.section = 0, push(opts.chapter+lex.SP+ls[1]) }
if (ls[0] == "section") { opts.section++, push(opts.chapter+nfs.PT+opts.section+lex.SP+ls[1]) }
},
},
py: {prefix: {"#!": code.COMMENT, "# ": code.COMMENT}, keyword: {"import": code.KEYWORD, "from": code.KEYWORD, "return": code.KEYWORD, "print": code.FUNCTION}},
proto: {prefix: {"// ": code.COMMENT}, regexp: {"[A-Z_0-9]+": code.CONSTANT}, keyword: {
"syntax": code.KEYWORD, "package": code.KEYWORD, "option": code.FUNCTION,
"service": code.KEYWORD, "rpc": code.KEYWORD, "returns": code.KEYWORD,
"message": code.KEYWORD, "repeated": code.FUNCTION, "string": code.DATATYPE, "int64": code.DATATYPE,
}},
go: {prefix: {"// ": code.COMMENT}, regexp: {"[A-Z_0-9]+": code.CONSTANT},
keyword: {
"package": code.KEYWORD, "import": code.KEYWORD, "const": code.KEYWORD, "type": code.KEYWORD, "struct": code.KEYWORD, "interface": code.KEYWORD, "func": code.KEYWORD, "var": code.KEYWORD,
"if": code.KEYWORD, "else": code.KEYWORD,
"for": code.KEYWORD, "range": code.KEYWORD, "break": code.KEYWORD, "continue": code.KEYWORD,
"switch": code.KEYWORD, "case": code.KEYWORD, "default": code.KEYWORD, "fallthrough": code.KEYWORD,
"go": code.KEYWORD, "select": code.KEYWORD, "defer": code.KEYWORD, "return": code.KEYWORD,
"iota": code.CONSTANT, "true": code.CONSTANT, "false": code.CONSTANT, "nil": code.CONSTANT,
"int": code.DATATYPE, "int8": code.DATATYPE, "int16": code.DATATYPE, "int32": code.DATATYPE, "int64": code.DATATYPE,
"uint": code.DATATYPE, "uint8": code.DATATYPE, "uint16": code.DATATYPE, "uint32": code.DATATYPE, "uint64": code.DATATYPE,
"float32": code.DATATYPE, "float64": code.DATATYPE, "complex64": code.DATATYPE, "complex128": code.DATATYPE,
"rune": code.DATATYPE, "string": code.DATATYPE, "byte": code.DATATYPE, "uintptr": code.DATATYPE,
"bool": code.DATATYPE, "error": code.DATATYPE, "chan": code.DATATYPE, "map": code.DATATYPE,
"init": code.FUNCTION, "main": code.FUNCTION, "print": code.FUNCTION, "println": code.FUNCTION, "panic": code.FUNCTION, "recover": code.FUNCTION,
"new": code.FUNCTION, "make": code.FUNCTION, "len": code.FUNCTION, "cap": code.FUNCTION, "copy": code.FUNCTION, "append": code.FUNCTION, "delete": code.FUNCTION, "close": code.FUNCTION,
"complex": code.FUNCTION, "real": code.FUNCTION, "imag": code.FUNCTION,
"If": code.KEYWORD, "For": code.KEYWORD, "Switch": code.KEYWORD,
"kit": code.PACKAGE, "ice": code.PACKAGE, "m": code.OBJECT, "msg": code.OBJECT,
"Any": code.DATATYPE, "List": code.DATATYPE, "Map": code.DATATYPE, "Maps": code.DATATYPE, "Message": code.DATATYPE,
},
func: function(can, push, text, indent, opts) { var ls = can.core.Split(text, "\t *", "({:})")
function isKey() { return opts.block == "cmds" && ls[1] == ":" && ls[2] == "{" } function isEnd() { return ls[0] == "}" }
function prefix(key, pre) { return key.slice(0, 1).toLowerCase() == key.slice(0, 1)? "- ": ("+ "+(pre? pre+nfs.PT: "")) }
if (indent == 0) { switch (ls[0]) {
case "package": opts.package = ls[1]; break
case "func": if (ls[1] == "(") { var p = ls.indexOf(")"); push(prefix(ls[p+1])+ls[2]+nfs.PT+ls[p+1]+"()"); break }
case "const":
case "var": if (ls[1] == "(") { break } // ")"
case "type": push(prefix(ls[1])+ls[1]+(ls[0]=="type"? "{}": ls[0]=="func"? "()": "")); break
} opts.stack = [ls[0]] } else if (indent == 4 && opts.stack[0] == "func") {
if (text.indexOf("MergeCommands(") > -1) { opts.block = "cmds" } else if (text.indexOf("}") == 0) { opts.block = "" }
} else if (indent == 8) {
if (isKey()) { push(prefix(ls[0], opts.package)+ls[0]), opts.cmds = ls[0] }
// if (isKey()) { push(prefix(ls[0], opts.package)+ls[0]), opts.cmds = opts.package+nfs.PT+ls[0] }
} else if (indent == 12) {
if (isKey()) { push("+ "+opts.cmds+lex.SP+ls[0]) }
}
},
},
mod: {prefix: {"//": code.COMMENT}, split: {operator: "(=>)"}, keyword: {
"go": code.KEYWORD, "module": code.KEYWORD, "require": code.KEYWORD, "replace": code.KEYWORD,
}}, sum: {}, work: {keyword: {go: code.KEYWORD, use: code.KEYWORD}},
js: {prefix: {"// ": code.COMMENT}, regexp: {"[A-Z_0-9]+": code.CONSTANT},
keyword: {
"let": code.KEYWORD, "const": code.KEYWORD, "var": code.KEYWORD,
"if": code.KEYWORD, "else": code.KEYWORD,
"switch": code.KEYWORD, "case": code.KEYWORD, "default": code.KEYWORD,
"for": code.KEYWORD, "in": code.KEYWORD, "while": code.KEYWORD, "break": code.KEYWORD, "continue": code.KEYWORD,
"try": code.KEYWORD, "catch": code.KEYWORD, "debugger": code.KEYWORD,
"function": code.KEYWORD, "return": code.KEYWORD, "arguments": code.OBJECT, "callee": code.OBJECT, "this": code.OBJECT,
"true": code.CONSTANT, "false": code.CONSTANT, "null": code.CONSTANT, "undefined": code.CONSTANT,
"parseInt": code.FUNCTION, "parseFloat": code.FUNCTION, "encodeURIComponent": code.FUNCTION, "decodeURIComponent": code.FUNCTION,
"setTimeout": code.FUNCTION, "alert": code.FUNCTION, "confirm": code.FUNCTION, "prompt": code.FUNCTION,
"document": code.OBJECT, "console": code.OBJECT,
"location": code.OBJECT, "history": code.OBJECT,
"window": code.OBJECT, "navigator": code.OBJECT,
"localStorage": code.OBJECT, "sessionStorage": code.OBJECT,
"typeof": code.KEYWORD, "new": code.KEYWORD, "delete": code.KEYWORD,
"import": code.KEYWORD, "from": code.KEYWORD, "export": code.KEYWORD, "default": code.KEYWORD,
"class": code.KEYWORD, "static": code.KEYWORD,
"async": code.KEYWORD, "await": code.KEYWORD,
"Array": code.DATATYPE, "JSON": code.DATATYPE, "Date": code.DATATYPE, "Math": code.DATATYPE, "XMLHttpRequest": code.DATATYPE, "WebSocket": code.DATATYPE,
"hasOwnProperty": code.FUNCTION, "isArray": code.FUNCTION, "forEach": code.FUNCTION, "apply": code.FUNCTION, "call": code.FUNCTION,
"length": code.FUNCTION, "split": code.FUNCTION, "trim": code.FUNCTION, "toLowerCase": code.FUNCTION, "indexOf": code.FUNCTION, "lastIndexOf": code.FUNCTION,
"concat": code.FUNCTION, "reverse": code.FUNCTION, "slice": code.FUNCTION, "join": code.FUNCTION, "sort": code.FUNCTION, "push": code.FUNCTION, "pop": code.FUNCTION,
"stringify": code.FUNCTION, "parse": code.FUNCTION,
"require": code.FUNCTION,
"kit": code.CONSTANT, "ice": code.CONSTANT,
"ctx": code.CONSTANT, "mdb": code.CONSTANT, "web": code.CONSTANT, "aaa": code.CONSTANT,
"tcp": code.CONSTANT, "nfs": code.CONSTANT, "cli": code.CONSTANT, "log": code.CONSTANT,
"code": code.CONSTANT, "wiki": code.CONSTANT, "chat": code.CONSTANT, "team": code.CONSTANT, "mall": code.CONSTANT,
"http": code.CONSTANT, "html": code.CONSTANT, "icon": code.CONSTANT, "svg": code.CONSTANT,
"can": code.OBJECT, "msg": code.OBJECT, "cb": code.FUNCTION, "target": code.OBJECT, "event": code.OBJECT,
"Volcanos": code.FUNCTION, "shy": code.FUNCTION, "cbs": code.FUNCTION,
"res": code.OBJECT, "sub": code.OBJECT, "sup": code.OBJECT,
},
complete: function(event, can, msg, target, pre, key) {
var ls = can.core.Split(can.core.Split(pre, "\t {(:,)}").pop(), nfs.PT), list = {event: event, can: can, msg: msg, target: target, window: window}
can.core.ItemKeys(key == ""? list: can.core.Value(list, ls)||can.core.Value(window, ls)||window, function(k, v) {
msg.Push(mdb.NAME, k).Push(mdb.TEXT, (v+"").split(lex.NL)[0])
})
},
func: function(can, push, text, indent, opts) { var ls = can.core.Split(text, "\t (,", nfs.DF)
if (indent == 0 && can.base.beginWith(text, "Volcanos")) {
var _block = can.base.trimPrefix(ls[1], "chat.").toLowerCase()
if (_block != opts.block) { push("") } opts.block = _block
if (text.indexOf(chat._INIT) > -1) { push(opts.block+nfs.PT+chat._INIT) }
} else if (indent == 0 && can.base.beginWith(text, "var ")) {
opts.block = ls[1]
} else if (indent == 4 && ls[1] == nfs.DF) {
ls[0] && push(opts.block+nfs.PT+ls[0])
}
},
}, json: {split: {operator: "{[:,]}"}, keyword: {"true": code.CONSTANT, "false": code.CONSTANT}},
css: {
prefix: {"// ": code.COMMENT, "/* ": code.COMMENT},
split: {operator: "{[(.,:;<!=>)]}"},
regexp: {
"#[^ ;]+": code.STRING, "[-0-9]+(deg|rem|px|s|%)?": code.STRING,
"--[^ ();]+": code.CONSTANT,
},
keyword: {
"not": code.DATATYPE, "first-child": code.DATATYPE, "last-child": code.DATATYPE, "nth-child": code.DATATYPE,
"placeholder": code.DATATYPE, "hover": code.DATATYPE, "focus": code.DATATYPE,
"$body": code.KEYWORD, "$fieldset": code.KEYWORD,
"$option": code.KEYWORD, "$action": code.KEYWORD, "$output": code.KEYWORD, "$status": code.KEYWORD,
"$content": code.KEYWORD, "$profile": code.KEYWORD, "$display": code.KEYWORD, "$project": code.KEYWORD,
"output": code.KEYWORD,
"background-color": code.FUNCTION, "color": code.FUNCTION,
"font-family": code.FUNCTION, "font-weight": code.FUNCTION, "font-style": code.FUNCTION, "font-size": code.FUNCTION, "line-height": code.FUNCTION,
"text-align": code.FUNCTION, "white-space": code.FUNCTION, "word-break": code.FUNCTION, "letter-space": code.FUNCTION, "tab-size": code.FUNCTION,
"vertical-align": code.FUNCTION,
"padding": code.FUNCTION, "padding-left": code.FUNCTION, "padding-top": code.FUNCTION, "padding-right": code.FUNCTION, "padding-bottom": code.FUNCTION,
"border": code.FUNCTION, "border-left": code.FUNCTION, "border-top": code.FUNCTION, "border-right": code.FUNCTION, "border-bottom": code.FUNCTION,
"margin": code.FUNCTION, "margin-left": code.FUNCTION, "margin-top": code.FUNCTION, "margin-right": code.FUNCTION, "margin-bottom": code.FUNCTION,
"box-sizing": code.FUNCTION, "border-radius": code.FUNCTION, "outline": code.FUNCTION, "box-shadow": code.FUNCTION,
"height": code.FUNCTION, "width": code.FUNCTION, "min-width": code.FUNCTION, "max-width": code.FUNCTION, "min-height": code.FUNCTION, "max-height": code.FUNCTION,
"display": code.FUNCTION, "float": code.FUNCTION, "clear": code.FUNCTION, "visibility": code.FUNCTION, "overflow": code.FUNCTION,
"flex": code.FUNCTION, "align-items": code.FUNCTION, "justify-content": code.FUNCTION, "flex-direction": code.FUNCTION,
"flex-grow": code.FUNCTION, "flex-shrink": code.FUNCTION, "flex-wrap": code.FUNCTION,
"position": code.FUNCTION, "z-index": code.FUNCTION, "cursor": code.FUNCTION, "transition": code.FUNCTION,
"transform": code.FUNCTION, "translate": code.FUNCTION, "rotate": code.FUNCTION,
"stroke-width": code.FUNCTION, "stroke": code.FUNCTION, "fill": code.FUNCTION,
"transparent": code.CONSTANT,
"monospace": code.CONSTANT, "bold": code.CONSTANT, "italic": code.CONSTANT, "normal": code.CONSTANT,
"center": code.CONSTANT,
"border-box": code.CONSTANT,
"calc": code.KEYWORD, "important": code.KEYWORD,
"solid": code.CONSTANT, "dashed": code.CONSTANT,
"0": code.CONSTANT, "none": code.CONSTANT, "unset": code.CONSTANT,
"block": code.CONSTANT, "both": code.CONSTANT, "hidden": code.CONSTANT, "visible": code.CONSTANT, "auto": code.CONSTANT,
"wrap": code.CONSTANT, "column": code.CONSTANT, "row-reverse": code.CONSTANT,
"relative": code.CONSTANT, "absolute": code.CONSTANT, "sticky": code.CONSTANT, "static": code.CONSTANT, "fixed": code.CONSTANT,
"left": code.FUNCTION, "top": code.FUNCTION, "right": code.FUNCTION, "bottom": code.FUNCTION,
"pointer": code.CONSTANT, "copy": code.CONSTANT,
"black": code.CONSTANT, "white": code.CONSTANT,
"silver": code.CONSTANT, "gray": code.CONSTANT,
"red": code.CONSTANT, "blue": code.CONSTANT,
"cyan": code.CONSTANT, "aliceblue": code.CONSTANT,
"--plugin-bg-color": code.CONSTANT, "--plugin-fg-color": code.CONSTANT,
"--input-bg-color": code.CONSTANT, "--output-bg-color": code.CONSTANT,
"--danger-bg-color": code.CONSTANT, "--notice-bg-color": code.CONSTANT,
"--hover-bg-color": code.CONSTANT, "--hover-fg-color": code.CONSTANT,
"--body-bg-color": code.CONSTANT, "--body-fg-color": code.CONSTANT,
/*
"text-shadow": code.FUNCTION,
"caret-color": code.FUNCTION,
"type": code.FUNCTION, "name": code.FUNCTION,
"background": code.FUNCTION, "background-position": code.FUNCTION, "background-size": code.FUNCTION,
"dark": code.CONSTANT, "light": code.CONSTANT,
"yellow": code.CONSTANT,
"green": code.CONSTANT,
"purple": code.CONSTANT,
"navy": code.CONSTANT,
"teal": code.CONSTANT,
"gold": code.CONSTANT,
"orange": code.CONSTANT,
"lavender": code.CONSTANT,
"chocolate": code.CONSTANT,
"dimgray": code.CONSTANT,
"brown": code.CONSTANT,
"snow": code.CONSTANT,
"skyblue": code.CONSTANT,
"cadetblue": code.CONSTANT,
"cornflowerblue": code.CONSTANT,
"royalblue": code.CONSTANT,
"steelblue": code.CONSTANT,
"darkblue": code.CONSTANT,
"darkcyan": code.CONSTANT,
"darkgray": code.CONSTANT,
"darkgreen": code.CONSTANT,
"lightblue": code.CONSTANT,
"lightgray": code.CONSTANT,
"lightgreen": code.CONSTANT,
"magenta": code.CONSTANT,
"vertical-align": code.FUNCTION,
"url": code.FUNCTION,
"contexts": code.CONSTANT,
*/
}, include: ["html"],
func: function(can, push, text) { text.indexOf("/* ") == 0 && push(can.base.trimPrefix(can.base.trimSuffix(text, " */"), "/* ")) },
},
html: {split: {operator: "<!=/>"}, keyword: {
"DOCTYPE": code.KEYWORD, "html": code.KEYWORD, "head": code.KEYWORD, "body": code.KEYWORD,
"meta": code.KEYWORD, "title": code.KEYWORD, "link": code.KEYWORD, "script": code.KEYWORD,
"src": code.FUNCTION, "href": code.FUNCTION, "rel": code.FUNCTION, "style": code.FUNCTION,
"h1": code.KEYWORD, "h2": code.KEYWORD, "h3": code.KEYWORD,
"p": code.KEYWORD, "em": code.KEYWORD, "strong": code.KEYWORD, "sub": code.KEYWORD, "sup": code.KEYWORD, "i": code.KEYWORD, "b": code.KEYWORD, "u": code.KEYWORD,
"pre": code.KEYWORD, "code": code.KEYWORD, "var": code.KEYWORD, "kbd": code.KEYWORD, "samp": code.KEYWORD,
"ul": code.KEYWORD, "ol": code.KEYWORD, "li": code.KEYWORD,
"table": code.KEYWORD, "thead": code.KEYWORD, "tbody": code.KEYWORD, "tfoot": code.KEYWORD,
"tr": code.KEYWORD, "th": code.KEYWORD, "td": code.KEYWORD,
"colgroup": code.KEYWORD, "col": code.KEYWORD, "colspan": code.FUNCTION, "rowspan": code.FUNCTION,
"header": code.KEYWORD, "nav": code.KEYWORD, "main": code.KEYWORD, "aside": code.KEYWORD, "footer": code.KEYWORD, "article": code.KEYWORD, "section": code.KEYWORD,
"a": code.KEYWORD, "div": code.KEYWORD, "span": code.KEYWORD, "br": code.KEYWORD, "hr": code.KEYWORD,
"img": code.KEYWORD, "video": code.KEYWORD, "audio": code.KEYWORD, "canvas": code.KEYWORD, "iframe": code.KEYWORD,
"svg": code.KEYWORD, "rect": code.KEYWORD, "circle": code.KEYWORD,
"fieldset": code.KEYWORD, "legend": code.KEYWORD, "form": code.KEYWORD, "label": code.KEYWORD,
"select": code.KEYWORD, "option": code.KEYWORD, "input": code.KEYWORD, "textarea": code.KEYWORD, "button": code.KEYWORD,
"height": code.FUNCTION, "width": code.FUNCTION,
}},
})

View File

@ -0,0 +1,25 @@
Volcanos("onimport", {help: "导入数据", _init: function(can, args, cb) {
can.onimport.toolkit(can, {index: "web.code.template"}, function(sub) {
sub.run = function(event, cmds, cb) { var msg = sub.request(event, can.Option())
if (can.misc.runAction(can, msg, cmds, cb, kit.Dict(
nfs.DEFS, function(cmds) {
can.user.input(event, can, can.base.Obj(msg.Option("args")||"[]"), function(ev, button, data, list, args) {
var msg = can.request(event); can.core.Item(data, function(key, value) { msg.Option(key, value) })
can.run(event, [ctx.ACTION, ice.RUN, "web.code.template", nfs.DEFS].concat(cmds), function(msg) {
can.base.isFunc(cb) && cb(msg)
can.onimport.project(can, can.Option(nfs.PATH))
can.onimport.tabview(can, can.Option(nfs.PATH), msg.Option("main"), "", function() {
can.onimport.tabview(can, can.Option(nfs.PATH), cmds[1], 1, function() {})
}, true)
}, true)
})
},
))) { return }
can.run(event, [ctx.ACTION, ice.RUN, "web.code.template"].concat(cmds), function(msg) {
can.base.isFunc(cb) && cb(msg)
}, true)
}, can.base.isFunc(cb) && cb(sub)
})
}})

View File

@ -0,0 +1,32 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.onmotion.clear(can)
if (msg.Option("content")) {
can.onappend.plugin(can, {index: "web.code.vimer", style: "full"}, function(sub) {
sub.run = function(event, cmds, cb) { var res = can.request(event)
if (cmds[1] == "plugin") {
can.run(event, can.misc.concat(can, ["action", "vimer"], cmds), cb, true)
return
}
if (cmds[1] == "main.go") { res.Echo(msg.Option("content"))
can.core.Timer(100, function() { can.sub && can.sub.onaction["项目"]({}, can.sub) })
}
cb(res), can.sub = can.core.Value(sub, "_outputs.-1")
}
}, can._output)
return
}
can.onappend.table(can, msg)
can.onappend.board(can, msg)
},
})
Volcanos("onaction", {help: "操作数据", list: [], _init: function(can, msg, list, cb, target) {
},
run: function(event, can, msg) {
can.run(event, [ctx.ACTION, ice.RUN, "go", "hi.go", can.sub.onexport.content(can.sub)], function(msg) {
can.onappend.board(can, msg)
}, true)
},
})
Volcanos("onexport", {help: "导出数据", list: [], _init: function(can, msg, list, cb, target) {
}})

View File

@ -1,22 +1,15 @@
fieldset.vimer>div.output.source>div.project div.item.select { border-right:var(--box-border3); } fieldset.vimer>div.output input.current {
fieldset.vimer>div.output.source>div.layout>div.tabs>div.tabs>div.tabs.select { border-top:var(--box-border3); } background-color:#00000000; color:#00000000;
fieldset.vimer>div.output.source.normal>div.project div.expand.open { color:var(--notice-bg-color); } font-size:1em; font-family:monospace;
fieldset.vimer>div.output.source.normal>div.project div.item.select { border-right:var(--box-notice3); } position:absolute; left:0;
fieldset.vimer>div.output.source.normal>div.layout>div.tabs>div.tabs>div.tabs.select { border-top:var(--box-notice3); } margin:0; margin-top:-2px;
fieldset.vimer>div.output.source.normal>div.layout>div.path span.mode.normal { color:var(--notice-bg-color); } padding:0; padding-left:9px;
fieldset.vimer>div.output.source.normal>div.layout>div.layout>div.content tr.line.select>td.line { background-color:var(--notice-bg-color); color:white; } width:-webkit-fill-available;
fieldset.vimer>div.output.source.normal>div.layout>div.layout>div.content input.current { border:var(--box-notice); caret-color:var(--notice-bg-color); } tab-size:4;
fieldset.vimer>div.output.source.insert>div.project div.expand.open { color:var(--danger-bg-color); } }
fieldset.vimer>div.output.source.insert>div.project div.item.select { border-right:var(--box-danger3); } fieldset.vimer>div.output input.current.insert {
fieldset.vimer>div.output.source.insert>div.layout>div.tabs>div.tabs>div.tabs.select { border-top:var(--box-danger3); } caret-color:yellow;
fieldset.vimer>div.output.source.insert>div.layout>div.path span.mode.insert { color:var(--danger-bg-color); } }
fieldset.vimer>div.output.source.insert>div.layout>div.layout>div.content tr.line.select>td.line { background-color:var(--danger-bg-color); color:white; } fieldset.vimer>div.output input.current.normal {
fieldset.vimer>div.output.source.insert>div.layout>div.layout>div.content input.current { border:var(--box-danger); caret-color:var(--danger-bg-color); } caret-color:blue;
fieldset.vimer>div.output.source.insert>div.layout>div.layout>div.content div.complete:not(.hide) { display:block; top:unset; } }
fieldset.vimer>div.output.source>div.layout>div.layout input.current { background-color:transparent; color:transparent; padding-left:var(--input-padding); height:var(--code-line-height); position:absolute; }
fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete { background-color:unset; padding-top:0; height:1px; overflow:visible; display:none; position:absolute; }
fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete div.prefix { color:transparent; white-space:pre; float:left; }
fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete table.content { box-shadow:var(--plugin-box-shadow); padding-left:var(--input-padding); width:unset; max-width:600px; display:block; }
fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete table.content thead { display:none; }
fieldset.vimer>div.output.source>div.layout>div.layout>div.content div.complete table.content td:first-child { padding-left:0; }
fieldset.vimer>div.output>div.layout>div.tabs>div.tabs>div.tabs.origin.select { border-top:var(--box-danger3); }

View File

@ -1,323 +1,196 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, cb, target) {
_init: function(can, msg, cb) { can.onappend.style(can, code.VIMER); if (can.user.mod.isPod) { delete(can.onfigure.space) } can.require(["inner.js"], function(can) { can.onimport.inner_init(can, msg, function() {
can.require(["/plugin/local/code/inner.js"], function(can) { can.onimport._last_init(can, msg, function() { can.onkeymap._build(can), can.onimport._input(can), can.onkeymap._plugin({}, can), can.base.isFunc(cb) && cb(msg)
can.db.undo = [], can.db.redo = [], can.onimport._input(can), cb && cb(msg) }, target) }, function(can, name, sub) { name == chat.ONIMPORT && (can.onimport.inner_init = sub._init)
}) }) if (name == chat.ONKEYMAP) {
can.base.Copy(can.onkeymap._mode, sub._mode)
can.core.Item(can.onkeymap._mode.normal, function(k, v) {
if (!sub._mode.plugin[k]) { sub._mode.plugin[k] = v }
})
can.core.Item(sub._mode.plugin, function(k, v) {
if (!can.onkeymap._mode.normal[k]) { can.onkeymap._mode.normal[k] = v }
})
}
})
}, },
_input: function(can) { var ui = can.page.Append(can, can.ui.content.parentNode, [ _input: function(can) {
{view: [code.CURRENT, html.INPUT], spellcheck: false, onkeydown: function(event) { if (event.metaKey) { return } can.ui.current = can.page.Append(can, can.ui.content.parentNode, [
can.onimport._value(can), can.onkeymap._parse(event, can, can.db.mode+(event.ctrlKey? "_ctrl": ""), can.ui.current) {view: ["current", html.INPUT], onkeydown: function(event) { if (event.metaKey) { return }
if (can.db.mode == mdb.INSERT) { can.ui.current._keylist = [] } can.misc.Debug("key", event.key)
if (can.db.mode == mdb.NORMAL) { can.onkeymap.prevent(event) } can._keylist = can.onkeymap._parse(event, can, can.mode+(event.ctrlKey? "_ctrl": ""), can._keylist, can.ui.current)
}, onkeyup: function(event) { if (event.metaKey) { return } can.mode == "insert" && can.core.Timer(10, function() { can.current.text(can.ui.current.value) })
can.onimport._value(can); can.onkeymap._complete(event, can) can.mode == "normal" && can.Status("按键", can._keylist.join(""))
}, onclick: function(event) { can.onkeymap._insert(event, can) can.mode == "normal" && can.onkeymap.prevent(event)
}}, {view: [[code.COMPLETE]]}, }, onclick: function(event) { can.onkeymap._insert(event, can) },
]); can.ui.current = ui.current, can.ui.complete = ui.complete, can.onkeymap._plugin(can) }, ondblclick: function(event) { var target = event.target
_value: function(can) { can.onimport.__tabPath(can, true) can.onaction.searchLine(event, can, target.value.slice(target.selectionStart, target.selectionEnd))
can.db.mode == mdb.INSERT && can.onmotion.delay(can, function() { can.current.text(can.ui.current.value) }) },
},
]).first
}, },
}, [""]) }, [""])
Volcanos(chat.ONFIGURE, { Volcanos("onkeymap", {help: "键盘交互", list: [],
source: function(can, target, zone, hash) { var args = [can.Option(nfs.PATH), can.Option(nfs.FILE)] _model: function(can, value) { can.Status("模式", can.mode = value)
can.run({}, [ctx.ACTION, nfs.REPOS], function(msg) { var paths = can.db.paths return can.page.Modify(can, can.ui.current, {className: "current"+ice.SP+can.mode}), value
can.core.List(paths.concat(msg.Table(function(value) { return value.path })), function(p) {
if (can.base.beginWith(p, nfs.USR_LOCAL_WORK) || can.base.isIn(p,
nfs.USR_ICONS,
"usr/material/",
nfs.USR_NODE_MODULES,
nfs.USR_WEBSOCKET,
nfs.USR_GO_QRCODE,
nfs.USR_GO_GIT,
nfs.USR_GEOAREA,
)) { return }
if (p && paths.indexOf(p) == -1 && p[0] != nfs.PS) { paths.push(p) }
})
function show(target, zone, path) { can.run(can.request({}, {dir_root: path, dir_deep: true}), [nfs.PWD], function(msg) {
var cache, list = can.core.List(msg.Table(), function(value) {
if (path == nfs.SRC && can.base.isIn(value.path,
"main.svg",
"main.ico",
"main.png",
"main.jpg",
"qrcode.jpg",
"version.go",
"binpack.go",
"binpack_usr.go",
)) { return }
if (path == nfs.USR_RELEASE && can.base.isIn(value.path, "conf.go", "binpack.go")) { return }
if (path == args[0] && args[1] == value.path) { value.expand = true }
return value
}); can.onmotion.clear(can, target), zone._total(msg.Length())
cache = can.onimport.tree(can, list, function(event, item, target) {
can.base.endWith(item.path, nfs.PS) || can.onimport.tabview(can, path, item.path, "", function(msg) { msg._item = target })
}, function(event, item, target) {
var msg = can.request(event); msg.Option(nfs.PATH, path), msg.Option(nfs.FILE, item.path)
}, target, cache)
can.onmotion.delay(can, function() { hash.length > 1 && can.onimport.openzone(can, hash[0], hash[1], hash[2]) && can.onimport.tabview(can, hash[0], hash[1], hash[2]), hash = [] })
can.onimport._zone_icon(can, msg, zone, function(event, button) { can.onaction._runs(event, can, button) })
}, true) } if (paths.length == 1) { return show(target, zone, paths[0]) } can.page.Remove(can, zone._action)
can.onimport.zone(can, can.core.List(paths, function(path) {
return kit.Dict(mdb.NAME, path, path == args[0]? chat._INIT: chat._DELAY_INIT, function(target, zone) { show(target, zone, path) })
}), target)
})
}, },
space: function(can, target, zone, hash) { can.onimport._zone(can, zone, web.DREAM, mdb.NAME, hash), zone.toggle(false) }, _plugin: function(event, can) { can.onkeymap._model(can, "plugin")
}) can.ui.current.blur()
Volcanos(chat.ONACTION, {_trans: {input: {main: "程序", top: "顶域"}},
_run: function(event, can, button, args, cb) { can.runAction(event, button, args, cb||function(msg) {
can.onmotion.delay(can, function() { can.onimport.tabview(can, msg.Option(nfs.PATH), msg.Option(nfs.FILE)) }, 300)
can.ui.zone.source.refresh()
}) },
_runs: function(event, can, button, cb) { var meta = can.Conf(), msg = can.request(event); msg.Option(ctx.ACTION, button)
can.user.input(event, can, meta.feature[button], function(data, args) { msg.Option(data), can.onaction._run(event, can, button, args, cb) })
}, },
save: function(event, can, button) { _normal: function(event, can) { can.onkeymap._model(can, "normal")
can.request(event, {file: can.Option(nfs.FILE), content: can.onexport.content(can), _toast: button}) can.ui.current.focus(), can.ui.content.scrollLeft -= 10000
can.onaction._run(event, can, button, [can.onexport.parse(can), can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) {
can.onaction.reload(can, msg)
})
}, },
reload: function(can, msg) { _insert: function(event, can) { can.onkeymap._model(can, "insert")
function imports(str) { var block = "", count = 0; can.core.List(str.split(lex.NL), function(text) { can.ui.current.focus(), can.ui.content.scrollLeft -= 10000
if (can.base.beginWith(text, "import (")) { block = can.core.Split(text)[0]; return } can.onkeymap.prevent(event)
if (can.base.beginWith(text, ")")) { block = ""; return }
if (can.base.beginWith(text, "import ")) { count++; return }
if (block == "import") { count++ }
}); return count }
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(text) { can.onaction.appendLine(can, text) })
can.onaction.selectLine(can, line+imports(msg.Result())-imports(msg.Option(nfs.CONTENT)))
}
if (can.base.isIn(can.onexport.parse(can), nfs.JS, nfs.JSON)) {
var line = can.onaction.selectLine(can); can.onmotion.clear(can, can.ui.content), can.ui.content._max = 0
can.core.List(msg.Option("content").split(lex.NL), function(text) { can.onaction.appendLine(can, text) })
can.onaction.selectLine(can, line)
}
}, },
trash: function(event, can, button) { var msg = can.request(event), p = msg.Option(nfs.PATH)+msg.Option(nfs.FILE)
can.onaction._run(event, can, button, [p], function(msg) { can.ui.zone.source.refresh() })
},
script: function(event, can, button) { can.onaction._runs(event, can, button) },
create: function(event, can, button) { can.onaction._runs(event, can, button) },
module: function(event, can, button) { can.onaction._runs(can.request(event, {title: can.user.trans(can, button, "创建模块")}), can, button) },
compile: function(event, can, button) { var msg = can.request(event, {_toast: button})
can.runAction(event, button, [], function(msg) { can.ui.search && can.ui.search.hidden()
if (msg.Length() > 0 || msg.Result()) { return can.onimport.exts(can, "inner/search.js", function(sub) { can.ui.search = sub, sub.select()
can.onmotion.delay(can, function() { can.onappend._output(sub, msg, sub.Conf(ctx.DISPLAY)) })
}) } var toast = can.user.toastProcess(can, cli.RESTART); can.onmotion.delay(can, function() { toast.close(), can.user.toastSuccess(can, cli.RESTART) }, 3000)
})
},
"命令": function(event, can) { can.user.input(event, can, [{name: ctx.INDEX, need: "must"}, ctx.ARGS], function(data) {
can.onimport.tabview(can, "", data.index+(data.args? mdb.FS+data.args: ""), ctx.INDEX)
}) },
"插件": function(event, can) { can.user.input(can.request(event, {type: "plug"}), can, [{name: ctx.INDEX, need: "must"}, ctx.ARGS], function(list, data) {
var key = list.join(","), sub = can.db.toolkit[key]; if (sub) { return sub.select() }
can.onimport.toolkit(can, {index: data.index, args: can.core.Split(data.args||"")}, function(sub) { can.db.toolkit[key] = sub.select() })
}) },
"扩展": function(event, can) { can.user.input(can.request(event, {action: "extension"}), can, ["url"], function(list) {
var sub = can.db.toolkit[list[0]]; sub? sub.select(): can.onimport.exts(can, list[0])
}) },
insertLine: function(can, text, before) {
var line = can.onaction.appendLine(can, text)
before && can.ui.content.insertBefore(line, can.onaction._getLine(can, before))
return can.onaction.rerankLine(can), can.onexport.line(can, line)
},
deleteLine: function(can, line) {
line = can.onaction._getLine(can, line)
var next = line.nextSibling||line.previousSibling;
return can.page.Remove(can, line), can.onaction.rerankLine(can), next
},
_selectLine: function(can) { can.current && can.page.Select(can, can.current.line, "td.text", function(td) { var target = can.ui.current; if (!target) { return }
can.current.line.appendChild(target), can.page.style(can, target, html.LEFT, td.offsetLeft-1, html.TOP, td.offsetTop, html.WIDTH, can.base.Min(td.offsetWidth, can.ui.content.offsetWidth-can.page.Select(can, can.current.line, "td.line")[0].offsetWidth))
target.value = td.innerText, can.db.mode == mdb.NORMAL && can.onkeymap._normal(can)
can.onmotion.delay(can, function() { can.page.SelectChild(can, can.ui.complete, html.DIV, function(target) {
target.innerText = can.ui.current.value.slice(0, can.ui.current.selectionStart)
}) })
}) },
})
Volcanos(chat.ONKEYMAP, {
scrollHold: function(can, count, begin) { var top = can.ui.content.scrollTop, left = can.ui.content.scrollLeft
can.ui.current.focus(), count != undefined && can.onkeymap.cursorMove(can.ui.current, count, begin == undefined? count: begin)
can.ui.content.scrollTop = top, can.ui.content.scrollLeft = left
},
cursorDown: function(can, target) { if (!can.current.next()) { return }
var p = can.onkeymap.cursorMove(target); can.onaction.selectLine(can, can.current.next()), can.onkeymap.cursorMove(target, 0, p)
},
cursorUp: function(can, target) { if (!can.current.prev()) { return }
var p = can.onkeymap.cursorMove(target); can.onaction.selectLine(can, can.current.prev()), can.onkeymap.cursorMove(target, 0, p)
},
_model: function(can, mode) { can.db.mode = mode, can.onimport.__tabPath(can, true), can.onmotion.toggle(can, can.ui.complete, false)
can.core.List([mdb.NORMAL, mdb.INSERT], function(mode) { can.page.ClassList.del(can, can._output, mode) }), can.page.ClassList.add(can, can._output, mode)
},
_plugin: function(can) { can.onkeymap._model(can, mdb.PLUGIN), can.ui.current.blur() },
_normal: function(can) { can.onkeymap._model(can, mdb.NORMAL), can.onkeymap.scrollHold(can) },
_insert: function(event, can, count, begin) { can.onkeymap._model(can, mdb.INSERT), can.onkeymap.scrollHold(can, count, begin), can.onkeymap.prevent(event) },
_complete: function(event, can, target) { if (event == undefined || event.type == "click") { return } target = target||can.ui.complete
var pre = can.ui.current.value.slice(0, can.ui.current.selectionStart), key = can.core.Split(pre, "\t .[]", lex.SP).pop()||"", end = can.ui.current.value.slice(can.ui.current.selectionStart)
function show() { can.current.line.appendChild(target), key && can.onmotion.toggle(can, target, true)
can.page.style(can, target, html.LEFT, can.ui.current.offsetLeft, html.MARGIN_TOP, can.user.isChrome? can.current.line.offsetHeight: 5)
} show()
function update() { target._pre = pre, target._end = end, target._index = -1
can.runAction(can.request(event, {text: pre}, can.Option()), code.COMPLETE, [], function(msg) { can.page.Appends(can, target, [{view: [lex.PREFIX, html.DIV, pre]}])
var parse = can.onsyntax[can.onexport.parse(can)]; can.core.CallFunc(can.core.Value(parse, code.COMPLETE), [event, can, msg, target, pre, key])
can.core.Item(can.core.Value(parse, code.KEYWORD), function(key, value) { msg.Push(mdb.NAME, key) })
var table = can.onappend.table(can, msg, function(value, key, index) { return {text: [value, html.TD], onclick: function(event) { change(value) }} }, target)
can.page.style(can, table, html.MAX_HEIGHT, can.ui.content.offsetHeight-(can.current.line.offsetTop-can.ui.content.scrollTop)-can.current.line.offsetHeight)
show()
})
}
function change(key) { can.current.text(can.ui.current.value = target._pre+key+target._end), can.onkeymap.cursorMove(can.ui.current, target._pre.length+key.length, 0) }
function filter() { can.page.ClassList.set(can, can.ui.complete, html.HIDE, can.page.Select(can, target, [html.TBODY, html.TR], function(tr) {
if (!can.page.ClassList.set(can, tr, html.HIDE, can.page.Select(can, tr, html.TD, function(td) { if (td.innerText.toLowerCase().indexOf(key.toLowerCase()) == 0) { return td } }).length == 0)) { return tr }
}).length == 0) }
function select(index, total) { index = (index+(total+1))%(total+1); if (index == total) { can.current.text(can.ui.current.value = target._pre+target._end) }
can.page.Select(can, target, [html.TBODY, html.TR+html.NOT_HIDE], function(tr, i) { if (can.page.ClassList.set(can, tr, html.SELECT, i == index)) {
change(can.page.Select(can, tr, html.TD)[0].innerText)
} }); return index
}
if (event.ctrlKey) { if (event.type == "keyup") { var total = can.page.Select(can, target, [html.TBODY, html.TR+html.NOT_HIDE]).length; switch (event.key) {
case "n": target._index = select(target._index+1, total); can.onkeymap.prevent(event); break
case "p": target._index = select(target._index-1, total); can.onkeymap.prevent(event); break
default: return can.onkeymap.selectCtrlN(event, can, target, [html.TBODY, html.TR+html.NOT_HIDE], function(tr) { change(can.page.Select(can, tr, html.TD)[0].innerText) })
} return can.onkeymap.prevent(event) } return }
switch (pre.slice(-1)) {
case lex.TB:
case lex.SP:
case nfs.PT:
case "[": // ]
case "(": // )
case "{": update(); break // }
case "":
default: filter()
}
},
_mode: { _mode: {
plugin: { normal_ctrl: {
Escape: shy("清除浮窗", function(event, can) { can.onaction.clear(event, can) }), f: function(event, can, target, count) {
f: shy("打开文件", function(event, can) { can.onaction.open(event, can) }), var line = can.onaction.selectLine(event, can)+can.current.window()-3-can.current.scroll()
g: shy("查找搜索", function(event, can) { can.onaction.find(event, can) }), return can.current.scroll(line), can.onaction.selectLine(event, can, line), true
d: shy("查找函数", function(event, can) { can.page.Select(can, can.ui.path, "span.func", function(target) { target.click() }) }), },
n: shy("命令模式", function(event, can) { can.onaction.selectLine(can, can.onaction.selectLine(can)), can.onkeymap._normal(can) }), b: function(event, can, target, count) {
i: shy("插入模式", function(event, can) { can.onaction.selectLine(can, can.onaction.selectLine(can)), can.onkeymap._insert(event, can) }), var line = can.onaction.selectLine(event, can)-can.current.window()+3
s: shy("保存文件", function(event, can) { can.onaction.save(event, can, nfs.SAVE) }), return can.current.scroll(line), can.onaction.selectLine(event, can, line), true
c: shy("编译项目", function(event, can) { can.onaction.compile(event, can, code.COMPILE) }), },
v: shy("渲染界面", function(event, can) { can.onaction.show(event, can) }),
r: shy("执行命令", function(event, can) { can.onaction.exec(event, can) }),
t: shy("添加命令", function(event, can) { can.onaction["命令"](event, can) }),
p: shy("添加插件", function(event, can) { can.onaction["插件"](event, can) }),
l: shy("打开右边标签", function(can) { var next = can._tab.nextSibling; next && next.click() }),
h: shy("打开左边标签", function(can) { var prev = can._tab.previousSibling; prev && prev.click() }),
x: shy("关闭标签", function(can) { can._tab._close() }),
}, },
normal: { normal: {
s: shy("保存文件", function(event, can) { can.onaction.save(event, can, nfs.SAVE) }), escape: function(event, can) { can.onkeymap._plugin(event, can) },
c: shy("编译项目", function(event, can) { can.onaction.compile(event, can, code.COMPILE) }), ArrowLeft: function(event, can, target) { can.onkeymap.cursorMove(can, target, -1) },
v: shy("渲染界面", function(event, can) { can.onaction.show(event, can) }), ArrowRight: function(event, can, target) { can.onkeymap.cursorMove(can, target, 1) },
r: shy("执行命令", function(event, can) { can.onaction.exec(event, can) }), ArrowDown: function(event, can) { can.onaction.selectLine(event, can, can.current.next()) },
ArrowUp: function(event, can) { can.onaction.selectLine(event, can, can.current.prev()) },
Escape: shy("切换模式", function(can) { can.onkeymap._plugin(can) }), H: function(event, can, target) { can.onkeymap.cursorMove(can, target, 0, 0) },
ArrowLeft: shy("光标左移", function(can, target) { can.onkeymap.cursorMove(target, -1) }), h: function(event, can, target) { can.onkeymap.cursorMove(can, target, -1) },
ArrowRight: shy("光标右移", function(can, target) { can.onkeymap.cursorMove(target, 1) }), l: function(event, can, target) { can.onkeymap.cursorMove(can, target, 1) },
ArrowDown: shy("光标下移", function(can, target) { can.onkeymap.cursorDown(can, target) }), L: function(event, can, target) { can.onkeymap.cursorMove(can, target, 0, -1) },
ArrowUp: shy("光标上移", function(can, target) { can.onkeymap.cursorUp(can, target) }), j: function(event, can) { can.onaction.selectLine(event, can, can.current.next()) },
H: shy("跳到行首", function(can, target) { can.onkeymap.cursorMove(target, 0, 0) }), k: function(event, can) { can.onaction.selectLine(event, can, can.current.prev()) },
L: shy("跳到行尾", function(can, target) { can.onkeymap.cursorMove(target, 0, -1) }),
h: shy("光标左移", function(can, target) { can.onkeymap.cursorMove(target, -1) }),
l: shy("光标右移", function(can, target) { can.onkeymap.cursorMove(target, 1) }),
j: shy("光标下移", function(can, target) { can.onkeymap.cursorDown(can, target) }),
k: shy("光标上移", function(can, target) { can.onkeymap.cursorUp(can, target) }),
I: shy("插入行首", function(event, can) { can.onkeymap._insert(event, can, 0, 0) }), gg: function(event, can, target, count) { return can.onaction.selectLine(event, can, count), true },
A: shy("插入行尾", function(event, can) { can.onkeymap._insert(event, can, 0, -1) }), G: function(event, can, target, count) { return can.onaction.selectLine(event, can, count = count>1? count: can.max), true },
i: shy("插入模式", function(event, can) { can.onkeymap._insert(event, can) }), zt: function(event, can, target, count) { return can.current.scroll(can.current.scroll()-(count>1? count: 3)), true },
a: shy("插入模式", function(event, can) { can.onkeymap._insert(event, can) }), zz: function(event, can, target, count) { return can.current.scroll(can.current.scroll()-(count = count>1? count: can.current.window()/2)), true },
o: shy("插入下一行", function(event, can) { var text = can.current.text() zb: function(event, can, target, count) { return can.current.scroll(can.current.scroll()-can.current.window()+(count>1? count: 5)), true },
text = text.substr(0, text.indexOf(text.trimLeft()))+(can.base.endWith(text, "{")? lex.TB: "")
can.onaction.selectLine(can, can.onaction.insertLine(can, text, can.current.next()))
can.onkeymap._insert(event, can, 0, -1)
}),
O: shy("插入上一行", function(event, can) { var text = can.current.text()
text = text.substr(0, text.indexOf(text.trimLeft()))+(can.base.beginWith(text, "}")? lex.TB: "")
can.onaction.selectLine(can, can.onaction.insertLine(can, text, can.current.line))
can.onkeymap._insert(event, can, 0, -1)
}),
yy: shy("复制当前行", function(event, can, target, count) { var list = [], line = can.current.line i: function(event, can) { can.onkeymap._insert(event, can) },
for (var i = 0; i < count; i++) { list.push(can.onexport.text(can, line)), line = line.nextSibling } can.db._last_text = list; return true I: function(event, can, target) { can.onkeymap._insert(event, can), can.onkeymap.cursorMove(can, target, 0, 0) },
}), a: function(event, can, target) { can.onkeymap._insert(event, can), can.onkeymap.cursorMove(can, target, 1) },
dd: shy("剪切当前行", function(event, can, target, count) { var line = can.onaction.selectLine(can), callee = arguments.callee A: function(event, can, target) { can.onkeymap._insert(event, can), can.onkeymap.cursorMove(can, target, 0, -1) },
var list = []; for (var i = 0; i < count; i++) { (function() { var line = can.onaction.selectLine(can), text = can.current.text(); list.push(text) o: function(event, can) { can.onkeymap._insert(event, can), can.onaction.selectLine(event, can, can.onaction.insertLine(can, "", can.current.next())) },
can.onaction.selectLine(can, can.onaction.deleteLine(can, line)), can.db.undo.push(function() { can.onaction.insertLine(can, text, line), can.onaction.selectLine(can, line) }) O: function(event, can) { can.onkeymap._insert(event, can), can.onaction.selectLine(event, can, can.onaction.insertLine(can, "", can.current.line)) },
})() } can.db._last_text = list, can.db.redo.push(function() { callee(event, can, target, count) })
return true
}),
p: shy("向后粘贴", function(can) { if (!can.db._last_text) { return } var line = can.onaction.selectLine(can), callee = arguments.callee
for (var i = can.db._last_text.length-1; i >= 0; i--) { (function() { var line = can.onaction.insertLine(can, can.db._last_text[i], can.current.next())
can.db.undo.push(function() { can.onaction.deleteLine(can, line), can.onaction.selectLine(can, line-1) })
})() } can.db.redo.push(function() { callee(event, can, target, count) })
}),
P: shy("向前粘贴", function(can) { if (!can.db._last_text) { return } var line = can.onaction.selectLine(can), callee = arguments.callee
for (var i = 0; i < can.db._last_text.length; i++) { (function() { var line = can.onaction.insertLine(can, can.db._last_text[i], can.current.line)
can.db.undo.push(function() { can.onaction.deleteLine(can, line), can.onaction.selectLine(can, line+1) })
})() } can.db.redo.push(function() { callee(event, can, target, count) })
}),
J: shy("合并两行", function(can) { var next = can.current.next(); if (!next) { return }
var line = can.onaction.selectLine(can), text = can.current.text(), rest = can.onexport.text(can, next)
can.ui.current.value = can.current.text(text.trimRight()+(can.base.endWith(text.trim(), "(", "[")||can.base.beginWith(rest.trim(), ",", "]", ")")? "": lex.SP)+rest.trimLeft())
can.onkeymap.cursorMove(can.ui.current, text.length, 0), can.onaction.deleteLine(can, next)
can.db.undo.push(function() { can.onaction.modifyLine(can, line, text), can.onaction.insertLine(can, rest, line+1) })
}),
".": shy("重复操作", function(can) { var cb = can.db.redo.pop(); cb && cb() }),
u: shy("撤销操作", function(can) { var cb = can.db.undo.pop(); cb && cb() }),
gg: shy("跳到某行", function(can, count) { return can.onaction.selectLine(can, count), true }), yy: function(event, can, target, count) { can._last_text = can.current.text() },
G: shy("跳到某行", function(can, count) { return can.onaction.selectLine(can, count = count>1? count: can.db.max), true }), dd: function(event, can, target, count) { can._last_text = can.current.text(), can.onaction.selectLine(event, can, can.onaction.deleteLine(can, can.current.line)) },
zt: shy("屏幕最上", function(can, count) { return can.current.scroll(can.current.scroll()-(count>1? count: 3)), true }), p: function(event, can) { can.onaction.insertLine(can, can._last_text, can.current.next()) },
zz: shy("屏幕中间", function(can, count) { return can.current.scroll(can.current.scroll()-(count = count>1? count: can.current.window()/2)), true }), P: function(event, can) { can.onaction.insertLine(can, can._last_text, can.current.line) },
zb: shy("屏幕最下", function(can, count) { return can.current.scroll(can.current.scroll()-can.current.window()+(count>1? count: 5)), true }),
F5: shy("刷新网页", function(can, target) { can.user.reload(true) }), s: function(event, can) { can.onaction.save(event, can) },
}, m: function(event, can) { can.onaction.autogen(event, can, "autogen") },
normal_ctrl: { c: function(event, can) { can.onaction.compile(event, can, "compile") },
e: shy("向上滚屏", function(can) { can.current.scroll(1); if (can.current.scroll()<2) { can.onaction.selectLine(can, can.current.next()) } }),
y: shy("向下滚屏", function(can) { can.current.scroll(-1); if (can.current.scroll()>can.current.window()-3) { can.onaction.selectLine(can, can.current.prev()) } }),
f: shy("向下翻页", function(can, count) { can.current.scroll(can.current.window()) }),
b: shy("向上翻页", function(can, count) { can.current.scroll(-can.current.window()) }),
r: shy("刷新页面", function(can) { can.user.reload(true) }),
},
insert_ctrl: {
a: shy("光标行首", function(can, target) { for (var i = 0; i < target.value.length; i++) { if (target.value[i] != lex.TB) { break } } can.onkeymap.cursorMove(target, i, 0), can.onkeymap.prevent(event) }),
e: shy("光标行尾", function(can, target) { can.user.isWindows && can.onkeymap.cursorMove(target, 0, -1) }),
b: shy("光标左移", function(can, target) { can.user.isWindows && can.onkeymap.cursorMove(target, -1) }),
f: shy("光标右移", function(can, target) { can.user.isWindows && can.onkeymap.cursorMove(target, 1) }),
d: shy("删除字符", function(can, target) { can.user.isWindows && can.onkeymap.deleteText(target, target.selectionStart, 1) }),
}, },
insert: { insert: {
Escape: shy("退出编辑", function(can) { can.onkeymap._normal(can), can.ui.current._keylist = [] }), jk: function(event, can, target) { can.onkeymap._normal(event, can),
ArrowUp: shy("光标上移", function(can, target) { can.onkeymap.cursorUp(can, target) }), can.onkeymap.deleteText(target, target.selectionStart-1, 1)
ArrowDown: shy("光标下移", function(can, target) { can.onkeymap.cursorDown(can, target) }), can.current.text(can.ui.current.value)
Backspace: shy("删除字符", function(event, can, target) { if (target.selectionStart > 0 || !can.current.prev()) { return } can.onkeymap.prevent(event) },
var rest = can.current.text(); can.onaction.selectLine(can, can.current.prev()), can.onaction.deleteLine(can, can.current.next()) Escape: function(event, can) { can.onkeymap._normal(event, can) },
var text = can.current.text(); can.ui.current.value = text+rest, can.onkeymap.cursorMove(target, 0, text.length) Tab: function(event, can) {
}), can.onkeymap.insertText(can.ui.current, "\t")
Tab: shy("添加缩进", function(event, can) { can.onkeymap.insertText(can.ui.current, lex.TB), can.onkeymap.prevent(event) }), can.onkeymap.prevent(event)
Enter: shy("插入换行", function(can, target) { },
var rest = can.onkeymap.deleteText(target, target.selectionEnd).trimLeft(), text = can.ui.current.value
var left = text.substr(0, text.indexOf(text.trimLeft()))||(text.trimRight() == ""? text: "") Enter: function(event, can, target) {
var line = can.onaction.selectLine(can), next = rest; for (var i = line; i < can.db.max; i++) { next += can.onexport.text(can, can.onaction._getLine(can, i)).trimLeft(); if (next != "") { break } } var line = can.onaction.insertLine(can, can.onkeymap.deleteText(target, target.selectionEnd), can.current.next())
function deep(text) { var deep = 0; for (var i = 0; i < text.length; i++) { if (text[i] == lex.TB) { deep += 4 } else if (text[i] == lex.SP) { deep++ } else { break } } return deep } can.current.text(can.ui.current.value), can.onaction.selectLine(event, can, line)
text.trim() && can.core.List(["{}", "[]", "()", "``"], function(item) { if (can.base.endWith(text, item[0])) { },
if (can.base.beginWith(next, item[1])) { Backspace: function(event, can, target) {
can.onaction.insertLine(can, left+rest, can.current.next()), rest = "" if (target.selectionStart > 0) { return }
} else if (deep(text) >= deep(can.onexport.text(can, can.onaction._getLine(can, line+1))) && rest == "") { if (!can.current.prev()) { return }
can.onaction.insertLine(can, left+item[1], can.current.next()) can.onkeymap.prevent(event)
} left += lex.TB
} else if (can.base.beginWith(rest, item[1])) { left = left.slice(0, -1) }}) var rest = can.current.text()
var line = can.onaction.insertLine(can, left+rest, can.current.next()) can.onaction.selectLine(event, can, can.current.prev())
can.current.text(text.trimRight()||text), can.onaction.selectLine(can, line), can.onkeymap._insert(event, can, 0, left.length) can.onaction.deleteLine(can, can.current.next())
}), var pos = can.current.text().length
can.ui.current.value = can.current.text()+rest
can.onkeymap.cursorMove(can, can.ui.current, 0, pos)
},
ArrowUp: function(event, can) { can.onaction.selectLine(event, can, can.current.prev()) },
ArrowDown: function(event, can) { can.onaction.selectLine(event, can, can.current.next()) },
}, },
}, _engine: {}, }, _engine: {},
}) })
Volcanos("onaction", {help: "控件交互", list: ["加载", nfs.SAVE, "autogen", "compile", "binpack", "刷新"],
"刷新": function(event, can) {
can.onimport.tabview(can, "src/", "main.go", "", function() {}, true)
},
"加载": function(event, can) {
var file = "/share/local/"+can.Option(nfs.PATH)+can.Option(nfs.FILE)
delete(Volcanos.meta.cache[file])
// var script = `\n_can_name = "`+file+`"\n`+
// can.onexport.content(can)+
// `\n_can_name = ""\nconsole.log("once")`
// eval(script)
},
save: function(event, can) { var msg = can.request(event, {content: can.onexport.content(can)})
can.run(event, [ctx.ACTION, nfs.SAVE, can.parse, can.Option(nfs.FILE), can.Option(nfs.PATH)], function(msg) {
can.user.toastSuccess(can)
}, true)
},
autogen: function(event, can, button) { var meta = can.Conf(), msg = can.request(event, {_handle: ice.TRUE})
can.user.input(event, can, meta.feature[button], function(ev, btn, data, list, args) {
can.run(event, [ctx.ACTION, button].concat(args), function(msg) {
can.onimport.tabview(can, can.Option(nfs.PATH), msg.Option(nfs.FILE))
can.onimport.project(can, can.Option(nfs.PATH))
}, true)
})
},
compile: function(event, can, button) { var msg = can.ui.search.request(event, {_handle: ice.TRUE, _toast: "编译中..."})
can.run(event, [ctx.ACTION, button], function(msg) {
if (msg.Length() == 0) { var toast = can.user.toast(can, "重启中...", "", -1)
can.core.Timer(5000, function() { toast.close(), can.onaction["展示"]({}, can) })
} else {
can.ui.search._show(msg)
}
}, true)
},
_selectLine: function(event, can) {
can.page.Select(can, can.current.line, "td.text", function(td) { can.current.line.appendChild(can.ui.current)
can.page.Modify(can, can.ui.current, {style: kit.Dict(html.LEFT, td.offsetLeft-1, html.WIDTH,td.offsetWidth-12), value: td.innerText})
if (event) { if (can.mode == "plugin") { can.onkeymap._insert(event, can) }
can.ui.current.focus(), can.onkeymap.cursorMove(can, can.ui.current, 0, (event.offsetX)/13-1)
can.ui.content.scrollLeft -= 10000
}
})
},
rerankLine: function(can, value) { can.max = 0
can.page.Select(can, can.ui.content, html.TR, function(item, index) {
can.max++, can.page.Select(can, item, "td.line", function(item) { item.innerText = index+1 })
})
},
insertLine: function(can, value, before) {
var line = can.onaction.appendLine(can, value)
before && can.ui.content.insertBefore(line, before)
return can.onaction.rerankLine(can), line
},
deleteLine: function(can, line) {
var next = line.nextSibling||line.previousSibling
can.page.Remove(can, line), can.onaction.rerankLine(can)
return next
},
modifyLine: function(can, line, value) {
can.page.Select(can, can.ui.content, html.TR, function(item, index) {
if (item != line && index+1 != line) { return }
can.page.Select(can, item, "td.text", function(item) {
can.page.Appends(can, item, [can.onsyntax._parse(can, value)])
})
})
},
})
Volcanos("onexport", {help: "导出数据", list: ["文件数", "模式", "按键", "解析器", "文件名", "当前行", "跳转数"]})

View File

@ -1,76 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) { can.page.requireModules(can, ["xterm/css/xterm.css", "xterm", "xterm-addon-fit", "xterm-addon-web-links"], function() {
if (can.Option(mdb.HASH) || can.Option("args0") || can.ConfIndex() == "can._filter") { var item = can.base.Obj(msg.TableDetail()); item.hash = item.hash||can.Option(mdb.HASH)||can.Option("args0")||"current"
can.onimport._connect(can, item, can._output)
} else {
can.ui = can.onappend.layout(can), can.onimport._project(can, msg, can.db.hash)
} cb && cb(msg)
}) },
_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, value, target, function() { can.onappend._status(can)
value._term = can.onimport._connect(can, value, can.ui.content)
})
})
}) },
_connect: function(can, item, target, text) { can.onimport.layout(can)
var term = new Terminal({fontSize: html.CODE_FONT_SIZE, tabStopWidth: 4, cursorBlink: true, theme: can.onimport._theme(can, item)}); term._item = item
term.onTitleChange(function(title) { can.onexport.title(can, term, title) }), can.onexport.title(can, term, item.nick)
term.onResize(function(size) { can.onimport._resize(can, term, size) })
term.onData(function(data) { can.onimport._input(can, term, data) })
term.onCursorMove(function() { can.onexport.term(can, term) })
var fitAddon = new FitAddon.FitAddon(); term.loadAddon(fitAddon), term._fit = fitAddon, can.onmotion.delay(can, function() { fitAddon.fit() })
term.loadAddon(new WebLinksAddon.WebLinksAddon())
can.onmotion.clear(can, target), term.open(target), term.focus(), can.onmotion.delay(can, function() { term.focus() })
can.onengine.listen(can, chat.ONTHEMECHANGE, function() { term.selectAll(), can.onimport._connect(can, item, target, can.base.trimSuffix(term.getSelection(), lex.NL)) })
can.page.style(can, target, html.BACKGROUND_COLOR, term._publicOptions.theme.background||cli.BLACK)
return can.db[item.hash] = term
},
_theme: function(can, item) { return can.base.Obj(item.theme)||(
can.getHeaderTheme() == html.LIGHT? {background: "#0000", foreground: cli.BLACK, cursor: cli.BLUE}:
can.getHeaderTheme() == html.DARK? {background: "#0000", foreground: cli.SILVER, cursor: cli.SILVER}:
can.getHeaderTheme() == chat.BLACK? {background: "#0000", foreground: cli.CYAN, cursor: cli.WHITE}:
{background: "#0000", foreground: cli.BLACK, cursor: cli.BLUE}
) },
_resize: function(can, term, size) {
can.runAction(can.request({}, size, term._item), web.RESIZE, [], function(msg) {})
},
_input: function(can, term, data) {
can.runAction(can.request({}, {rows: term.rows, cols: term.cols}, term._item), html.INPUT, [btoa(data)], function(msg) {})
},
input: function(can, msg, hash, text) { var arg = msg.detail.slice(1); arg = [hash||arg[0], text||arg[1]]
term = can.db[arg[0]], can.onimport._input(can, term, arg[1])
},
grow: function(can, msg, hash, text) { var arg = msg.detail.slice(1); arg = [hash||arg[0], text||arg[1]], term = can.db[arg[0]]
if (arg[1] == "~~~end~~~") { arg[0] == "current"? can.sup.onmotion._close({}, can.sup): can.sup.onimport._back(can.sup) } else { term.write(arg[1]) }
},
layout: function(can) {
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight())
can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function() {
can.core.Item(can.db, function(hash, term) { term._fit && term._fit.fit() })
can.db.value && can.db.value._term && can.onexport.term(can, can.db.value._term)
}), can.core.Item(can.db, function(hash, term) { term._fit && term._fit.fit() })
},
})
Volcanos(chat.ONACTION, {
create: function(event, can) { can.user.input(event, can, [mdb.TYPE, mdb.NAME, mdb.TEXT], function(data) {
can.runAction(can.request({}, data), mdb.CREATE, [], function(msg) { var hash = msg.Result()
can.run(event, [hash], function(msg) { var _msg = can.request(); _msg.Push(msg.TableDetail())
can.onimport._project(can, _msg, [hash])
})
})
}) },
remove: function(event, can) { var item = event._msg.Option("_item")
can.runAction(event, mdb.REMOVE, [], function(msg) {
var value = item._item; value._tabs && value._tabs._close(), can.page.Remove(can, item)
})
},
})
Volcanos(chat.ONEXPORT, {list: [mdb.TIME, mdb.HASH, mdb.TYPE, mdb.NAME, "rows", "cols", "cursorY", "cursorX"],
term: function(can, term) { item = term._item, can.onexport.title(can, term, item.nick||item.name||item.type)
can.core.List(can.onexport.list, function(key) { if (key == mdb.TIME && !item[key]) { return } can.Status(key, can.base.getValid(item[key], term[key], term.buffer.active[key], "")+"") })
can.core.List([mdb.TIME, mdb.HASH, mdb.TYPE, mdb.NAME], function(key) { if (key == mdb.TIME && !item[key]) { return } can.Status(key, item[key]||"") })
},
title: function(can, term, title) { can.Status(mdb.NAME, title), can.sup.onexport.title(can.sup, title) },
})

View File

@ -1,19 +0,0 @@
fieldset.goods>div.output>div.project { flex:0 0 90px; }
fieldset.goods>div.output>div.project>div.item { border-right:var(--box-border3); text-align:center; padding:20px 10px; }
fieldset.goods>div.output>div.project>div.item.select {
border-right:var(--box-notice3);
position:unset;
}
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item:not(.hide) {
box-shadow:var(--th-box-shadow); border:var(--plugin-border); border-radius:var(--plugin-radius);
background-color:var(--plugin-bg-color); margin:10px; float:left; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div { padding:10px; float:left; clear:none; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.image { flex-grow:0; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.image>img { height:120px; width:120px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content { flex-grow:1; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.title { font-weight:bold; white-space:break-spaces; overflow:hidden; height:32px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.content { height:24px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.display { line-height:32px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.display>div { float:left; margin-right:5px; }
fieldset.goods>div.output>div.layout>div.layout>div.content>div.item>div.content div.price { color:red; }
body:not(.mobile) fieldset.goods>div.output>div.layout>div.layout>div.content>div.item:not(.hide) { height:150px; }

View File

@ -1,33 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { if (msg.IsDetail()) { return msg.Dump(can) }
var list = {}; can.ui = can.onappend.layout(can), can.onmotion.clear(can, can.ui.project)
can.page.Appends(can, can.ui.content, msg.Table(function(item, index) { var style = {}
if (!list[item.zone]) { if (can.user.isMobile && index > 0) { style["margin-top"] = "40px" }
list[item.zone] = item, item._zone = can.onimport.item(can, {name: item.zone}, function() {
can.onmotion.scrollIntoView(can, item._target, 10)
})
}
return {view: [[html.ITEM, html.FLEX]], style: style, list: [
{view: wiki.IMAGE, list: [{img: can.misc.MergeCache(can, can.core.Split(item.image)[0], item.space)}]},
{view: wiki.CONTENT, list: [
{view: [html.TITLE, html.DIV, item.name]},
{view: [html.CONTENT, html.DIV, item.text]},
{view: html.DISPLAY, list: [
item.area? {view: [mall.PRICE, html.DIV, "¥ "+(item.price||0)+" 万"]}: {view: [mall.PRICE, html.DIV, "¥ "+(item.price||0)]},
item.area? {view: [mall.COUNT, html.DIV, "面积 "+(item.area||0)+" 平"]}: {view: [mall.COUNT, html.DIV, "剩 "+(item.count||0)+" "+item.units]},
]},
{view: html.ACTION, inner: item.action},
]},
], _init: function(target) { item._target = target }, onclick: function(event) {
if (can.page.tagis(event.target, html.INPUT) && event.target.type == html.BUTTON) {
can.run(can.request(event, item), [ctx.ACTION, event.target.name])
}
}}
})), can.onmotion.select(can, can.ui.project, html.DIV_ITEM, 0)
can.ui.content.onscroll = function(event) { can.core.Item(list, function(zone, item) {
if (item._target.offsetTop > can.ui.content.scrollTop && item._target.offsetTop < can.ui.content.scrollTop+can.ui.content.offsetHeight/4) {
can.onmotion.select(can, can.ui.project, html.DIV_ITEM, item._zone)
}
}) }
},
}, [""])

View File

@ -1,22 +1,30 @@
fieldset.plan>div.output td.content { position:relative; } fieldset.plan>div.output div.prepare {
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td { vertical-align:top; } background-color:blue;
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td.over { border:var(--box-danger); } color:white;
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td.select { background-color:var(--hover-bg-color); box-shadow:var(--th-box-shadow); } }
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td:hover { background-color:var(--hover-bg-color); } fieldset.plan>div.output div.process {
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td.over { background-color:var(--hover-bg-color); } background-color:green;
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div { color:white; padding:10px; margin:10px; } color:white;
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.date { color:gray; } }
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.date span.lunar { font-size:12px; } fieldset.plan>div.output div.cancel {
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.date span.lunar.fest { color:red; } background-color:yellow;
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.date span.lunar.term { color:green; } color:white;
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.prepare { background-color:#0000ff70; } }
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.process { background-color:#00800070; } fieldset.plan>div.output div.finish {
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.cancel { background-color:#ff000070; text-decoration:line-through; } background-color:red;
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content td div.finish { background-color:#8080809c; } color:white;
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content tr:first-child { height:30px; position:sticky; top:2px; z-index:2; } }
fieldset.plan>div.output>div.layout>div.layout>div.profile>table.content tr:first-child { height:30px; position:sticky; top:2px; z-index:2; }
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content thead tr:first-child { z-index:2; } fieldset.plan>div.output td {
fieldset.plan>div.output>div.layout>div.layout>div.content>table.content th:first-child { width:40px; position:sticky; left:2px; z-index:1; } vertical-align:top;
fieldset.plan>div.output>div.layout>div.layout>div.profile>table.content tr:first-child { height:30px; position:sticky; top:2px; } }
fieldset.plan>div.output>fieldset.plug { position:absolute; } fieldset.plan>div.output td.over {
fieldset.plan.story>form.option>div.item.scale { display:none; } border:solid 2px red;
}
fieldset.plan>div.output td div.date {
color:gray;
}
fieldset.plan>div.output div.project {
max-height:400px;
overflow:auto;
}

View File

@ -1,156 +1,199 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
_init: function(can, msg, target) { can.onmotion.clear(can, target)
can._display_heights = {}, can.list = {}; var ls = can.misc.SearchHash(can) can.ui = can.onlayout.profile(can)
can.ui = can.onappend.layout(can), can.ui.toggle = can.onappend.toggle(can) can.onmotion.hidden(can, can._action)
can.onmotion.hidden(can, can.ui.project), can.isCmdMode() || can.onmotion.hidden(can, can._action) can.onimport[can.Option("scale")||"week"](can, msg)
can.onimport[can.Option("scale")||team.WEEK](can, msg), can.Status(mdb.COUNT, msg.Length()) can.page.Modify(can, can.ui.project, {style: {"max-height": can.ui.content.offsetHeight}})
// can.ui.filter.placeholder = `search in ${ msg.Length() } items` can.page.Modify(can, can.ui.profile, {style: {"max-height": can.ui.content.offsetHeight}})
can.onimport.layout(can) can.page.Modify(can, can.ui.profile, {style: {display: "block"}})
var item; if (can.isCmdMode() && ls.length > 0) { item = can.list[can.core.Keys(ls)] } else if (can.sup.task) { item = can.list[can.core.Keys(can.sup.task.space, can.sup.task.zone, can.sup.task.id)] } item && item.click() can.base.isFunc(cb) && cb(msg)
}, },
_content: function(can, msg, head, list, key, get, set) { var begin_time = can.base.Date(can.Option(team.BEGIN_TIME)); can.sup.task && (can.sup.task._target = null) _content: function(can, msg, head, list, key, get, set) {
var hash = {}; msg.Table(function(value, index) { var k = key(can.base.Date(value.begin_time)); hash[k] = (hash[k]||[]).concat([value]) }) var hash = {}; msg.Table(function(value, index) {
can.ui.table = can.page.Append(can, can.ui.content, [{view: [[chat.CONTENT, team.PLAN], html.TABLE], list: [{type: html.TBODY, list: can.core.List(list, function(hour, row) { var k = key(can.base.Date(value.begin_time)); hash[k] = (hash[k]||[]).concat([value])
})
can.sup.task && (can.sup.task._target = null)
var begin_time = can.base.Date(can.Option("begin_time"))
can.page.Append(can, can.ui.content, [{view: [chat.CONTENT, html.TABLE], list: can.core.List(list, function(hour, row) {
return {type: html.TR, list: can.core.List(head, function(week, col) { return {type: html.TR, list: can.core.List(head, function(week, col) {
if (row == 0) { return {text: [can.user.trans(can, week), html.TH]} } if (col == 0) { return {text: [hour, html.TH]} } if (row == 0) { return {text: [week, html.TH]} }
if (col == 0) { return {text: [hour, html.TD]} }
return can.onimport._task(can, msg, get(begin_time, col, row, hash), set(begin_time, col, row)) return can.onimport._task(can, msg, get(begin_time, col, row, hash), set(begin_time, col, row))
})} })}
}) }] }])._target, can.onmotion.delay(can, function() { var target = can.sup.task && can.sup.task._target; target && target.click(), can.Status(mdb.COUNT, msg.Length()) }) }) }])
can.core.Timer(10, function() { if (!can.sup.task) { return }
var target = can.sup.task._target||can.task._target
can.sup.task = null, target.click()
can.Status("count", msg.Length())
})
}, },
_task: function(can, msg, list, time) { return {type: html.TD, className: time == can.base.Time().slice(0, time.length)? html.SELECT: "", _task: function(can, msg, list, time) { return {text: ["", html.TD],
ondblclick: function(event) { can.onaction.insertTask(event, can, time+can.base.Time().slice(time.length)) }, ondblclick: function(event) {
ondrop: function(event) { can.onkeymap.prevent(event), can.drop(event, event.target, time) }, can.onaction.insertTask(event, can, time+can.base.Time(null, "%y-%m-%d %H:%M:%S").slice(time.length))
ondragover: function(event) { can.onkeymap.prevent(event), can.page.Select(can, can.ui.content, html.TD, function(td) { can.page.ClassList.set(can, td, "over", td == event.target) }) }, },
ondrop: function(event) { event.preventDefault()
can.drop(event, event.target, time)
},
ondragover: function(event) { event.preventDefault()
can.page.Select(can, can.ui.content, html.TD, function(item) {
can.page.ClassList[event.target == item? "add": "del"](can, item, "over")
})
},
list: can.core.List(list, function(task) { return can.base.isString(task)? {text: [task, html.DIV, "date"]}: list: can.core.List(list, function(task) { return can.base.isString(task)? {text: [task, html.DIV, "date"]}:
{text: [can.core.CallFunc([can.onexport, can.Action(html.VIEW)||mdb.TEXT], [can, task])||task.name, html.DIV, can.onexport.style(can, task)], {text: [can.onexport[can.Action("view")||"text"](can, task), html.DIV, can.onexport.style(can, task)],
ondragstart: function(event) { var target = event.target; can.drop = function(event, td, time) { td.append(target) ondragstart: function(event) { var target = event.target; can.drop = function(event, td, time) { td.append(target)
can.onaction.modifyTask(event, can, task, team.BEGIN_TIME, time+task.begin_time.slice(time.length), task.begin_time) can.onaction.modifyTask(event, can, task, "begin_time", time+task.begin_time.slice(time.length), task.begin_time)
} }, draggable: time != undefined, title: can.onexport.title(can, task.name), _init: function(target) { } }, draggable: time != undefined,
var item = can.onimport.item(can, {nick: task.name+nfs.DF+task.text}, function() { can.onmotion.delay(can, function() {
can.onmotion.select(can, can.ui.content, html.TD, target.parentNode), can.onimport._profile(can, task), can.onimport._display(can, task), can.onimport.layout(can) title: can.onexport.title(can, task), _init: function(target) {
}) }); task._target = target, target.onclick = function(event) { item.click() }, can.list[can.core.Keys(task.space, task.zone, task.id)] = target var item = can.onappend.item(can, html.ITEM, {nick: task.name+":"+task.text}, function() {
}} can.core.Timer(10, function() { can.onmotion.select(can, can.ui.content, html.TD, target.parentNode) })
can.onimport._profile(can, task)
}, function() {
}, can.ui.project); task._target = target, can.task = can.task||task, can.sup.task = can.sup.task||task
can.sup.task.zone == task.zone && can.sup.task.id == task.id && (can.sup.task._target = target)
target.onclick = function(event) { item.click() }
},
}
}), }),
} }, } },
_profile: function(can, task) { can.onmotion.toggle(can, can.ui.profile, true), can.onexport.hash(can, task), can.onexport.title(can, task.name, task.text) _profile: function(can, task) {
if (can.onmotion.cache(can, function() { return can.sup.task = task, can.Status(task), [task.space, task.zone, task.id].join(nfs.PT) }, can.ui.profile)) { return } if (can.sup.task && can.sup.task.pod == task.pod && can.sup.task.id == task.id) { return }
task.extra && can.core.Item(can.base.Obj(task.extra), function(key, value) { task[key] = value }), delete(task.extra) if (can.onmotion.cache(can, function() { return can.sup.task = task, can.Status(task), [task.pod, task.zone, task.id].join(ice.PT) }, can.ui.profile, can.ui.display)) { return }
var table = can.page.Appends(can, can.ui.profile, [{view: [[chat.CONTENT, mdb.DETAIL], html.TABLE], list: [{th: [can.user.trans(can, mdb.KEY, "字段"), can.user.trans(can, mdb.VALUE, "属性")]}]}])._target
task.extra && can.core.Item(can.base.Obj(task.extra), function(key, value) { task["extra."+key] = value }), delete(task.extra)
var table = can.page.Appends(can, can.ui.profile, [{view: [chat.CONTENT, html.TABLE], list: [{th: ["key", "value"]}]}]).first
can.core.Item(task, function(key, value) { key != "_target" && can.page.Append(can, table, [{ can.core.Item(task, function(key, value) { key != "_target" && can.page.Append(can, table, [{
className: key, td: [key, key == "pod" && value != ""? can.page.Format("a", can.misc.MergeURL(can, {pod: value}), value): value],
td: [can.user.trans(can, key, null, html.INPUT), key == web.SPACE && value != ""? can.page.Format(html.A, can.misc.MergeURL(can, {pod: value}), value): value], onclick: function(event) { if (event.target.type == "button") { var msg = can.request(event, can.sup.task)
onclick: function(event) { can.page.tagis(event.target, html.INPUT) && event.target.type == html.BUTTON && can.run(can.request(event, task), [ctx.ACTION, event.target.name]) }, can.run(event, [ctx.ACTION, event.target.name], function(msg) { can.Update() }, true)
ondblclick: function(event) { if ([web.SPACE, mdb.ZONE, mdb.ID].indexOf(key) > -1) { return } } },
can.onmotion.modify(can, event.target, function(sub, value) { can.onaction.modifyTask(event, can, task, key, value) }, {name: key, action: key.indexOf(mdb.TIME) > 0? "date": "key"}) ondblclick: function(event) { can.onmotion.modify(can, event.target, function(ev, value, old) {
}, can.onaction.modifyTask(event, can, task, key, value)
}]) }), can.onmotion.story.auto(can, can.ui.profile) }, {name: key, action: key.indexOf("time") > 0? "date": "key"}) },
}]) }), can.onimport._display(can, task)
}, },
_display: function(can, task) { can.onmotion.toggle(can, can.ui.display, true) _display: function(can, task) { if (!task["extra.cmd"]) { return }
if (can.onmotion.cache(can, function(save, load) { save({_plugin_display: can._plugin_display}), can.sup.task = task, can.Status(task) can.onappend.plugin(can, {type: chat.STORY, ctx: task["extra.ctx"], cmd: task["extra.cmd"], arg: task["extra.arg"]}, function(sub, meta) {
return load([task.space, task.zone, task.id].join(nfs.PT), function(bak) { can._plugin_display = bak._plugin_display }) sub.run = function(event, cmds, cb) { var msg = can.request(event, kit.Dict("task.pod", task["pod"], "task.zone", task.zone, "task.id", task.id))
}, can.ui.display)) { return } can.run(event, can.misc.concat(can, [ctx.ACTION, ice.RUN, task[mdb.ZONE], task[mdb.ID]], cmds), cb, true)
var index = task[ctx.INDEX]||task[ctx.EXTRA_INDEX]
index && can.onappend.plugin(can, {space: task.space, index: index, args: task[ctx.ARGS]||task[ctx.EXTRA_ARGS], height: can.ConfHeight()/2-2*html.ACTION_HEIGHT}, function(sub, meta) {
sub.run = function(event, cmds, cb) { can.request(event, kit.Dict(team.TASK_POD, task.space, team.TASK_ZONE, task.zone, team.TASK_ID, task.id))
can.page.style(can, sub._output, html.MAX_HEIGHT, ""), can.runAction(event, ctx.RUN, [task[mdb.ZONE], task[mdb.ID]].concat(cmds), cb)
} }
can._plugin_display = sub
sub.onaction.close = function() { can.onmotion.toggle(can, can.ui.display), can.onimport.layout(can) }
sub.onexport.output = function() { can.onmotion.delay(can, function() { sub.onimport.display_size(can, sub), can.onimport.layout(can) }) }
}, can.ui.display) }, can.ui.display)
can.page.Modify(can, can.ui.display, {style: {display: html.BLOCK}})
}, },
day: function(can, msg) { var head = [team.HOUR, team.TASK]
day: function(can, msg) {
var head = ["hour", "task"]
var list = [0]; for (var i = 7; i < 24; i++) { list.push(can.base.Number(i, 2)) } var list = [0]; for (var i = 7; i < 24; i++) { list.push(can.base.Number(i, 2)) }
function key(time) { return can.base.Number(time.getHours(), 2) } function key(time) { return can.base.Number(time.getHours(), 2) }
function get(begin_time, col, row, hash) { return hash[list[row]] } function get(begin_time, col, row, hash) { return hash[list[row]] }
function set(begin_time, col, row) { return can.base.Time(begin_time, "%y-%m-%d ")+list[row] } function set(begin_time, col, row) { return can.base.Time(begin_time, "%y-%m-%d ")+list[row] }
can.onimport._content(can, msg, head, list, key, get, set) can.onimport._content(can, msg, head, list, key, get, set)
}, },
week: function(can, msg) { var head = can.onexport.head(can, team.HOUR) week: function(can, msg) {
var head = ["hour"].concat(["周日", "周一", "周二", "周三", "周四", "周五", "周六"])
var list = [0]; for (var i = 7; i < 24; i++) { list.push(can.base.Number(i, 2)) } var list = [0]; for (var i = 7; i < 24; i++) { list.push(can.base.Number(i, 2)) }
function key(time) { return time.getDay()+" "+can.base.Number(time.getHours(), 2) } function key(time) { return time.getDay()+" "+can.base.Number(time.getHours(), 2) }
function get(begin_time, col, row, hash) { return hash[col-1+" "+list[row]] } function get(begin_time, col, row, hash) { return hash[col-1+" "+list[row]] }
function set(begin_time, col, row) { return can.base.Time(can.base.DateAdd(begin_time, -begin_time.getDay()+col-1), "%y-%m-%d ")+list[row] } function set(begin_time, col, row) { return can.base.Time(can.base.TimeAdd(begin_time, -begin_time.getDay()+col-1), "%y-%m-%d ")+list[row] }
can.onimport._content(can, msg, head, list, key, get, set) can.onimport._content(can, msg, head, list, key, get, set)
}, },
month: function(can, msg) { var head = can.onexport.head(can, "order") month: function(can, msg) {
var head = ["order"].concat(["周日", "周一", "周二", "周三", "周四", "周五", "周六"])
var list = [0]; for (var i = 1; i < 6; i++) { list.push(i) } var list = [0]; for (var i = 1; i < 6; i++) { list.push(i) }
function key(time) { return can.base.Time(time, "%y-%m-%d") } function key(time) { return can.base.Time(time, "%y-%m-%d") }
function get(begin_time, col, row, hash) { function get(begin_time, col, row, hash) {
var begin = can.base.DateAdd(begin_time, -(begin_time.getDate()-1)) var begin = can.base.TimeAdd(begin_time, -(begin_time.getDate()-1))
var last = can.base.DateAdd(begin_time, -(begin_time.getDate()-1)-begin.getDay()) var last = can.base.TimeAdd(begin_time, -(begin_time.getDate()-1)-begin.getDay())
var day = can.base.DateAdd(last, (row-1)*7+col) var day = can.base.TimeAdd(last, (row-1)*7+col)
var l = can.date.solar2lunar(day) return [day.getDate()+""].concat(hash[key(day)]||[])
return [can.page.Format(html.SPAN, day.getDate(), "day")+" "+can.page.Format(html.SPAN, l.autoDay, l.autoClass)].concat(hash[key(day)]||[])
} }
function set(begin_time, col, row) { function set(begin_time, col, row) {
var begin = can.base.DateAdd(begin_time, -(begin_time.getDate()-1)) var begin = can.base.TimeAdd(begin_time, -(begin_time.getDate()-1))
var last = can.base.DateAdd(begin_time, -(begin_time.getDate()-1)-begin.getDay()) var last = can.base.TimeAdd(begin_time, -(begin_time.getDate()-1)-begin.getDay())
var day = can.base.DateAdd(last, (row-1)*7+col) var day = can.base.TimeAdd(last, (row-1)*7+col)
return key(day) return key(day)
} }
can.onimport._content(can, msg, head, list, key, get, set) can.onimport._content(can, msg, head, list, key, get, set)
}, },
year: function(can, msg) { var head = can.onexport.head(can, team.MONTH) year: function(can, msg) {
var head = ["month"].concat(["周日", "周一", "周二", "周三", "周四", "周五", "周六"]);
var list = [0]; for (var i = 1; i < 13; i++) { list.push(i) } var list = [0]; for (var i = 1; i < 13; i++) { list.push(i) }
function key(time) { return can.base.Time(time, "%y-%m ")+time.getDay() } function key(time) { return can.base.Time(time, "%y-%m ")+time.getDay() }
function get(begin_time, col, row, hash) { return hash[begin_time.getFullYear()+"-"+can.base.Number(row, 2)+" "+(col-1)] } function get(begin_time, col, row, hash) { return hash[begin_time.getFullYear()+"-"+can.base.Number(row, 2)+" "+(col-1)] }
function set(begin_time, col, row) { return begin_time.getFullYear()+"-"+can.base.Number(list[row], 2) } function set(begin_time, col, row) { return begin_time.getFullYear()+"-"+can.base.Number(list[row], 2) }
can.onimport._content(can, msg, head, list, key, get, set) can.onimport._content(can, msg, head, list, key, get, set)
}, },
long: function(can, msg) { long: function(can, msg) {
var begin_time = can.base.Date(can.base.Time(can.Option(team.BEGIN_TIME), "%y-%m-%d %H:%M:%S")), begin = begin_time.getFullYear() - 5 var begin_time = can.base.Date(can.base.Time(can.Option("begin_time"), "%y-%m-%d %H:%M:%S"))
var head = [team.MONTH]; for (var i = 0; i < 10; i++) { head.push(begin+i) } var begin = begin_time.getFullYear() - 5
var head = ["month"]; for (var i = 0; i < 10; i++) { head.push(begin+i) }
var list = [0]; for (var i = 1; i < 13; i++) { list.push(i) } var list = [0]; for (var i = 1; i < 13; i++) { list.push(i) }
function key(time) { return can.base.Time(time, "%y-%m") } function key(time) { return can.base.Time(time, "%y-%m") }
function get(begin_time, col, row, hash) { return hash[begin+col-1+"-"+can.base.Number(row, 2)] } function get(begin_time, col, row, hash) { return hash[begin+col-1+"-"+can.base.Number(row, 2)] }
function set(begin_time, col, row) { return begin+col-1+"-"+can.base.Number(row, 2) } function set(begin_time, col, row) { return begin+col-1+"-"+can.base.Number(row, 2) }
can.onimport._content(can, msg, head, list, key, get, set) can.onimport._content(can, msg, head, list, key, get, set)
}, },
layout: function(can) { can.ui.layout(can.ConfHeight(), can.ConfWidth());
(can.Conf("_auto") || can.user.isMobile) && can.page.style(can, can.ui.content, html.HEIGHT, "")
var sub = can._plugin_display; sub && sub.onimport.display_size(can, sub)
can.ui.toggle && can.ui.toggle.layout()
}
}, [""]) }, [""])
Volcanos(chat.ONACTION, {list: [ Volcanos("onaction", {help: "组件交互", list: [
["status", "status", "prepare", "process", "cancel", "finish"], ["level", "all", "l1", "l2", "l3", "l4", "l5"],
["level", "level", "l1", "l2", "l3", "l4", "l5"], ["status", "all", "prepare", "process", "cancel", "finish"],
["score", "score", "s1", "s2", "s3", "s4", "s5"], ["score", "all", "s1", "s2", "s3", "s4", "s5"],
["view", "text", "name", "text", "level", "score"], ["view", "", "name", "text", "level", "score"],
], _trans: {"task": "任务", "hour": "时间", "month": "月份", "order": "周序"}, ],
prev: function(event, can) { var begin = can.base.Date(can.Option(team.BEGIN_TIME)||can.base.Time())
can.Option(team.BEGIN_TIME, can.base.Time(new Date(begin-can.onexport.span(can)))), can.Update()
},
next: function(event, can) { var begin = can.base.Date(can.Option(team.BEGIN_TIME)||can.base.Time())
can.Option(team.BEGIN_TIME, can.base.Time(new Date(begin-(-can.onexport.span(can))))), can.Update()
},
insertTask: function(event, can, time) { var msg = can.sup.request(event, {begin_time: time}) insertTask: function(event, can, time) { var msg = can.sup.request(event, {begin_time: time})
can.user.input(event, can, can.Conf([ctx.FEATURE, mdb.INSERT]), function(args) { can.user.input(event, can, can.Conf("feature.insert"), function(event, button, data, list) {
can.runAction(event, mdb.INSERT, [web.SPACE, args[1], mdb.ZONE, args[3], team.BEGIN_TIME, time].concat(args.slice(4))) can.run(event, can.base.Simple(ctx.ACTION, mdb.INSERT, data, "begin_time", time), true)
}) })
}, },
modifyTask: function(event, can, task, key, value) { can.runAction(can.request(event, task, can.Option()), mdb.MODIFY, [key, value], function() { can.Update() }) }, modifyTask: function(event, can, task, key, value) { var msg = can.request(event, task)
_filter: function(event, can, key, value) { var count = 0 can.run(event, [ctx.ACTION, mdb.MODIFY, key, value, task[key]])
if (value == key) { },
can.page.Select(can, can.ui.content, html.DIV_ITEM, function(item) { can.page.ClassList.del(can, item, html.HIDE), count++ })
} else { _filter: function(event, can, key, value) { var count = 0
can.page.Select(can, can.ui.content, html.DIV_ITEM, function(item) { can.page.ClassList.add(can, item, html.HIDE) }) if (value == "all") {
can.page.Select(can, can.ui.content, can.core.Keys(html.DIV, value), function(item) { can.page.ClassList.del(can, item, html.HIDE), count++ }) can.page.Select(can, can.ui.content, "div.item", function(item) {
} can.Action(key, value), can.Status(mdb.COUNT, count) can.page.ClassList.del(can, item, "hide"), count++
})
} else {
can.page.Select(can, can.ui.content, "div.item", function(item) {
can.page.ClassList.add(can, item, "hide")
})
can.page.Select(can, can.ui.content, "div."+value, function(item) {
can.page.ClassList.del(can, item, "hide"), count++
})
}
can.Action(key, value), can.Status("count", count)
}, },
status: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
level: function(event, can, key, value) { can.onaction._filter(event, can, key, value) }, level: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
status: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
score: function(event, can, key, value) { can.onaction._filter(event, can, key, value) }, score: function(event, can, key, value) { can.onaction._filter(event, can, key, value) },
view: function(event, can, key, value) { can.Action(key, value), can.onmotion.clear(can, can.ui.project), can.onmotion.clear(can, can.ui.content), can.core.CallFunc([can.onimport, can.Option("scale")], [can, can._msg]) }, view: function(event, can, key, value) {
can.Action(key, value)
can.onmotion.clear(can, can.ui.project)
can.onmotion.clear(can, can.ui.content)
can.onimport[can.Option("scale")](can, can._msg)
},
}) })
Volcanos(chat.ONEXPORT, {list: [mdb.COUNT, team.BEGIN_TIME, mdb.ZONE, mdb.ID, mdb.TYPE, mdb.NAME, mdb.TEXT, web.SPACE], Volcanos("onexport", {help: "导出数据", list: ["count", "begin_time", "zone", "id", "type", "name", "text"],
span: function(can) { return kit.Dict(team.DAY, 24*3600*1000, team.WEEK, 7*24*3600*1000, team.MONTH, 30*24*3600*1000, team.YEAR, 365*24*3600*1000, team.LONG, 365*24*3600*1000)[can.Option("scale")]||0 },
hash: function(can, task) { if (!can.isCmdMode()) { return } location.hash = [task.space, task.zone, task.id].join(nfs.DF) },
head: function(can, scale) { if ([team.YEAR, team.LONG].indexOf(scale) > -1) { return } return [scale].concat(can.user.time(can, "", "%W")) },
name: function(can, task) { return task.name }, name: function(can, task) { return task.name },
text: function(can, task) { return task.name+": "+(task.text||"") }, text: function(can, task) { return task.name+": "+(task.text||"") },
level: function(can, task) { return "l-"+(task.level||3)+": "+(task.name||"") }, level: function(can, task) { return "l-"+(task.level||3)+": "+(task.name||"") },
score: function(can, task) { return "s-"+(task.level||3)+": "+(task.name||"") }, score: function(can, task) { return "s-"+(task.level||3)+": "+(task.name||"") },
style: function(can, task) { return [html.ITEM, task.status, mdb.ID+task.id, "l"+(task.level||""), "s"+(task.score||"")].join(lex.SP) }, title: function(can, task) { return task.zone+": "+(task.type||"") },
style: function(can, task) { return ["item", task.status, "id"+task.id, "l"+(task.level||""), "s"+(task.score||"")].join(" ") },
}) })

View File

@ -1,2 +0,0 @@
fieldset.data div.output table.content tr.select { background-color:gray; }
fieldset.data div.output table.content tr.over { background-color:gray; }

View File

@ -1,77 +1,143 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb) {
if (can.Option(mdb.TYPE)) { return can.onimport[can.Option(mdb.TYPE)](can, msg, can.Option(mdb.FIELD)) } can.ui = can.onlayout.display(can)
can.ui = can.onappend.layout(can), can.table = can.onappend.table(can, msg, function(value, key, index, line) { return can.onimport._value(can, value) }, can.ui.content) can.base.isFunc(cb) && cb(msg)
cb && cb(msg), can.onappend._status(can, msg.append), can.onaction._compute(event, can)
can.table = can.onappend.table(can, msg, function(value, key, index, line) {
return {text: [value, "td"], oncontextmenu: function(event) {
can.user.carte(event, can, can.ondetail, can.ondetail.list, function(ev, cmd, meta) {
var cb = meta[cmd]; cb && cb(event, can, cmd, value, key, index, line)
})
}, ondblclick: function(event) {
can.page.Modify(can, event.target, {contenteditable: true})
}, onclick: function(event) {
if (key == "path") { can.run(event, [can.Option("path", value)]) }
}}
}, can.ui.content)
can.onexport.list = msg.append
can.onaction._compute(event, can)
}, },
_value: function(can, value) {
return {text: [value, html.TD], oncontextmenu: function(event) {
can.user.carte(event, can, can.ondetail, can.ondetail.list, function(ev, button, meta) { var cb = meta[button]; can.base.isFunc(cb) && cb(event, can, button) })
}, ondblclick: function(event) { can.page.editable(can, event.target, true) }}
},
_story: function(can, msg, display) { return can.onappend.plugin(can, {msg: msg, mode: chat.OUTPUT, display: can.misc.MergePath(can, display, chat.PLUGIN_STORY)}) },
"折线图": function(can, msg, field) { return can.onimport._story(can, msg, can.base.MergeURL("trend.js", {field: field, view: "折线图"})) },
"柱状图": function(can, msg, field) { return can.onimport._story(can, msg, can.base.MergeURL("trend.js", {field: field, view: "柱状图"})) },
"比例图": function(can, msg, field) { return can.onimport._story(can, msg, can.base.MergeURL("pie.js", {field: field})) },
}, [""])
Volcanos(chat.ONFIGURE, {
"求和": function(event, can, res, td, index) { res[index] = parseFloat(td.innerText) + (res[index]||0) },
"最大": function(event, can, res, td, index) { (res[index] === undefined || parseFloat(td.innerText) > parseFloat(res[index])) && (res[index] = parseFloat(td.innerText)) },
"最小": function(event, can, res, td, index) { (res[index] === undefined || parseFloat(td.innerText) < parseFloat(res[index])) && (res[index] = parseFloat(td.innerText)) },
"平均": function(event, can, res, td, index, cols, rows, nrow) { res[index] = parseFloat(td.innerText) + (res[index]||0); if (nrow == rows.length - 1) { res[index] = res[index] / nrow } },
}) })
Volcanos(chat.ONACTION, {list: [nfs.SAVE, Volcanos("onfigure", {help: "组件菜单", list: [],
[ice.MODE, "全选", "多选", "块选", "反选", "拖动", "编辑"], "求和": function(event, can, res, td, index) {
[ice.EXEC, "求和", "最大", "最小", "平均"], res[index] = parseInt(td.innerText) + (res[index]||0);
],
_compute: function(event, can) { var method = can.onfigure[can.Action(ice.EXEC)], res = {}
var mul = html.TR + (can.Action(ice.MODE) == "全选"? "": ".select"); can.page.Select(can, can.table, mul, function(tr, nrow, rows) {
(mul != html.TR || nrow > 0) && can.page.Select(can, tr, html.TD, function(td, ncol, cols) { method && method(event, can, res, td, ncol, cols, rows, nrow) })
}), can.core.Item(res, function(key, value) { can.Status(can._msg.append[key], value||"") })
}, },
save: function(event, can, button) { can.runAction(event, button, [can.Option(nfs.PATH), can.onexport.content(can)]) }, "最大": function(event, can, res, td, index) {
exec: function(event, can, button) { can.onaction._compute(event, can) }, var n = parseInt(td.innerText);
push: function(event, can, button) { n > (res[index]||-10000) && (res[index] = n);
can.user.input(event, can, can.page.Select(can, can.table, html.TH, function(th, index) { return {name: th.innerText, run: function(event, cmds, cb) {
var msg = can.request(event); can.page.Select(can, can.table, html.TR, function(tr, _index) { _index > 0 && msg.Push(mdb.VALUE, tr.children[index].innerText) }), cb(msg)
}} }), function(list) { can.runAction(event, button, [can.Option(nfs.PATH)].concat(list), function() { can.Update() }) })
}, },
draw: function(event, can, button) { "最小": function(event, can, res, td, index) {
can.user.input(event, can, [[mdb.TYPE, "折线图", "比例图"], {name: mdb.FIELD, run: function(event, cmds, cb) { var n = parseInt(td.innerText);
var msg = can.request(event); can.page.Select(can, can.table, html.TH, function(th) { msg.Push(mdb.VALUE, th.innerText) }), cb(msg) n < (res[index]||10000) && (res[index] = n);
}}], function(list) { can.onimport[list[0]](can, can._msg, list[1]) }) },
"平均": function(event, can, res, td, ncol, cols, rows, nrow) {
res[ncol] = parseInt(td.innerText) + (res[ncol]||0);
if (nrow == rows.length - 1) {
res[ncol] = res[ncol] / nrow
}
},
})
Volcanos("onaction", {help: "组件菜单", list: ["保存", ["mode", "全选", "块选", "反选", "多选", "拖动", "编辑"], ["some", "求和", "最大", "最小", "平均"]],
_compute: function(event, can) {
var mul = "tr" + (can.Action("mode") == "全选"? "": ".select")
var method = can.onfigure[can.Action("some")], res = {}
can.page.Select(can, can.ui.content, mul, function(tr, nrow, rows) {
(mul != "tr" || nrow > 0) && can.page.Select(can, tr, "td", function(td, ncol, cols) {
method && method(event, can, res, td, ncol, cols, rows, nrow)
})
})
can.core.Item(res, function(key, value) {
can.Status(can._msg.append[key], value||"")
})
}, },
_foreach: function(can, button, cb) { button && can.Action(ice.MODE, button), can.page.Select(can, can.table, "tbody>tr", function(target) { cb(target) }) }, "保存": function(event, can, cmd) {
"全选": function(event, can, button) { can.onaction._foreach(can, button, function(target) { can.run(event, [ctx.ACTION, cmd, can.Option("path"), can.onexport.file(can)], function(msg) {
can.page.ClassList.del(can, target, html.SELECT), can.page.ClassList.del(can, target, "over") can.user.toastSuccess(can)
can.page.editable(can, target, false), can.page.draggable(can, target, false) }, true)
target.onmouseenter = null, target.onclick = null },
}), can.onaction._compute(event, can) }, some: function(event, can, cmd) {
"多选": function(event, can, button) { can.onaction._foreach(can, button, function(target) { can.onaction._compute(event, can)
target.onmouseenter = function() {}, target.onclick = function() { can.page.ClassList.neg(can, target, html.SELECT), can.onaction._compute(event, can) } },
}) },
"块选": function(event, can, button) { can.onaction._foreach(can, button, function(target) { "全选": function(event, can, cmd) {
target.onmouseenter = function() { can.page.ClassList.add(can, target, html.SELECT), can.onaction._compute(event, can) } cmd && can.Action("mode", cmd)
}) }, can.page.Select(can, can.ui.content, "tr", function(item) {
"反选": function(event, can, button) { can.onaction._foreach(can, button, function(target) { can.page.ClassList.del(can, item, "over")
target.onmouseenter = function() { can.page.ClassList.del(can, target, html.SELECT), can.onaction._compute(event, can) } can.page.ClassList.del(can, item, "select")
}) }, item.setAttribute("contenteditable", false)
"拖动": function(event, can, button) { can.onaction["全选"](event, can, button), can.onaction._foreach(can, "", function(target) { can.page.draggable(can, target, true) item.setAttribute("draggable", false)
target.ondragstart = function(event) { can.drag = target } item.onmouseenter = null
target.ondragover = function(event) { event.preventDefault(), can.page.ClassList.add(can, target, "over")} item.onclick = null
target.ondragleave = function(event) { can.page.ClassList.del(can, target, "over") } })
target.ondrop = function(event) { event.preventDefault(), can.page.ClassList.del(can, target, "over"), can.page.Select(can, can.table, html.TBODY, function(tbody) { tbody.insertBefore(can.drag, target) }) } can.onaction._compute(event, can)
}) }, },
"编辑": function(event, can, button) { can.onaction._foreach(can, button, function(target) { can.page.editable(can, target, true) }) }, "块选": function(event, can, cmd) {
}) cmd && can.Action("mode", cmd)
Volcanos(chat.ONDETAIL, {list: ["复制", "删除"], can.page.Select(can, can.ui.content, "tr", function(item) {
"复制": function(event, can) { var list = can.page.Select(can, event.target.parentNode, html.TD, function(target) { return target.innerHTML }) item.onmouseenter = function() {
can.page.insertBefore(can, [{type: html.TR, list: can.page.Select(can, can.table, html.TH, function(key, index) { return can.onimport._value(can, list[index]) })}], event.target.parentNode, can.table) can.page.ClassList.add(can, item, "select")
can.onaction._compute(event, can)
}
})
},
"反选": function(event, can, cmd) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
item.onmouseenter = function() {
can.page.ClassList.del(can, item, "select")
can.onaction._compute(event, can)
}
})
},
"多选": function(event, can, cmd) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
item.onclick = function() {
can.page.ClassList.neg(can, item, "select")
can.onaction._compute(event, can)
}
})
},
"拖动": function(event, can, cmd) {
can.onaction["全选"](event, can, cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
item.setAttribute("draggable", true)
item.ondragstart = function(event) { can.drag = item }
item.ondragover = function(event) { event.preventDefault(), can.page.ClassList.add(can, item, "over")}
item.ondragleave = function(event) { can.page.ClassList.del(can, item, "over") }
item.ondrop = function(event) { event.preventDefault()
can.page.Select(can, can.ui.content, "table", function(table) {
table.insertBefore(can.drag, item)
})
}
})
},
"编辑": function(event, can, cmd) {
cmd && can.Action("mode", cmd)
can.page.Select(can, can.ui.content, "tr", function(item) {
item.setAttribute("contenteditable", true)
})
}, },
"删除": function(event, can) { can.page.Remove(can, event.target.parentNode) },
}) })
Volcanos(chat.ONEXPORT, { Volcanos("ondetail", {help: "组件详情", list: ["复制", "删除"],
content: function(can) { return can.page.Select(can, can.ui.content, html.TR, function(tr) { "复制": function(event, can, cmd, value, key, index, line) {
return can.page.Select(can, tr, can.page.Keys(html.TH, html.TD), function(td) {return td.innerHTML}).join(mdb.FS) var end = can.page.Append(can, can.table, [{type: "tr", list: can.core.List(can._msg.append, function(key) {
}).join(lex.NL) }, return {text: [line[key], "td"]}
})}]).tr
can.table.insertBefore(end, event.target.parentNode)
},
"删除": function(event, can, cmd) {
can.page.Remove(can, event.target.parentNode)
},
}) })
Volcanos("onexport", {help: "导出数据", list: [],
file: function(can) {
return can.page.Select(can, can.ui.content, "tr", function(tr) {
return can.page.Select(can, tr, "th,td", function(td) {return td.innerHTML}).join(",")
}).join("\n")
},
})

View File

@ -0,0 +1,14 @@
fieldset.draw div.output {
background-color:#1b5b738c;
font-size:20px;
}
fieldset.draw div.output div.content svg {
background-color:#1b5b738c;
}
fieldset.draw div.output div.profile div.action div.item {
float:left;
}
fieldset.draw div.output div.display {
max-height:400px;
overflow:auto;
}

View File

@ -1,399 +1,590 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
_init: function(can, msg) { can.onmotion.clear(can), can.onmotion.hidden(can, can._action)
can.isCmdMode() || can.onmotion.hidden(can, can._action) can.onimport._show(can, msg), can.base.isFunc(cb) && cb(msg)
can.OptionPath = function(value) { return can.Option(nfs.PATH, value) } can.keylist = [], can.onkeymap._build(can)
can.OptionPid = function(value) { return can.Option(svg.PID, value) }
can.ActionGo = function(value) { return can.Action(svg.GO, value) }
can.ActionMode = function(value) { return can.Action(ice.MODE, value) }
can.ActionShape = function(value) { return can.Action(svg.SHAPE, value) }
can._temp = []
if (can.ConfIndex() == web.WIKI_DRAW) { can.ui = can.onappend.layout(can), can.onexport.title(can, can.OptionPath())
if (can.isCmdMode() && !can.user.isMobile) { can.onmotion.toggle(can, can.ui.profile, true) } else { can.onmotion.hidden(can, can._action), can.onmotion.hidden(can, can.ui.project) }
} else { can.ui.content || (can.ui = {content: can._output}) } can.page.Modify(can, can.ui.content, msg.Results()||can.onexport.content(can))
can.page.Select(can, can.ui.content, html.SVG, function(target) { can.ui.svg = can.ui.group = can.onimport._block(can, target), can.onimport._project(can, target), can.ui.profile && can.core.ItemCB(can.onaction, target, can)
can.page.Select(can, target, "", function(target) { can.onimport._block(can, target), can.page.tagis(target, svg.G) && target.Value(html.CLASS) && can.onimport._project(can, target) })
}), can.ondetail._select(can, can.db.hash[1]||can.OptionPid()||can.ui.svg.Value(svg.PID)), can.ui.points = []
}, },
_block: function(can, target) { _show: function(can, msg) { can.point = []
target.Value = function(key, value) { if (can.base.isUndefined(key)) { return } if (can.base.isObject(key)) { return can.core.Item(key, target.Value), key } can.svg = null, can.group = null, can.temp = null, can.current = null
var figure = can.onfigure._get(can, target); key = can.core.Value(figure, [svg.DATA, svg.TRANS, key])||key
var _cb = can.core.Value(figure, [svg.DATA, key]); if (can.base.isFunc(_cb)) { return _cb(can, value, key, target) } // 加载图形
if (value == ice.AUTO) { return target.removeAttribute(key) } can.ui = can.onlayout.profile(can), can.onmotion.hidden(can, can.ui.project)
if (key == html.INNER) { return value != undefined && (target.innerHTML = value), target.innerHTML } can.page.Modify(can, can.ui.content, msg.Result()||can.onexport.content(can))
if (key == svg.SHIP) { return value != undefined && target.setAttribute(key, JSON.stringify(value)), can.base.Obj(target.getAttribute(key), []) } can.page.Select(can, can.ui.content, html.SVG, function(svg) {
try { return value != undefined && target.setAttribute(key, value), target.getAttribute(key) || can.core.Value(target[key], "baseVal.value") || can.core.Value(target[key], "baseVal") || undefined } catch(e) { } can.svg = can.group = can.onimport._block(can, svg), can.onimport._group(can, svg).click()
}, target.Val = function(key, value) { return parseInt(target.Value(key, value == undefined? value: parseInt(value)||0))||0 } can.core.ItemCB(can.onaction, function(key, cb) { svg[key] = function(event) { cb(event, can) } })
target.Group = function() { for (var node = target; node; node = node.parentNode) { if (can.page.tagis(node, svg.G, html.SVG)) { return node } } return can.ui.svg } can.page.Select(can, svg, "*", function(item, index) { can.onimport._block(can, item)
target.Groups = function() { if (target == can.ui.svg) { return html.SVG } var list = [] item.tagName == svg.G && item.Value(html.CLASS) && can.onimport._group(can, item)
for (var node = target; node && !can.page.tagis(node, html.SVG); node = node.parentNode) { can.page.tagis(node, svg.G) && node.Value(html.CLASS) && list.push(node.Value(html.CLASS)) } })
return list.reverse().join(nfs.PT) })
}; return target // 默认参数
}, can.core.Timer(10, function() {
_project: function(can, target) { var groups = target.Groups(); if (!groups || !can.ui.project) { return } can.core.Item({
var item = can.onimport.item(can, {name: groups}, function(event) { can.ui.group = target "stroke-width": 2, stroke: cli.YELLOW, fill: cli.PURPLE,
can.misc.SearchHash(can, groups, can.OptionPid()), can.Status(svg.GROUP, groups), can.onaction.show(event, can) "font-size": 24, "font-family": html.MONOSPACE,
can.core.List([svg.FONT_SIZE, svg.STROKE_WIDTH, svg.STROKE, svg.FILL], function(key) { can.Action(key, target.Value(key)||key) }) go: ice.RUN, shape: "rect", grid: 10,
}, function(event) { return {meta: can.onaction, list: can.onaction.menu_list} }); target._item = item }, function(key, value) { can.svg.Value(key, can.Action(key, can.svg.Value(key)||value)) })
groups == can.db.hash[0] && can.onmotion.delay(can, function() { item.click() })
}, var pid = can.Option("pid")||can.svg.Value("pid"); can.onmotion.hidden(can, can.ui.profile, true)
_profile: function(can, target) { if (!can.ui.profile) { return } pid && can.page.Select(can, can.svg, ice.PT+pid, function(item) {
can.misc.SearchHash(can, target.Groups()||html.SVG, can.OptionPid(can.onexport._pid(can, target))) can.ondetail.run({target: item}, can), can.onimport._profile(can, item)
var figure = can.onfigure._get(can, target), ui = can.page.Appends(can, can.ui.profile, [html.OUTPUT, html.ACTION]) }) || can.onimport._profile(can, can.svg), can.onmotion.hidden(can, can.ui.profile)
can.page.Appends(can, ui.output, [{view: [html.CONTENT, html.TABLE], list: [ can.page.Modify(can, can.ui.display, {style: {"min-height": 80, "max-height": can.Conf("height")-can.svg.Val("height")-52}})
{th: [mdb.KEY, mdb.VALUE]}, {td: [mdb.TYPE, target.tagName]}, {td: [svg.PID, target.Value(svg.PID)]}, {td: [mdb.TEXT, target.Value(mdb.TEXT)]},
].concat(can.core.List([].concat(can.core.Value(figure, "data.copy"), [svg.X, svg.Y, mdb.INDEX, ctx.ARGS]), function(key) {
return key = can.core.Value(figure.data, can.core.Keys(svg.TRANS, key))||key, {td: [key, target.Value(key)], ondblclick: function(event) {
var _target = event.target
can.onmotion.modify(can, _target, function(event, value) {
target.Value(key, _target.innerHTML = value), can.ondetail._move(can, target)
if (key == ctx.INDEX || key == ctx.ARGS) { can.onimport._display(can, target) }
}, {name: key, action: "key"})
}}
})) }])
// can.onappend._action(can, can.ondetail.list, ui.action, {_engine: function(event, can, button) { can.ondetail[button]({target: target}, can, button) }})
},
_display: function(can, target) { if (!can.ui.display) { return }
if (!target.Value(ctx.INDEX)) { return can.onmotion.hidden(can, can.ui.display) } can.onmotion.toggle(can, can.ui.display, true)
if (can.onmotion.cache(can, function() { return target.Value(svg.PID) }, can.ui.display)) { return can.onimport.layout(can) }
can.onappend.plugin(can, {index: target.Value(ctx.INDEX), args: target.Value(ctx.ARGS), height: can.ConfHeight()/2}, function(sub) {
sub.onexport.output = function() { can.onmotion.delay(can, function() { can.page.style(can, sub._output, html.MAX_HEIGHT, "")
sub.onimport.size(sub, can.base.Max(sub._target.offsetHeight, can.ConfHeight()/2), can.ConfWidth()-can.ui.project.offsetWidth, true), can.onimport.layout(can)
}) }
sub.onaction._close = function() { can.onmotion.hidden(can, can.ui.display), can.onimport.layout(can) }
}, can.ui.display)
},
block: function(can, type, value, group) { group = group||can.ui.group
var target = document.createElementNS("http://www.w3.org/2000/svg", type)
return group.appendChild(can.onimport._block(can, target)), target.Value(value), target
},
group: function(can, name, value, group) { var target = can.onimport.block(can, svg.G, {}, group||can.ui.svg)
return target.Value(html.CLASS, name), target.Value(value), can.onimport._project(can, target), target
},
draw: function(can, meta, group) { group = group||can.ui.svg
var figure = can.onfigure[meta.shape], data = figure.draw({}, can, meta.points, meta.style||{}); can.core.Item(meta.style, function(key, value) { data[key] = value })
var target = can.onimport.block(can, figure.data.name||meta.shape, data, group); can.core.ItemCB(meta, target, can)
return meta._init && meta._init(target), target
},
layout: function(can) {
can.ui.svg && can.page.style(can, can.ui.svg, html.MIN_HEIGHT, can.ConfHeight()-1, html.MIN_WIDTH, can.ConfWidth())
can.ui.layout && can.ui.layout(can.ConfHeight(), can.ConfWidth(), 0, function(height, width) {
can.page.style(can, can.ui.svg, html.MIN_HEIGHT, height-1, html.MIN_WIDTH, width)
}) })
}, },
}) _group: function(can, target) { var name = target.Groups()
Volcanos(chat.ONACTION, { function show(event) { can.group = target
list: [ can.core.List([html.STROKE_WIDTH, html.STROKE, html.FILL, html.FONT_SIZE], function(key) {
[svg.GO, ctx.RUN, ice.AUTO, "manual"], [ice.MODE, web.DRAW, html.MOVE, html.RESIZE], can.Action(key, target.Value(key)||can.Action(key))
[svg.SHAPE, svg.RECT, svg.LINE, svg.TEXT, svg.BLOCK, svg.CIRCLE, svg.ELLIPSE], })
[svg.STROKE_WIDTH, svg.STROKE_WIDTH, 1, 2, 3, 4, 5], }
[svg.STROKE, svg.STROKE, cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.BLACK, cli.WHITE], return (name || target == can.svg) && can.onappend.item(can, html.ITEM, {name: name||html.SVG}, function(event) { show(event)
[svg.FILL, svg.FILL, cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.BLACK, cli.WHITE], can.onaction.show(event, can)
[svg.FONT_SIZE, svg.FONT_SIZE, 12, 16, 18, 24, 32], [svg.GRID, svg.GRID, 1, 2, 3, 4, 5, 10, 20], }, function(event) {
], _change: function(can, key, value) { can.user.carteRight(event, can, can.onaction, [ice.HIDE, ice.SHOW, mdb.CREATE, cli.CLEAR, mdb.REMOVE])
value == "" && (value = key), can.Action(key, value) }, can.ui.project)
key == value && (value = ice.AUTO), can.ui.group.Value(key, value)
can.user.toast(can, key+" "+value)
}, },
_block: function(can, target) {
target.oncontextmenu = function(event) {
var carte = can.user.carte(event, can, can.ondetail, null, function(ev, button, meta) {
meta[button](event, can, button)
}); can.page.Modify(can, carte._target, {style: {left: event.clientX, top: event.clientY}})
}
target.Val = function(key, value) {
return parseInt(target.Value(key, value == undefined? value: parseInt(value)||0))||0
}
target.Value = function(key, value) { if (can.base.isUndefined(key)) { return }
if (can.base.isObject(key)) { can.core.Item(key, target.Value); return }
var figure = can.onfigure._get(can, target)
key = figure && figure.data && figure.data.size && figure.data.size[key] || key
if (figure && figure.data && can.base.isFunc(figure.data[key])) {
return figure.data[key](can, value, key, target)
}
if (key == html.INNER) {
return value != undefined && (target.innerHTML = value), target.innerHTML
}
if (key == ice.SHIP) {
return value != undefined && target.setAttribute(key, JSON.stringify(value)), can.base.Obj(target.getAttribute(key), [])
}
return value != undefined && target.setAttribute(key, value), target.getAttribute(key||html.CLASS)
|| target[key]&&target[key].baseVal&&target[key].baseVal.value || target[key]&&target[key].baseVal || ""
}
target.Group = function() { var item = target
while (item) { if ([html.SVG, svg.G].indexOf(item.tagName) > -1) { return item }; item = item.parentNode }
return can.svg
}
target.Groups = function() { var item = target
var list = []; while (item && item.tagName != html.SVG) {
item.tagName == svg.G && item.Value(html.CLASS) && list.push(item.Value(html.CLASS))
item = item.parentNode
}
return list.reverse().join(ice.PT)
}
return target
},
_profile: function(can, target, list) { can.Option("pid", can.onfigure._pid(can, target))
if (can.onmotion.cache(can, function() { return target.Value("pid") }, can.ui.profile)) { return }
var action = can.page.Append(can, can.ui.profile, [{view: "action"}]).first
can.onappend._action(can, can.ondetail.list, action, {_engine: function(event, can, button) {
can.ondetail[button]({target: target}, can, button)
}})
var figure = can.onfigure._get(can, target)
list = (list||[]).concat(figure.data.copy, [svg.X, svg.Y, mdb.INDEX, ctx.ARGS])
can.page.Append(can, can.ui.profile, [{type: html.TABLE, className: "content", list: [
{th: [mdb.KEY, mdb.VALUE]}, {td: [mdb.TYPE, target.tagName]}, {td: ["pid", target.Value("pid")]},
].concat(can.core.List(list, function(key) {
return key = figure.data.size[key]||key, {td: [key, target.Value(key)], ondblclick: function(event) {
can.onmotion.modify(can, event.target, function(event, value, old) {
target.Value(key, value), can.onfigure._move(can, target)
})
}}
})) }])
},
draw: function(event, can, value) {
var figure = can.onfigure[value.shape]
var data = figure.draw(event, can, value.point, value.style)
can.core.Item(value.style, function(key, value) { data[key] = value })
var item = can.onfigure._push(can, figure.data.name||value.shape, data, can.group||can.svg)
can.core.ItemCB(value, function(key, cb) { item[key] = cb })
can.onimport._block(can, item), can.onfigure._pid(can, item)
return value._init && value._init(item), item
},
}, ["/plugin/local/wiki/draw.css"])
Volcanos("onfigure", {help: "图形绘制", list: [],
_get: function(can, item, name) {
return can.onfigure[name]||can.onfigure[item.getAttribute(mdb.NAME)]||can.onfigure[item.tagName]
},
_pid: function(can, item) { if (item.Value("pid")) { return item.Value("pid") }
var pid = "p"+can.svg.Val(mdb.COUNT, can.svg.Val(mdb.COUNT)+1)
item.Value(html.CLASS, (item.Value(html.CLASS)+ice.SP+item.Value("pid", pid)).trim())
return pid
},
_push: function(can, type, data, target) {
var item = document.createElementNS("http://www.w3.org/2000/svg", type)
target.appendChild(can.onimport._block(can, item)), item.Value(data)
return item
},
_copy: function(event, can, target) {
var data = {}, figure = can.onfigure._get(can, target), size = figure.data.size
can.core.List(figure.data.copy, function(item) { data[item] = target.Value(item) })
data[size.x||svg.X] = target.Val(size.x||svg.X)+10
data[size.y||svg.Y] = target.Val(size.y||svg.Y)+10
return can.onfigure._push(can, target.tagName, data, can.group||can.svg)
},
_move: function(can, target, list) {
can.core.List(list||target.Value(ice.SHIP), function(ship) {
ship.target = can.page.Select(can, can.svg, ice.PT+ship.pid)[0]
var p = can.onexport.anchor(target, ship.anchor, {})
if (ship.which == 1) {
ship.target.Val("x1", p.x), ship.target.Val("y1", p.y)
} else if (ship.which == 2) {
ship.target.Val("x2", p.x), ship.target.Val("y2", p.y)
}
})
},
svg: { // <svg height="200" width="600" count="0" grid="10" stroke-width="2" stroke="yellow" fill="purple" font-size="24"/>
data: {size: {}, copy: []},
show: function(can, target, figure) { return can.onexport._size(can, target, figure) }
},
text: { // <text x="60" y="10">hi<text>
data: {points: 1, size: {}, copy: [html.INNER]},
draw: function(event, can, point, style) { if (point.length < 1 || event.type == "mousemove") { return }
var p0 = point[0], text = style&&style.inner||can.user.prompt(mdb.TEXT)
return text? {x: p0.x, y: p0.y, inner: text}: null
},
show: function(can, target, figure) { return can.onexport._position(can, target, figure) }
},
circle: { // <circle r="20" cx="25" cy="75"/>
data: {points: 2, size: {height: svg.R, width: svg.R, x: "cx", y: "cy"}, copy: [svg.R]},
draw: function(event, can, point) { if (point.length < 2) { return }
var p0 = point[0], p1 = point[1]
return {r: parseInt(Math.sqrt(Math.pow(p0.x-p1.x, 2)+Math.pow(p0.y-p1.y, 2))), cx: p0.x, cy: p0.y}
},
},
ellipse: { // <ellipse ry="5" rx="20" cx="75" cy="75"/>
data: {points: 2, size: {height: "ry", width: "rx", x: "cx", y: "cy"}, copy: ["ry", "rx"]},
draw: function(event, can, point) { if (point.length < 2) { return }
var p0 = point[0], p1 = point[1]
return {ry: Math.abs(p0.y - p1.y), rx: Math.abs(p0.x - p1.x), cx: p0.x, cy: p0.y}
},
},
rect: { // <rect height="30" width="30" ry="10" rx="10" x="60" y="10"/>
data: {points: 2, ry: 4, rx: 4, size: {}, copy: [html.HEIGHT, html.WIDTH, "ry", "rx"]},
draw: function(event, can, point) { if (point.length < 2) { return }
var p0 = point[0], p1 = point[1]
return {
height: Math.abs(p0.y-p1.y), width: Math.abs(p0.x-p1.x), ry: this.data.ry, rx: this.data.rx,
x: p0.x > p1.x? p1.x: p0.x, y: p0.y > p1.y? p1.y: p0.y,
}
},
text: function(can, data, target) { return data.x = target.Val(svg.X)+target.Val(html.WIDTH)/2, data.y = target.Val(svg.Y)+target.Val(html.HEIGHT)/2, data },
},
block: { // <rect height="30" width="30" ry="10" rx="10" x="60" y="10"/>
data: {points: 2, ry: 4, rx: 4, size: {}, copy: [html.HEIGHT, html.WIDTH, "ry", "rx"]},
draw: function(event, can, point) { if (point.length < 2) { return }
this._temp && can.page.Remove(can, this._temp) && delete(this._temp)
this._temp = can.onfigure._push(can, svg.G, {}, can.group||can.svg)
var rect = can.onfigure._push(can, "rect", can.onfigure.rect.draw(event, can, point), this._temp)
if (event.type == html.CLICK) {
can.onfigure._pid(can, rect), delete(this._temp)
}
},
text: function(can, data, target) { can.onfigure.rect.text(can, data, target) },
},
line: { // <line x1="10" y1="50" x2="110" y2="150" xx="100" yy="100"/>
data: {points: 2, size: {x: "x1", y: "y1"}, copy: ["x1", "y1", "x2", "y2"]},
grid: function(event, can, point) { var target = event.target
if (target == can.svg) { return }
var p = point[point.length-1], pos = can.onexport.cursor(event, can, target)
target.Val && can.onexport.anchor(target, pos, p)
return p.target = target, p.anchor = pos, point
},
draw: function(event, can, point) { if (point.length < 2) { return }
var p0 = point[0], p1 = point[1], ship = []
p0.target && p0.target.Value && ship.push({pid: p0.target.Value("pid")})
p1.target && p1.target.Value && ship.push({pid: p1.target.Value("pid")})
return {x1: p0.x, y1: p0.y, x2: p1.x, y2: p1.y, ship: ship}
},
text: function(can, target, data) { return data.x = (target.Val("x1")+target.Val("x2"))/2, data.y = (target.Val("y1")+target.Val("y2"))/2, data },
show: function(can, target, figure) { return "<("+(target.Val("y2")-target.Val("y1"))+ice.FS+(target.Val("x2")-target.Val("x1"))+")"+can.onexport._position(can, target, figure) },
},
}, [])
Volcanos("onkeymap", {help: "键盘交互", list: [],
_mode: {
normal: {
gr: function(event, can) { can.Action("go", "run") },
ga: function(event, can) { can.Action("go", "auto") },
gm: function(event, can) { can.Action("go", "manual") },
ad: function(event, can) { can.Action("mode", "draw") },
ar: function(event, can) { can.Action("mode", "resize") },
st: function(event, can) { can.Action("shape", "text") },
sr: function(event, can) { can.Action("shape", "rect") },
sl: function(event, can) { can.Action("shape", "line") },
sc: function(event, can) { can.Action("shape", "circle") },
se: function(event, can) { can.Action("shape", "ellipse") },
cr: function(event, can) { can.onaction._change(can, "stroke", "red") },
cb: function(event, can) { can.onaction._change(can, "stroke", "blue") },
cg: function(event, can) { can.onaction._change(can, "stroke", "green") },
cy: function(event, can) { can.onaction._change(can, "stroke", "yellow") },
cp: function(event, can) { can.onaction._change(can, "stroke", "purple") },
cc: function(event, can) { can.onaction._change(can, "stroke", "cyan") },
ch: function(event, can) { can.onaction._change(can, "stroke", "black") },
cw: function(event, can) { can.onaction._change(can, "stroke", "white") },
fr: function(event, can) { can.onaction._change(can, "fill", "red") },
fb: function(event, can) { can.onaction._change(can, "fill", "blue") },
fg: function(event, can) { can.onaction._change(can, "fill", "green") },
fy: function(event, can) { can.onaction._change(can, "fill", "yellow") },
fp: function(event, can) { can.onaction._change(can, "fill", "purple") },
fc: function(event, can) { can.onaction._change(can, "fill", "cyan") },
fh: function(event, can) { can.onaction._change(can, "fill", "black") },
fw: function(event, can) { can.onaction._change(can, "fill", "white") },
},
}, _engine: {},
})
Volcanos("onaction", {help: "组件菜单", list: [
["stroke-width", 1, 2, 3, 4, 5],
["stroke", cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.BLACK, cli.WHITE],
["fill", cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.BLACK, cli.WHITE, "#0000"],
["font-size", 12, 16, 18, 24, 32],
["go", ice.RUN, ice.AUTO, "manual"],
["mode", "draw", "resize"],
["shape", "text", "circle", "ellipse", "rect", "block", "line"],
["grid", 1, 2, 3, 4, 5, 10, 20],
],
_change: function(can, key, value) { can.Action(key, value), can.group.Value(key, value) },
"stroke-width": function(event, can, key, value) { can.onaction._change(can, key, value) }, "stroke-width": function(event, can, key, value) { can.onaction._change(can, key, value) },
stroke: function(event, can, key, value) { can.onaction._change(can, key, value) }, stroke: function(event, can, key, value) { can.onaction._change(can, key, value) },
fill: function(event, can, key, value) { can.onaction._change(can, key, value) }, fill: function(event, can, key, value) { can.onaction._change(can, key, value) },
"font-size": function(event, can, key, value) { can.onaction._change(can, key, value) }, "font-size": function(event, can, key, value) { can.onaction._change(can, key, value) },
save: function(event, can, button) { can.runAction(can.request(event, {text: can.onexport.content(can, can.ui.svg)}), button, [can.OptionPath()]) },
menu_list: [html.HIDE, html.SHOW, web.CLEAR, mdb.CREATE, mdb.REMOVE], go: function(event, can, key, value) { can.Action(key, value) },
hide: function(event, can) { can.onmotion.hide(can, {interval: 50, length: 10}, null, can.ui.group) }, mode: function(event, can, key, value) { can.Action(key, value) },
show: function(event, can) { can.onmotion.show(can, {interval: 50, length: 10}, null, can.ui.group) }, shape: function(event, can, key, value) { can.Action(key, value) },
clear: function(event, can) { can.onmotion.clear(can, can.ui.group), delete(can.ui.temp), can.ui.points = [] },
create: function(event, can) { can.user.input(event, can, [svg.GROUP], function(list) { can.onimport.group(can, list[0], {}, can.ui.group) }) }, edit: function(event, can) { can.Action("go", can.Action("go") == ice.RUN? ice.AUTO: ice.RUN) },
remove: function(event, can) { save: function(event, can, button) {
if (can.ui.group == can.ui.svg) { return can.onmotion.clear(can, can.ui.svg) } var msg = can.request(event, {content: can.onexport.content(can, can.svg)})
can.page.Remove(can, can.ui.group._item), can.page.Remove(can, can.ui.group) can.run(event, [ctx.ACTION, button, can.Option(nfs.PATH)], function(msg) {
can.user.toastSuccess(can)
}, true)
},
project: function(event, can) { can.onmotion.toggle(can, can.ui.project) },
profile: function(event, can) { can.onmotion.toggle(can, can.ui.profile) },
show: function(event, can) { can.onmotion.show(can, {interval: 100, length: 10}, null, can.group) },
hide: function(event, can) { can.onmotion.hide(can, {interval: 100, length: 10}, null, can.group) },
create: function(event, can) {
can.user.prompt("group", "some", function(name) {
var group = document.createElementNS('http://www.w3.org/2000/svg', svg.G)
can.group.append(group), can.onimport._block(can, group)
group.Value(html.CLASS, name), can.core.List([html.STROKE_WIDTH, html.STROKE, html.FILL, html.FONT_SIZE], function(name) {
group.Value(name, can.Action(name))
}), can.onimport._group(can, group).click()
})
},
remove: function(event, can) { if (can.group == can.svg) { return }
can.page.Remove(can, can.group)
},
clear: function(event, can) {
can.onmotion.clear(can, can.group), can.point = [], delete(can.temp)
}, },
_mode: { _mode: {
draw: function(event, can, points) { var shape = can.ActionShape(), figure = can.onfigure[shape] draw: function(event, can, point) {
figure.grid && figure.grid(event, can, points); if (figure.data.points && points.length < figure.data.points) { return } var shape = can.Action("shape")
var data = figure.draw && figure.draw(event, can, points, {}), target = data && can.onimport.block(can, figure.data.name||shape, data, can.ui.group) var figure = can.onfigure[shape]
if (event.type != html.CLICK) { return target } can.ui.points = []; if (!target) { return } var pid = can.onexport._pid(can, target) figure.grid && figure.grid(event, can, point)
can.core.List(points, function(p, i) { p.target && p.target.Value(svg.SHIP, p.target.Value(svg.SHIP).concat([{pid: pid, which: i+1, anchor: p.anchor}])) })
}, var data = figure.draw && figure.draw(event, can, point)
move: function(event, can, points) { var target = event.target var item = data && can.onfigure._push(can, figure.data.name||shape, data, can.group||can.svg)
if (event.type == html.CLICK) { if (points.length > 1) { return can.ui.points = [], delete(can.ui.current) } event.type == html.CLICK && point.length === figure.data.points && (can.point = [])
return can.ui.current = {target: target, begin: can.core.List([target], function(target) { if (can.page.tagis(target, svg.G)) { return }
return {target: target, height: target.Val(html.HEIGHT), width: target.Val(html.WIDTH), x: target.Val(svg.X), y: target.Val(svg.Y), if (event.type == html.CLICK && item) {
ship: can.core.List(target.Value(svg.SHIP), function(ship) { return ship.pid && (ship.target = can.ondetail._select(can, ship.pid)) && ship }) var pid = can.onfigure._pid(can, item); can.core.List(point, function(p, i) { if (!p.target) { return }
} p.target.Value(ice.SHIP, p.target.Value(ice.SHIP).concat([{pid: pid, which: i+1, anchor: p.anchor}]))
}), pos: can.onexport.cursor(event, can, target)} })
} }
can.ui.current && can.core.List(can.ui.current.begin, function(item) { var figure = can.onfigure._get(can, item.target) return item
can.onexport.resize(item.target, 5, points[0], points[1], item), can.ondetail._move(can, item.target, item.ship) },
can.ondetail._select(can, item.target.Value(mdb.TEXT), function(text) { text.Value(can.onexport._text(can, item.target, figure, {})) }) resize: function(event, can, point, target) { target = target||event.target
if (event.type == html.CLICK) {
if (point.length == 1) {
can.current = {target: target, begin: can.core.List([target], function(item) { if (item.tagName == svg.G) { return }
return {
height: item.Val(html.HEIGHT), width: item.Val(html.WIDTH), x: item.Val(svg.X), y: item.Val(svg.Y),
target: item, ship: can.core.List(item.Value(ice.SHIP), function(ship) {
return ship.pid && (ship.target = can.page.Select(can, can.svg, ice.PT+ship.pid)[0]) && ship
})
}
}), pos: can.onexport.cursor(event, can, target)}
return
}
return can.point = [], delete(can.current)
}
can.current && can.core.List(can.current.begin, function(item) { var figure = can.onfigure._get(can, item.target)
can.onexport.resize(event, item.target, item, point[0], point[1], can.current.pos)
can.page.Select(can, can.svg, ice.PT+item.target.Value(mdb.TEXT), function(text) {
text.Value(can.onexport._text(can, item.target, figure, {}))
})
can.onfigure._move(can, item.target, item.ship)
}) })
}, },
resize: function(event, can, points) { var target = event.target run: function(event, can) {
if (event.type == html.CLICK) { if (points.length > 1) { return can.ui.points = [], delete(can.ui.current) } can.onimport._profile(can, event.target)
return can.ui.current = {target: target, begin: can.core.List([target], function(target) { if (can.page.tagis(target, svg.G)) { return }
return {target: target, height: target.Val(html.HEIGHT), width: target.Val(html.WIDTH), x: target.Val(svg.X), y: target.Val(svg.Y),
ship: can.core.List(target.Value(svg.SHIP), function(ship) { return ship.pid && (ship.target = can.ondetail._select(can, ship.pid)) && ship })
}
}), pos: can.onexport.cursor(event, can, target)}
}
can.ui.current && can.core.List(can.ui.current.begin, function(item) { var figure = can.onfigure._get(can, item.target)
can.onexport.resize(item.target, can.ui.current.pos, points[0], points[1], item), can.ondetail._move(can, item.target, item.ship)
can.ondetail._select(can, item.target.Value(mdb.TEXT), function(text) { text.Value(can.onexport._text(can, item.target, figure, {})) })
})
}, },
}, },
_figure: function(event, can, points) { _auto: function(can, target) {
can._undo && can._undo(), can._undo = function() { can.ui.temp && can.page.Remove(can, can.ui.temp) && delete(can.ui.temp), delete(can._undo) } if (can.point.length > 0) { return }
can.ui.temp = can.core.CallFunc([can.onaction._mode, can.ActionMode()], [event, can, points]), can.ui.points.length == 0 && can._undo && can._undo() if (target.tagName == mdb.TEXT) { return }
},
_group: function(can) { var pos = can.onexport.cursor(event, can, event.target)
can._undo && can._undo(), can._temp = can.onimport.block(can, svg.G, {}, can.ui.group) if (target == can.svg) {
can._undo = function() { can._temp && can.page.Remove(can, can._temp) && delete(can._temp), delete(can._undo) } if (pos == 5) {
return can._temp can.Action(ice.MODE, "draw"), can.Action("shape", html.BLOCK)
}, can.page.Modify(can, target, {style: {cursor: "crosshair"}})
_auto: function(can, target) { if (can.ui.points.length > 0 || can.page.tagis(target, html.TEXT)) { return } } else {
var pos = can.onexport.cursor(event, can, target); if (target == can.ui.svg) { switch (pos) { can.Action(ice.MODE, "resize")
case 5: can.ActionMode(web.DRAW), can.ActionShape(html.BLOCK), can.page.style(can, target, {cursor: html.CROSSHAIR}); break }
default: can.ActionMode(html.RESIZE) } else {
} } else { switch (pos) { switch (pos) {
case 5: can.ActionMode(html.MOVE); break case 5:
case 9: can.ActionMode(html.RESIZE); break case 9: can.Action(ice.MODE, "resize"); break
default: can.ActionMode(web.DRAW), can.ActionShape(svg.LINE) default: can.Action(ice.MODE, "draw"), can.Action("shape", "line")
} }
},
onmouseover: function(event, can) { can.onexport._show(can, event.target) },
onmousemove: function(event, can) {
if (can.ActionGo() == ctx.RUN) { return can.page.style(can, can.ui.svg, {cursor: html.POINTER}) }
if (can.ActionGo() == ice.AUTO) { can.onaction._auto(can, event.target) }
if (can.ActionGo() == "manual") { if (event.target == can.ui.svg) { can.onexport._cursor(can, "") }
if (can.ActionMode()== html.MOVE) {
if (event.target != can.ui.svg) { can.onexport._cursor(can, html.MOVE) }
} else if (can.ActionMode() == html.RESIZE) {
if (event.target != can.ui.svg) { can.onaction._auto(can, event.target), can.ActionMode(html.RESIZE) }
} else { var shape = can.ActionShape()
can.onaction._auto(can, event.target), can.ActionMode("draw"), can.ActionShape(shape)
} }
} }
can.onaction._figure(event, can, can.ui.points.concat(can.onexport._point(event, can)))
can.ui.temp && can.onexport._show(can, can.ui.temp||event.target)
}, },
onclick: function(event, can) { _figure: function(event, can, points, target) {
if (can.ActionGo() == ctx.RUN) { return can.ondetail._select(can, event.target.Value(svg.PID)) } can.temp && can.page.Remove(can, can.temp) && delete(can.temp)
can.onaction._figure(event, can, can.ui.points = can.ui.points.concat(can.onexport._point(event, can))) can.temp = can.core.CallFunc([can.onaction._mode, can.Action(ice.MODE)], [event, can, points, target])
can.point.length == 0 && delete(can.temp)
},
onmouseover: function(event, can) { can.onexport._show(can, event.target) },
onmousemove: function(event, can) { var point = can.onexport._point(event, can)
if (can.Action("go") == ice.RUN) { return }
can.onexport.cursor(event, can, event.target)
if (can.Action("go") == ice.AUTO) { can.onaction._auto(can, event.target) }
can.onaction._figure(event, can, can.point.concat(point))
},
onclick: function(event, can) { var point = can.onexport._point(event, can)
if (can.Action("go") == ice.RUN) { can.onimport._profile(can, event.target)
return event.shiftKey? can.onaction._mode.run(event, can): can.ondetail.run(event, can)
}
can.onaction._figure(event, can, can.point = can.point.concat(point))
},
ondblclick: function(event, can) {
can.ondetail.label(event, can)
}, },
ondblclick: function(event, can) { can.page.style(can, can.ondetail.label(event, can)._target, {left: event.clientX, top: event.clientY}) },
oncontextmenu: function(event, can) { can.page.style(can, can.user.carte(event, can, can.ondetail)._target, {left: event.clientX, top: event.clientY}) },
}) })
Volcanos(chat.ONDETAIL, {list: [cli.START, nfs.COPY, html.LABEL, mdb.REMOVE], _trans: {copy: "复制", label: "标签"}, Volcanos("ondetail", {help: "组件详情", list: [cli.START, ice.RUN, ice.COPY, html.LABEL, mdb.MODIFY, "toimage", mdb.DELETE],
_select: function(can, name, cb) { if (!name) { return } var target = can.page.SelectOne(can, can.ui.svg, nfs.PT+name, cb); if (!target) { return } start: function(event, can) { var target = event.target
can.onimport._profile(can, target), can.onimport._display(can, target), can.onimport.layout(can); return target
},
_move: function(can, target, list) {
can.core.List(list||target.Value(svg.SHIP), function(ship) { var p = can.onexport.anchor(target, ship.anchor, {})
ship.target = can.page.SelectOne(can, can.ui.svg, nfs.PT+ship.pid)
if (ship.which == 1) { ship.target.Val(svg.X1, p.x), ship.target.Val(svg.Y1, p.y) } else if (ship.which == 2) { ship.target.Val(svg.X2, p.x), ship.target.Val(svg.Y2, p.y) }
})
},
start: function(event, can) { event = event._events||event; var target = event.target; if (target == can.ui.svg) { return }
var list = [target], dict = {} var list = [target], dict = {}
for (var i = 0; i < list.length; i++) { var ship = list[i].Value(svg.SHIP) for (var i = 0; i < list.length; i++) { var ship = list[i].Value("ship")
for (var j = 0; j < ship.length; j++) { var pid = ship[j].pid for (var j = 0; j < ship.length; j++) { var pid = ship[j].pid
can.ondetail._select(can, pid, function(target) { var pid = target.Value(svg.SHIP)[1].pid can.page.Select(can, can.svg, ice.PT+pid, function(item) {
can.ondetail._select(can, pid, function(target) { !dict[pid] && list.push(target), dict[pid] = true }) var pid = item.Value("ship")[1].pid
can.page.Select(can, can.svg, ice.PT+pid, function(item) {
!dict[pid] && list.push(item), dict[pid] = true
})
}) })
} }
} }
can.core.Next(list, function(target, next) { can.core.Next(list, function(item, next) { can.core.Timer(3000, function() {
can.onimport._display(can, target), can.user.toast(can, target.Value(ctx.INDEX)) can.onmotion.show(can, {interval: 300, length: 10}, null, item)
can.onmotion.show(can, {interval: 500, length: 10}, null, target) can.user.toast(can, item.Value("index"))
can.onmotion.delay(can, function() { next() }, 1000) can.ondetail.run({target: item}, can), next()
}, function() { can.user.toastSuccess(can) }) }) })
}, },
copy: function(event, can) { event = event._events||event; var target = event.target; if (target == can.ui.svg) { return } run: function(event, can) { var target = event.target
var figure = can.onfigure._get(can, target), trans = can.core.Value(figure, [svg.DATA, svg.TRANS])||{}, data = {} if (!target.Value("pid")) { can.onfigure._pid(can, target) }
data[trans.x||svg.X] = target.Val(trans.x||svg.X)+10, data[trans.y||svg.Y] = target.Val(trans.y||svg.Y)+10
can.core.List(figure.data.copy, function(key) { data[key] = target.Value(key) }) if (can.onmotion.cache(can, function() { return target.Value("pid") }, can.ui.display)) { return }
return can.onimport.block(can, target.tagName, data, can.ui.group)
can.onmotion.clear(can, can.ui.display), can.svg.Value("pid", target.Value("pid"))
var index = target.Value(mdb.INDEX); index && can.onappend.plugin(can, {type: chat.STORY, index: index, args: target.Value(ctx.ARGS)}, function(sub) {
sub.Conf("height", can.Conf("height")-can.svg.Val("height")-52), sub.Conf("width", can.Conf("width"))
sub.run = function(event, cmds, cb) { can.run(event, can.misc.concat(can, [ice.RUN, index], cmds), cb, true) }
can.onmotion.hidden(can, sub._legend), can.onmotion.hidden(can, can.ui.display, true)
}, can.ui.display)
}, },
label: function(event, can) { event = event._events||event; var target = event.target; if (target == can.ui.svg) { return } copy: function(event, can) { can.onfigure._copy(event, can, event.target) },
var _target, text = target.Value(mdb.TEXT); can.ondetail._select(can, text, function(target) { _target = target, text = target.Value(html.INNER) }) label: function(event, can) { var target = event.target
return can.user.input(event, can, [{name: html.LABEL, value: text}], function(list) { var def = target.Value(mdb.TEXT); def && can.page.Select(can, can.svg, ice.PT+def, function(item) {
if (_target) { _target.Value(html.INNER, list[0]); return } if (can.page.tagis(target, html.TEXT)) { target.innerHTML = list[0]; return } def = item.Value(html.INNER)
target.Value(mdb.TEXT, can.onexport._pid(can, can.onimport.block(can, html.TEXT, can.onexport._text(can, target, can.onfigure._get(can, target), {inner: list[0]}), target.Group()) )) })
can.user.prompt(html.LABEL, def, function(text) {
if (target.tagName == html.TEXT) { return target.innerHTML = text }
if (def && can.page.Select(can, can.svg, ice.PT+def, function(item) {
item.Value(html.INNER, text)
}).length > 0) {
return
}
var figure = can.onfigure._get(can, target)
var data = can.onexport._text(can, target, figure, {inner: text})
var item = can.onfigure._push(can, html.TEXT, data, target.Group())
target.Value(mdb.TEXT, can.onfigure._pid(can, item))
}) })
}, },
remove: function(event, can) { event = event._events||event; var target = event.target; if (target == can.ui.svg) { return } modify: function(event, can) { can.onimport._profile(can, event.target) },
can.core.List(target.Value(svg.SHIP), function(item) { can.ondetail._select(can, item.pid, function(target) { can.page.Remove(can, target) }) }) toimage: function(event, can) { can.onmotion.toimage(event, can, can.Option(nfs.PATH).split("/").pop().split(".")[0], can.svg) },
can.ondetail._select(can, target.Value(mdb.TEXT), function(target) { can.page.Remove(can, target) }), can.page.Remove(can, target) "delete": function(event, can) { var target = event.target
if (target == can.svg) { return }
can.core.List(target.Value(ice.SHIP), function(value) {
can.page.Select(can, can.svg, ice.PT+value.pid, function(item) {
can.page.Remove(can, item)
})
})
target.Value(mdb.TEXT) && can.page.Select(can, can.svg, ice.PT+target.Value(mdb.TEXT), function(item) {
can.page.Remove(can, item)
})
can.page.Remove(can, target)
}, },
}) })
Volcanos(chat.ONEXPORT, {list: [svg.GROUP, svg.FIGURE, ctx.INDEX, "pos"], Volcanos("onexport", {help: "导出数据", list: ["group", "figure", "index", "pos"],
_point: function(event, can) { var p = can.ui.svg.getBoundingClientRect(), point = {x: event.clientX-p.x, y: event.clientY-p.y}
point.x = point.x - point.x % can.onexport.grid(can), point.y = point.y - point.y % can.onexport.grid(can)
return can.Status("pos", point.x+mdb.FS+point.y), point
},
_pid: function(can, target) { if (target.Value(svg.PID)) { return target.Value(svg.PID) }
var pid = "p"+can.ui.svg.Val(mdb.COUNT, can.ui.svg.Val(mdb.COUNT)+1)
return target.Value(html.CLASS, [target.Value(html.CLASS), target.Value(svg.PID, pid)].join(lex.SP).trim()), pid
},
_text: function(can, target, figure, data) { var trans = can.core.Value(figure.data, svg.TRANS)||{}
if (figure.text) { return figure.text(can, target, data) }
return data.x = target.Val(trans[svg.X]||svg.X), data.y = target.Val(trans[svg.Y]||svg.Y), data
},
_size: function(can, target, figure) { var trans = can.core.Value(figure.data, svg.TRANS)||{}
return "<("+target.Val(trans[html.WIDTH]||html.WIDTH)+mdb.FS+target.Val(trans[html.HEIGHT]||html.HEIGHT)+")"
},
_position: function(can, target, figure) { var trans = can.core.Value(figure.data, svg.TRANS)||{}
return "@("+target.Val(trans[svg.X]||svg.X)+mdb.FS+target.Val(trans[svg.Y]||svg.Y)+")"
},
_show: function(can, target) { var figure = can.onfigure._get(can, target) _show: function(can, target) { var figure = can.onfigure._get(can, target)
function show() { return can.onexport._position(can, target, figure)+lex.SP+can.onexport._size(can, target, figure) } function show() { return can.onexport._size(can, target, figure)+ice.SP+can.onexport._position(can, target, figure) }
can.Status(svg.FIGURE, can.core.Keys(target.tagName, target.Value(svg.PID))+lex.SP+(figure? (figure.show||show)(can, target, figure): "")) can.Status("figure", target.tagName+":"+target.Value("pid")+ice.SP+(figure? (figure.show||show)(can, target, figure): ""))
can.Status(svg.GROUP, target.Groups()||can.ui.group.Groups()||html.SVG) can.Status("group", target.Groups()||can.group.Groups()||html.SVG)
can.Status(ctx.INDEX, target.Value(ctx.INDEX)||"") can.Status("index", target.Value("index"))
}, },
content: function(can, target) { _size: function(can, target, figure) { var size = figure.data.size||{}
return ['<svg xmlns="https://www.w3.org/2000/svg" vertion="1.1" text-anchor="middle" dominant-baseline="middle"'].concat( return "<("+target.Val(size[html.HEIGHT]||html.HEIGHT)+ice.FS+target.Val(size[html.WIDTH]||html.WIDTH)+")"
target? can.core.List([mdb.COUNT, svg.PID], function(item) { return target.Value(item)? can.base.joinKV([item, target.Value(item)], mdb.EQ): ""}).join(lex.SP): "").concat([">", target? target.innerHTML: "", "</svg>"]).join("")
}, },
grid: function(can) { var grid = can.Action(svg.GRID); return grid == svg.GRID || grid == ice.AUTO? 10: grid }, _position: function(can, target, figure) { var size = figure.data.size||{}
_cursor: function(can, cursor) { can.page.style(can, can.ui.svg, {cursor: cursor}) }, return "@("+target.Val(size[svg.X]||svg.X)+ice.FS+target.Val(size[svg.Y]||svg.Y)+")"
cursor: function(event, can, target) { },
var p = target.getBoundingClientRect(), q = {x: event.clientX, y: event.clientY}, pos = 5, margin = 20 _text: function(can, target, figure, data) { var size = figure.data.size||{}
var y = (q.y-p.y)/p.height; if (y < 0.2 && q.y-p.y < margin) { pos -= 3 } else if (y > 0.8 && q.y-p.y-p.height > -margin) { pos += 3 } if (figure.text) { return figure.text(can, data, target) }
var x = (q.x-p.x)/p.width; if (x < 0.2 && q.x-p.x < margin) { pos -= 1 } else if (x > 0.8 && q.x-p.x- p.width > -margin) { pos += 1 } return data.x = target.Val(size[svg.X]||svg.X), data.y = target.Val(size[svg.Y]||svg.Y), data
return can.ui.svg.style.cursor = ["nw-resize", "n-resize", "ne-resize", "w-resize", html.MOVE, "e-resize", "sw-resize", "s-resize", "se-resize"][pos-1], pos },
_point: function(event, can) {
var p = can.svg.getBoundingClientRect()
var point = {x: event.clientX-p.x, y: event.clientY-p.y}
point.x = point.x - point.x % parseInt(can.Action("grid"))
point.y = point.y - point.y % parseInt(can.Action("grid"))
return can.Status("pos", point.x+ice.FS+point.y), point
},
content: function(can, svg) {
return ['<svg vertion="1.1" xmlns="https://www.w3.org/2000/svg" text-anchor="middle" dominant-baseline="middle"'].concat(
svg? can.core.List([html.HEIGHT, html.WIDTH, mdb.COUNT, "pid", "grid", html.STROKE_WIDTH, html.STROKE, html.FILL, html.FONT_SIZE], function(item) {
return svg.Value(item)? ice.SP + item + '="' + svg.Value(item) + '"': ""
}): [" height="+((can.Conf(html.HEIGHT)||450)-50)+" width="+(can.Conf(html.WIDTH)||600)]).concat(['>', svg? svg.innerHTML: "", "</svg>"]).join("")
},
cursor: function(event, can, item, show) {
var p = item.getBoundingClientRect()
var q = {x: event.clientX, y: event.clientY}
var pos = 5, margin = 20
var y = (q.y-p.y)/p.height
if (y < 0.2 && q.y-p.y < margin) {
pos -= 3
} else if (y > 0.8 && q.y-p.y-p.height > -margin) {
pos += 3
}
var x = (q.x-p.x)/p.width
if (x < 0.2 && q.x-p.x < margin) {
pos -= 1
} else if (x > 0.8 && q.x-p.x- p.width > -margin) {
pos += 1
}
return (show||can.svg).style.cursor = [
"nw-resize", "n-resize", "ne-resize",
"w-resize", "move", "e-resize",
"sw-resize", "s-resize", "se-resize",
][pos-1], pos
}, },
anchor: function(target, pos, point) { anchor: function(target, pos, point) {
switch (pos) { switch (pos) {
case 1: case 1:
case 2: case 2:
case 3: point.y = target.Val(svg.Y); break case 3:
point.y = target.Val(svg.Y)
break
case 4: case 4:
case 5: case 5:
case 6: point.y = target.Val(svg.Y) + target.Val(html.HEIGHT)/2; break case 6:
point.y = target.Val(svg.Y) + target.Val(html.HEIGHT) / 2
break
case 7: case 7:
case 8: case 8:
case 9: point.y = target.Val(svg.Y) + target.Val(html.HEIGHT); break case 9:
point.y = target.Val(svg.Y) + target.Val(html.HEIGHT)
break
} }
switch (pos) { switch (pos) {
case 1: case 1:
case 4: case 4:
case 7: point.x = target.Val(svg.X); break case 7:
point.x = target.Val(svg.X)
break
case 2: case 2:
case 5: case 5:
case 8: point.x = target.Val(svg.X) + target.Val(html.WIDTH)/2; break case 8:
point.x = target.Val(svg.X) + target.Val(html.WIDTH) / 2
break
case 3: case 3:
case 6: case 6:
case 9: point.x = target.Val(svg.X) + target.Val(html.WIDTH); break case 9:
} return point point.x = target.Val(svg.X) + target.Val(html.WIDTH)
break
}
return point
}, },
resize: function(target, pos, p0, p1, begin) { resize: function(event, item, begin, p0, p1, pos) {
if (pos == 5) { target.Value(svg.X, begin.x + p1.x - p0.x), target.Value(svg.Y, begin.y + p1.y - p0.y); return } switch (pos) {
case 5:
item.Value(svg.X, begin.x + p1.x - p0.x)
item.Value(svg.Y, begin.y + p1.y - p0.y)
return
}
switch (pos) { switch (pos) {
case 1: case 1:
case 2: case 2:
case 3: target.Value(svg.Y, begin.y + p1.y - p0.y), target.Value(html.HEIGHT, begin.height - p1.y + p0.y); break case 3:
case 7: item.Value(svg.Y, begin.y + p1.y - p0.y)
case 8: item.Value(html.HEIGHT, begin.height - p1.y + p0.y)
case 9: target.Value(html.HEIGHT, begin.height + p1.y - p0.y); break break
} }
switch (pos) { switch (pos) {
case 1: case 1:
case 4: case 4:
case 7: target.Value(svg.X, begin.x + p1.x - p0.x), target.Value(html.WIDTH, begin.width - p1.x + p0.x); break case 7:
item.Value(sve.X, begin.x + p1.x - p0.x)
item.Value(html.WIDTH, begin.width - p1.x + p0.x)
break
}
switch (pos) {
case 3: case 3:
case 6: case 6:
case 9: target.Value(html.WIDTH, begin.width + p1.x - p0.x); break case 9:
item.Value(html.WIDTH, begin.width + p1.x - p0.x)
break
}
switch (pos) {
case 7:
case 8:
case 9:
item.Value(html.HEIGHT, begin.height + p1.y - p0.y)
break
} }
}, },
}) })
Volcanos(chat.ONFIGURE, {
_get: function(can, target, name) { return can.onfigure[name]||can.onfigure[target.getAttribute(mdb.NAME)]||can.onfigure[target.tagName] },
svg: {show: function(can, target, figure) { return can.onexport._size(can, target, figure) }},
rect: { // <rect x="60" y="10" height="30" width="30" rx="10" ry="10"/>
data: {points: 2, rx: 4, ry: 4, copy: [html.HEIGHT, html.WIDTH, svg.RX, svg.RY]},
draw: function(event, can, points, style) { var p0 = points[0], p1 = points[1]
return {x: Math.min(p0.x, p1.x), y: Math.min(p0.y, p1.y), height: Math.abs(p0.y-p1.y), width: Math.abs(p0.x-p1.x), rx: style.rx == undefined? this.data.rx: style.rx, ry: style.ry == undefined? this.data.ry: style.ry}
},
text: function(can, target, data) { return data.x = target.Val(svg.X)+target.Val(html.WIDTH)/2, data.y = target.Val(svg.Y)+target.Val(html.HEIGHT)/2, data },
},
line: { // <line x1="10" y1="10" x2="110" y2="150"/>
data: {points: 2, trans: {x: svg.X1, y: svg.Y1}, copy: [svg.X1, svg.Y1, svg.X2, svg.Y2]},
grid: function(event, can, points) { var target = event.target; if (target == can.ui.svg) { return }
var p = points[points.length-1], pos = can.onexport.cursor(event, can, target); can.onexport.anchor(target, pos, p)
return p.target = target, p.anchor = pos, points
},
draw: function(event, can, points) { var p0 = points[0], p1 = points[1], ship = []
p0.target && p0.target.Value && ship.push({pid: p0.target.Value(svg.PID)})
p1.target && p1.target.Value && ship.push({pid: p1.target.Value(svg.PID)})
return {x1: p0.x, y1: p0.y, x2: p1.x, y2: p1.y, ship: ship.length > 0? ship: undefined}
},
text: function(can, target, data) { return data.x = (target.Val(svg.X1)+target.Val(svg.X2))/2, data.y = (target.Val(svg.Y1)+target.Val(svg.Y2))/2, data },
show: function(can, target, figure) { return can.onexport._position(can, target, figure)+" <("+(target.Val(svg.X2)-target.Val(svg.X1))+mdb.FS+(target.Val(svg.Y2)-target.Val(svg.Y1))+")" },
},
text: { // <text x="60" y="10">hi</text>
data: {points: 1, copy: [html.INNER]},
draw: function(event, can, points, style) { if (event.type == "mousemove") { return }
var p0 = points[0]; return {x: p0.x, y: p0.y, inner: style.inner||can.user.prompt(mdb.TEXT)}
},
show: function(can, target, figure) { return can.onexport._position(can, target, figure) }
},
block: { // <rect x="60" y="10" height="30" width="30" rx="10" ry="10"/>
data: {points: 2, rx: 4, ry: 4, copy: [html.HEIGHT, html.WIDTH, svg.RX, svg.RY]},
draw: function(event, can, points, style) { var group = can.onaction._group(can)
var target = can.onimport.block(can, svg.RECT, can.onfigure.rect.draw(event, can, points, style), group)
if (event.type == html.CLICK) { can.onexport._pid(can, target), delete(can._temp) }
},
text: function(can, target, data) { can.onfigure.rect.text(can, data, target) },
},
circle: { // <cx="25" cy="75" r="20"/>
data: {points: 2, trans: {x: svg.CX, y: svg.CY, height: svg.R, width: svg.R}, copy: [svg.R]},
draw: function(event, can, points) { var p0 = points[0], p1 = points[1]; return {cx: p0.x, cy: p0.y, r: parseInt(Math.sqrt(Math.pow(p0.x-p1.x, 2)+Math.pow(p0.y-p1.y, 2)))} },
},
ellipse: { // <ellipse cx="75" cy="75" rx="20" ry="5"/>
data: {points: 2, trans: {x: svg.CX, y: svg.CY, height: svg.RY, width: svg.RX}, copy: [svg.RY, svg.RX]},
draw: function(event, can, points) { var p0 = points[0], p1 = points[1]; return {cx: p0.x, cy: p0.y, ry: Math.abs(p0.y - p1.y), rx: Math.abs(p0.x - p1.x)} },
},
}, [])
Volcanos(chat.ONKEYMAP, {
_mode: {
plugin: {
Escape: function(event, can) { can._undo && can._undo(), can.ui.points = [] },
gr: function(event, can) { can.ActionGo(ctx.RUN) },
ga: function(event, can) { can.ActionGo(ice.AUTO) },
gm: function(event, can) { can.ActionGo("manual") },
ad: function(event, can) { can.ActionMode(web.DRAW) },
am: function(event, can) { can.ActionMode(html.MOVE) },
ar: function(event, can) { can.ActionMode(html.RESIZE) },
st: function(event, can) { can.ActionShape(svg.TEXT) },
sr: function(event, can) { can.ActionShape(svg.RECT) },
sl: function(event, can) { can.ActionShape(svg.LINE) },
ss: function(event, can) { can.ActionShape(svg.LINE) },
sc: function(event, can) { can.ActionShape(svg.CIRCLE) },
se: function(event, can) { can.ActionShape(svg.ELLIPSE) },
cr: function(event, can) { can.onaction._change(can, svg.STROKE, cli.RED) },
cb: function(event, can) { can.onaction._change(can, svg.STROKE, cli.BLUE) },
cg: function(event, can) { can.onaction._change(can, svg.STROKE, cli.GREEN) },
cy: function(event, can) { can.onaction._change(can, svg.STROKE, cli.YELLOW) },
cp: function(event, can) { can.onaction._change(can, svg.STROKE, cli.PURPLE) },
cc: function(event, can) { can.onaction._change(can, svg.STROKE, cli.CYAN) },
ch: function(event, can) { can.onaction._change(can, svg.STROKE, cli.BLACK) },
cw: function(event, can) { can.onaction._change(can, svg.STROKE, cli.WHITE) },
fr: function(event, can) { can.onaction._change(can, svg.FILL, cli.RED) },
fb: function(event, can) { can.onaction._change(can, svg.FILL, cli.BLUE) },
fg: function(event, can) { can.onaction._change(can, svg.FILL, cli.GREEN) },
fy: function(event, can) { can.onaction._change(can, svg.FILL, cli.YELLOW) },
fp: function(event, can) { can.onaction._change(can, svg.FILL, cli.PURPLE) },
fc: function(event, can) { can.onaction._change(can, svg.FILL, cli.CYAN) },
fh: function(event, can) { can.onaction._change(can, svg.FILL, cli.BLACK) },
fw: function(event, can) { can.onaction._change(can, svg.FILL, cli.WHITE) },
},
}, _engine: {},
})

View File

@ -1,4 +1,4 @@
Volcanos("heart", { Volcanos("heart", {help: "心形", list: [],
data: {name: "path", size: {}, data: {name: "path", size: {},
copy: ["d", "name", "meta", "tt", "xx", "yy"], copy: ["d", "name", "meta", "tt", "xx", "yy"],
x: function(event, can, value, cmd, target) { x: function(event, can, value, cmd, target) {
@ -57,3 +57,4 @@ Volcanos("heart", {
return "heart " + target.Value("tt") return "heart " + target.Value("tt")
}, },
}) })

View File

@ -1,4 +1,4 @@
Volcanos(chat.ONFIGURE, { Volcanos("onfigure", {help: "图形绘制", list: [],
path2v: { // <path d="M x0,y0 Q x2,y2 x3,y3 T x1,y1"/> path2v: { // <path d="M x0,y0 Q x2,y2 x3,y3 T x1,y1"/>
data: {name: "path", size: {}, copy: []}, data: {name: "path", size: {}, copy: []},
draw: function(event, can, point) { draw: function(event, can, point) {
@ -60,8 +60,7 @@ Volcanos(chat.ONFIGURE, {
if (i < skip) {return} if (i < skip) {return}
switch (i) { switch (i) {
case 0: k = "M"; break case 0: k = "M"; break
default: k = p.k || "L"; break default: k = can._temp[i] || p.k || "L"; break
// default: k = can._temp[i] || p.k || "L"; break
} }
if (end) {return} if (end) {return}
@ -150,3 +149,4 @@ Volcanos(chat.ONFIGURE, {
show: function(can, target) { return target.tagName + " " + target.Value("d") }, show: function(can, target) { return target.tagName + " " + target.Value("d") },
}, },
}) })

View File

@ -1,8 +1,8 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [],
init: function(can, msg, cb, output, action, option) {output.innerHTML = ""; init: function(can, msg, cb, output, action, option) {output.innerHTML = "";
if (!msg.result || msg.result.length == 0) { if (!msg.result || msg.result.length == 0) {
var table = can.page.AppendTable(can, msg, output, msg.append); var table = can.page.AppendTable(can, msg, output, msg.append);
table.onclick = function(event) { can.misc.Event(event, can, function(msg) { switch (event.target.tagName) { table.onclick = function(event) {switch (event.target.tagName) {
case "TD": case "TD":
can.onimport.which(event, table, msg.append, function(index, key) { can.onimport.which(event, table, msg.append, function(index, key) {
can.Option("file", event.target.innerHTML.trim()) can.Option("file", event.target.innerHTML.trim())
@ -13,7 +13,7 @@ Volcanos(chat.ONIMPORT, {
break break
case "TR": case "TR":
case "TABLE": case "TABLE":
} }) } }}
return can.base.isFunc(cb) && cb(msg), table; return can.base.isFunc(cb) && cb(msg), table;
} }
@ -147,3 +147,4 @@ Volcanos(chat.ONIMPORT, {
}) })
}, },
}) })

View File

@ -1,44 +1,15 @@
fieldset.feel>form.option>div.item.file { display:none; } fieldset.feel div.output img {
body.mobile fieldset.feel>form.option>div.item.file { display:none; } display:block; float:left;
fieldset.feel.fullscreen>div.action>div.item:not(.fullscreen) { display:none; } }
fieldset.feel>div.output>div.project>div.albums { display:flex; flex-wrap:wrap; } fieldset.feel div.output video {
fieldset.feel>div.output>div.project>div.albums>div.item.album { border-bottom:var(--box-notice3); border-color:transparent; width:33.3%; display:flex; flex-direction:column; } display:block; float:left;
fieldset.feel>div.output>div.project>div.albums>div.item.album.select { border-bottom:var(--box-notice3); border-right:none; } }
fieldset.feel>div.output>div.project>div.albums>div.item.album.create { height:calc(var(--project-width)/3 - 10px); font-size:42px; display:flex; justify-content:center; align-items:center; } fieldset.feel.float>legend {
fieldset.feel>div.output>div.project>div.albums>div.item.album img { height:calc(var(--project-width)/3 - 10px); width:100%; object-fit:cover; } display:none;
fieldset.feel>div.output>div.project>div.item.select { border-width:3px; } }
fieldset.feel>div.output>div.project>div.item>img { padding:5px; } fieldset.feel.float {
fieldset.feel>div.output>div.project>div.item>span.name { flex-grow:1; overflow:hidden; } margin:0 10px; padding:0 10px;
fieldset.feel>div.output>div.project>div.item>span.progress { color:var(--notice-bg-color); margin-left:10px; } background-color:#4eaad0c2;
fieldset.feel>div.output>div.project>div.item>span.size { color:var(--disable-fg-color); font-size:var(--status-font-size); margin-left:10px; } position:absolute;
fieldset.feel>div.output>div.project>div.item>span.time { color:var(--disable-fg-color); font-size:var(--status-font-size); margin-left:10px; } top:26px;
fieldset.feel>div.output>div.layout>div.display { overflow:hidden; position:relative; } }
fieldset.feel>div.output>div.layout>div.display:not(.hide) { height:100px; display:flex; justify-content:center; align-items:center; gap:10px; }
fieldset.feel>div.output>div.layout>div.display>.select { border:var(--box-notice); border-width:3px; }
fieldset.feel>div.output>div.layout>div.display>img { height:100px; width:100px; object-fit:contain; }
fieldset.feel>div.output>div.layout>div.display>video { height:100px; width:100px; object-fit:contain; }
fieldset.feel>div.output>div.layout>div.display>div.audio { word-break:break-all; height:100px; width:100px; display:flex; align-items:end; }
fieldset.feel>div.output>div.layout>div.display>div.audio:not(.select) { border:var(--box-border); }
fieldset.feel>div.output>div.layout>div.display>div.audio img.cover { height:98px; width:98px; position:absolute; }
fieldset.feel>div.output>div.layout>div.display>div.audio.select img.cover { height:94px; width:94px; position:absolute; }
fieldset.feel>div.output>div.layout>div.display>div.audio span.name { background-color:var(--hover-bg-color); color:white; z-index:5; }
fieldset.feel>div.output>div.layout>div.display>*.select { background-color:var(--hover-bg-color); }
fieldset.feel>div.output>div.layout>div.display>*:hover { background-color:var(--hover-bg-color); cursor:pointer; }
fieldset.feel>div.output>div.layout>div.display>img:hover { background-color:var(--hover-bg-color); cursor:pointer; }
fieldset.feel>div.output>div.layout>div.display>video:hover { background-color:var(--hover-bg-color); cursor:pointer; }
fieldset.feel>div.output>div.layout>div.display>div.audio:hover { background-color:var(--hover-bg-color); cursor:pointer; }
fieldset.feel>div.output>div.layout>div.display>div.toggle { font-size:32px; padding:5px; padding-top:32px; height:100px; position:absolute; }
fieldset.feel>div.output>div.layout>div.display>div.toggle.prev { left:0; }
fieldset.feel>div.output>div.layout>div.display>div.toggle.next { right:0; }
fieldset.feel>div.output>div.layout>div.layout>div.content { padding:0; overflow:hidden; }
fieldset.feel>div.output>div.layout>div.layout>div.content>img { height:100%; width:100%; object-fit:scale-down; cursor:pointer; }
fieldset.feel>div.output>div.layout>div.layout>div.content>video { height:100%; width:100%; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.audio { height:100%; width: 100%; display:flex; flex-direction:column; justify-content:center; align-items:center; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.audio img.cover { height:calc(100% - 120px); }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.audio span.name { padding:10px; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.progress { background-color:var(--notice-bg-color); height:3px; position:absolute; bottom:2px; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.toggle { font-size:32px; padding:5px; padding-top:32px; height:100px; top:40%; z-index:5; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.toggle.next { right:0; }
fieldset.feel>div.output>div.layout>div.layout>div.content>div.toggle.prev { left:0; }
div.toggle { -webkit-user-select:none; }
img { -webkit-user-select:none; }

View File

@ -1,206 +1,125 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
_init: function(can, msg, cb) { can.onappend.style(can, wiki.FEEL) can.path = can.request(), can.list = [], msg.Table(function(value) {
can.run({}, [], function(_msg) { can.db.albums = _msg value.path.lastIndexOf(ice.PS)==value.path.length-1? can.path.Push(value): can.list.push(value)
can.ui = can.onappend.layout(can)
// can.user.isMobile && (can.onaction.list = [web.UPLOAD])
cb && cb(msg)
if (can.base.isIn(can.Action("sort")||"", mdb.TIME, "")) {
can.onimport._project(can, msg)
} else {
can.onaction.sort({}, can, "sort", can.Action("sort"))
} can.onimport.page(can, can.db.list, can.db.begin = 0)
can.onmotion.toggle(can, can.ui.display, can.page.isDisplay(can.ui.project)), can.onimport.layout(can)
}) })
can.onmotion.toggle(can, can._action, true)
can.base.isFunc(cb) && cb(msg)
can.ui = can.onlayout.display(can, target)
can.onappend.table(can, can.path, null, can.ui.content)
can.dir_root = msg.Option("dir_root")
can.Action("height", msg.Option("height")||"100")
can.Action("limit", msg.Option("limit")||"6")
can.Action("rate", msg.Option("rate")||"1")
can.onmotion.hidden(can, can._action)
can.begin = msg.Option("begin")||"0"
can.onimport.page(can, can.list)
}, },
_project: function(can, msg) { can.db.list = [], can.db.dir_root = msg.Option(nfs.DIR_ROOT) _file: function(can, path, index) { var p = location.href.indexOf("http") == 0? "": "http://localhost:9020"
can.ui.albums = can.page.Appends(can, can.ui.project, ["albums"])._target return path.indexOf("http") == 0? path: p+can.base.Path("/share/local", can.dir_root||"", path)
can.db.albums.Table(function(value) {
can.page.Append(can, can.ui.albums, [{view: "item album "+(can.base.beginWith(can.Option(nfs.PATH), value.path)? "select": ""), background: value.cover, list: [
{img: can.misc.Resource(can, value.cover||"usr/icons/background.jpg")}, {text: value.name},
], onclick: function(event) {
can.Option(nfs.PATH, value.path), can.Update()
}, oncontextmenu: function(event) {
can.user.carteItem(event, can, value)
}}])
})
can.page.Append(can, can.ui.albums, [{view: ["item album create", "", "+"], onclick: function(event) {
can.Update(event, [ctx.ACTION, mdb.CREATE])
}}])
can.ui.filter = can.onappend.filter(can, can.ui.project)
msg.Table(function(item) { item.name = can.base.trimPrefix(item.path, can.Option(nfs.PATH))
can.base.endWith(item.path, "/") && (item.nick = [{img: can.misc.Resource(can, "usr/icons/dir.png")}, {text: [item.name, "", mdb.NAME]}])
can.base.endWith(item.path, nfs.PS)? can.onimport.item(can, item, function(event) { can.Option(nfs.PATH, item.path) && can.Update(event) }): can.db.list.push(item)
})
can.onmotion.cacheClear(can, "", can.ui.content)
can.db.hash[0] && msg.path.indexOf(can.db.hash[0]) == -1 && (can.db.hash[0] = "")
can.core.List(can.db.list, function(item, index) { var last = can.onexport.progress(can, "p."+item.path);
(!can.db.hash[0] || can.db.hash[0] == can.Option(nfs.PATH) || can.db.hash[0].indexOf(can.Option(nfs.PATH)) == -1) && (can.db.hash[0] = item.path)
item.nick = [item.cover? {img: can.misc.Resource(can, item.cover)}:
can.misc.isImage(can, item.path)? {img: can.misc.Resource(can, item.path)}:
can.misc.isVideo(can, item.path)? {img: can.misc.Resource(can, "usr/icons/QuickTime Player.png")}:
can.misc.isAudio(can, item.path)? {img: can.misc.Resource(can, "usr/icons/Music.png")}: null,
{text: [item.name, "", mdb.NAME]}, {text: [last||"", "", "progress"]},
can.Option(nfs.PATH) != "usr/icons/" && can.base.isIn(can.Action("sort")||"", mdb.TIME, "")? {text: [can.base.TimeTrim(item.time), "", mdb.TIME]}: {text: [item.size, "", nfs.SIZE]},
]
item.title = [item.time, item.path, item.size].join("\n")
item._hash = item.path, item._title = item.path.split("/").pop()
item._target = can.onimport.item(can, item, function(event, item, show, target) { can.onimport._content(can, item, index, target) })
item.title = ""
})
}, },
_content: function(can, item, index, target) { can.Option(nfs.FILE, item.name), can.Status(item), can.ui.video = item._video, can.ui.current = item file: function(can, path, index) { path = can.onimport._file(can, path, index)
if (can.onexport.progress(can, "p."+item.path) == "100%") { can.onexport.progress(can, "p."+item.path, ""), can.onexport.progress(can, item.path, "") } var cb = can.onfigure[can.base.Ext(path)]; can.Status("file", path)
if (can.misc.isImage(can, item.path)) { can.onmotion.delay(can, function() { can.onaction.playnext(can) }, 5000) } can.base.isFunc(cb) && can.page.Append(can, can.ui.display, [cb(can, path, index)])
if (!can.onmotion.cache(can, function() { return item.path }, can.ui.content)) { var progress
item._cb = function(event, video) { can.ui.video = item._video = video
var p = parseInt(video.currentTime*100/video.duration); can.page.Select(can, target, "span.progress", function(target) { target.innerText = p+"%" })
if (!progress) { progress = can.page.Append(can, can.ui.content, ["progress"])._target } can.page.style(can, progress, html.WIDTH, can.ui.content.offsetWidth*p/100)
}
var _target = can.onimport.file(can, item.path, item, index, can.ui.content, true); _target.focus()
can.onappend._toggle(can, can.ui.content, function() { can.onaction.prev({}, can) }, function() { can.onaction.next({}, can) })
}
if (index < can.db.begin || index >= can.db.begin+can.db.limit) {
can.onimport.page(can, can.db.list, can.db.begin = index-index%can.db.limit)
} can.onmotion.select(can, can.ui.display, "*", item._display)
}, },
_file: function(can, path) { page: function(can, list, begin, limit) { can.onmotion.clear(can, can.ui.display)
return can.misc.Resource(can, can.db.dir_root+path, can.ConfSpace()) begin = parseInt(begin||can.begin), limit = parseInt(limit||can.Action("limit"))
for (var i = begin; i < begin+limit; i++) { list && list[i] && can.onimport.file(can, list[i].path, i) }
can.Status({begin: begin, limit: limit, total: can.list.length})
}, },
file: function(can, path, item, index, target, auto) { item._path = path = can.onimport._file(can, path) }, ["/plugin/local/wiki/feel.css"])
var cb = can.onfigure[can.base.Ext(path)]||can.onfigure[wiki.IMAGE] Volcanos("onfigure", {help: "组件菜单", list: [],
return cb && can.page.Append(can, target||can.ui.display, [cb(can, item, auto)])._target png: function(can, path, index) { return can.onfigure.image(can, path, index) },
}, jpg: function(can, path, index) { return can.onfigure.image(can, path, index) },
page: function(can, list, begin) { can.onmotion.clear(can, can.ui.display) jpeg: function(can, path, index) { return can.onfigure.image(can, path, index) },
begin = parseInt(begin||can.db.begin||0), can.db.limit = can.base.Min((parseInt(can.ui.display.offsetWidth/110)||5)-1, 3) image: function(can, path, index) { return {img: path, height: can.Action("height"), onclick: function(event) {
for (var i = begin; i < begin+can.db.limit; i++) { if (list && list[i]) { list[i]._display = can.onimport.file(can, list[i].path, list[i], i) } } can.ondetail._init(can, index)
can.onappend._toggle(can, can.ui.display, function(event) { can.onaction.prevpage(event, can) }, function(event) { can.onaction.nextpage(event, can) }) }, _init: function(target) { can.Status("file", path) },
can.Status({begin: begin, limit: can.db.limit, total: list.length}) onmouseover: function(event) { can.Status("file", path) },
}, } },
}, [""])
Volcanos(chat.ONFIGURE, { video: function(can, path) { var auto = can.user.isMobile&&can.Action("limit")!="1"? false: true, loop = true, total = 0; function cb(event) { }
png: function(can, item) { return can.onfigure.image(can, item) }, return {type: "video", style: {height: parseInt(can.Action("height"))}, className: "preview",
gif: function(can, item) { return can.onfigure.image(can, item) }, data: {src: path, controls: "controls", autoplay: auto, loop: loop, playbackRate: parseFloat(can.Action("rate"))},
jpg: function(can, item) { return can.onfigure.image(can, item) }, oncontextmenu: cb, onplay: cb, onpause: cb, onended: cb,
jpeg: function(can, item) { return can.onfigure.image(can, item) }, onmouseover: function(event) { can.Status("file", path) },
image: function(can, item) { return {img: item._path, title: item.title, onclick: function(event) { item._target.click() }} }, onloadedmetadata: function(event) { total = event.timeStamp
video: function(can, item, auto) { var init, last = can.onexport.progress(can, item.path)||0 event.target.currentTime = can._msg.currentTime || 0
var meta = {type: html.VIDEO, title: item.title, data: {src: item._path, controls: auto, autoplay: auto}, }, onloadeddata: cb, ontimeupdate: function(event) {
onclick: function(event) { item._target.click() }, can.Status("file") == path && can.Status("position", can.onexport.position(can, (can._msg.currentTime=event.target.currentTime)-1, event.target.duration))
onratechange: function(event) { can.onexport.storage(can, "rate", event.target.playbackRate) },
onvolumechange: function(event) { can.onexport.storage(can, "volume", event.target.volume) },
onloadedmetadata: function(event) { item._cb && item._cb(event, event.target)
event.target.volume = can.onexport.storage(can, "volume")||0.5
event.target.playbackRate = can.onexport.storage(can, "rate")||1
}, },
ontimeupdate: function(event) { if (event.target.currentTime == 0) { return } item._cb && item._cb(event, event.target)
can.Status("position", can.onexport.position(can, event.target.currentTime-1, event.target.duration))
can.onexport.progress(can, "p."+item.path, parseInt(event.target.currentTime*100/event.target.duration)+"%")
can.onexport.progress(can, item.path, event.target.currentTime)
if (!init) { init = true, event.target.currentTime = last }
},
onended: function(event) { can.onaction.playnext(can) },
} }
if (!auto && can.misc.isVideo(can, item.path) && !can.user.isChrome) {
return {view: html.AUDIO, list: [{img: can.misc.Resource(can, item.cover||"usr/icons/QuickTime Player.png", can.ConfSpace()), className: "cover"}, {text: [item.name, "", mdb.NAME]}], onclick: meta.onclick}
}
return meta
}, },
audio: function(can, item, auto) { var meta = can.onfigure.video(can, item, auto); meta.type = html.AUDIO mp4: function(can, path) { return can.onfigure.video(can, path) },
return {view: html.AUDIO, list: [{img: can.misc.Resource(can, item.cover||"usr/icons/Music.png", can.ConfSpace()), className: "cover"}, {text: [item.name, "", mdb.NAME]}, meta], onclick: meta.onclick} m4v: function(can, path) { return can.onfigure.video(can, path) },
}, mov: function(can, path) { return can.onfigure.video(can, path) },
webm: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
mov: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
m4v: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
mp4: function(can, item, auto) { return can.onfigure.video(can, item, auto) },
mp3: function(can, item, auto) { return can.onfigure.audio(can, item, auto) },
}) })
Volcanos(chat.ONACTION, { Volcanos("onaction", {help: "组件菜单", list: [
list: [ ["height", 100, 200, 400, 600, 800],
"mkdir", "upload", "record1", "record2", ["limit", 1, 3, 6, 9, 12, 15, 20, 30],
["sort", mdb.TIME, nfs.PATH, nfs.SIZE], ["rate", 0.1, 0.2, 0.5, 1, 2, 3, 5, 10],
["order", "repeat", "range", "loop", "random"],
], ],
record0: function(event, can, name, cb) { can.user.input(event, can, [{name: nfs.FILE, value: name}], function(list) { "上一页": function(event, can, key, value) {
var height = window.innerHeight, width = window.innerWidth can.begin > 0 && (can.begin -= parseInt(can.Action("limit")), can.onimport.page(can, can.list))
navigator.mediaDevices.getDisplayMedia({video: {height: height*8, width: width*8}}).then(function(stream) { },
can.core.Next([3, 2, 1], function(item, next) { can.user.toast(can, item + "s 后开始截图"), can.onmotion.delay(can, next, 1000) }, function() { can.onmotion.clearFloat(can) "下一页": function(event, can, key, value) {
can.onmotion.delay(can, function() { can.begin + parseInt(can.Action("limit")) < can.list.length && (can.begin += parseInt(can.Action("limit")), can.onimport.page(can, can.list))
cb(stream, function(blobs, ext) { var msg = can.request(event); msg._upload = new File(blobs, list[0]+nfs.PT+ext) },
can.runAction(msg, html.UPLOAD, [], function(msg) { can.user.toast(can, "上传成功")
can.db.hash = can.onexport.hash(can, encodeURIComponent(msg.Result())), can.Update() "height": function(event, can, key, value) {
}), can.core.List(stream.getTracks(), function(item) { item.stop() }) can.Action("height", value), can.onimport.page(can, can.list)
}) },
}, 300) "limit": function(event, can, key, value) {
can.Action("limit", value), can.onimport.page(can, can.list)
},
"rate": function(event, can, key, value) {
can.Action("rate", value), can.onimport.page(can, can.list)
},
chooseImage: function(event, can) { var msg = can.request(event)
can.user.agent.chooseImage(function(list) { can.core.List(list, function(item) {
can.page.Append(can, can._output, [{img: item, height: 200}])
}) })
},
})
Volcanos("ondetail", {help: "组件菜单", list: ["关闭", "下载", "删除", "上一个", "下一个", "设置头像", "设置背景", "复制链接"], _init: function(can, index) {
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.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)
can.order = index, can.show = function(order) {
path = can.onimport._file(can, can.list[order].path)
sub.page.Appends(sub, sub._output, [{img: path, style: {"max-width": width-40, "max-height": height-55}}])
sub.Status("begin", order+1+ice.PS+can.list.length), sub.Status("file", path)
}, can.show(can.order)
}) })
}).catch(function(err) { can.user.toast(can, err.name + ": " + err.message) }) }, document.body)
}) },
record1: function(event, can) { can.onaction.record0(event, can, "Screenshot "+can.base.Time(null), function(stream, cb) { var height = window.innerHeight
var video = can.page.Append(can, document.body, [{type: html.VIDEO, height: height}])._target; video.srcObject = stream, video.onloadedmetadata = function() {
video.play(), height = video.offsetHeight, width = video.offsetWidth
var canvas = can.page.Append(can, document.body, [{type: html.CANVAS, height: height, width: width}])._target; canvas.getContext("2d").drawImage(video, 0, 0, width, height)
canvas.toBlob(function(blob) { cb([blob], nfs.PNG) })
}
}) },
record2: function(event, can) { if (can.ui.recorder) { return can.ui.recorder.stop() }
can.onaction.record0(event, can, "Screenshot "+can.base.Time(null), function(stream, cb) {
if (can.user.isChrome) {
var recorder = new MediaRecorder(stream, {mimeType: "video/webm;codecs=vp8"})
recorder.onstop = function() { delete(can.ui.recorder), cb(blobs, "webm") }
// var recorder = new MediaRecorder(stream, {mimeType: 'video/mp4; codecs="avc1.4d002a"'})
// recorder.onstop = function() { delete(can.ui.recorder), cb(blobs, "mp4") }
} else {
var recorder = new MediaRecorder(stream, {mimeType: "video/mp4"})
recorder.onstop = function() { delete(can.ui.recorder), cb(blobs, "mp4") }
}
var blobs = []; recorder.ondataavailable = function(res) { blobs.push(res.data) }
can.ui.recorder = recorder, recorder.start(1)
})
}, },
fullscreen: function(event, can, button) { var show = can.onmotion.toggle(can, can.ui.project) "关闭": function(event, can) { can.page.Remove(can, can.sub._target) },
can.onmotion.toggle(can, can.ui.display, show), can.onmotion.toggle(can, can._status, show) "下载": function(event, can) { can.user.download(can, path = can.onimport._file(can, can.list[can.order].path)) },
can.page.ClassList.set(can, can._fields, button, !show), can.page.ClassList.set(can, can.ui.content, html.FLOAT, !show) "删除": function(event, can) {
can.sup.onimport.size(can.sup, can.sup.ConfHeight(), can.sup.ConfWidth()) can.run(event, [ctx.ACTION, mdb.REMOVE, can.Status("file")], function(msg) { can.user.toast(can, "删除成功") }, true)
}, },
sort: function(event, can, button, value) { "上一个": function(event, can) { can.order > 0? can.show(--can.order): can.user.toast(can, "已经是第一张啦!") },
switch (value) { "下一个": function(event, can) { can.order < can.list.length-1? can.show(++can.order): can.user.toast(can, "已经是最后一张啦!") },
case mdb.TIME: can._msg.Sort(value, "str_r"); break "设置头像": function(event, can) { var msg = can.request(event, {url: can.onimport._file(can, can.list[can.order].path)})
case nfs.PATH: can._msg.Sort(value, "str"); break can.search(event, ["Header.onimport.avatar"], null, true)
case nfs.SIZE: can._msg.Sort(value, "int_r"); break
} can.onimport._project(can, can._msg)
}, },
playnext: function(can) { "设置背景": function(event, can) { var msg = can.request(event, {url: can.onimport._file(can, can.list[can.order].path)})
if (can.Action("order") == "repeat") { can.search(event, ["Header.onimport.background"], null, true)
if (can.ui.video) { can.ui.video.currentTime = 0, can.ui.video.play() }
}
if (can.Action("order") == "range") { var next = can.ui.current._target.nextSibling
next && can.onmotion.delay(can, function() { next.click() }, 300)
}
if (can.Action("order") == "loop") { var next = can.ui.current._target.nextSibling
next? can.onmotion.delay(can, function() { next.click() }, 300): can.db.list[0]._target.click()
}
if (can.Action("order") == "random") {
can.db.list[parseInt(Math.random()*can.db.list.length)]._target.click()
}
}, },
prev: function(event, can) { var target = can.ui.current._target; target.previousSibling? target.previousSibling.click(): can.user.toast(can, "已经是第一页了") }, "复制链接": function(event, can) {
next: function(event, can) { var target = can.ui.current._target; target.nextSibling? target.nextSibling.click(): can.user.toast(can, "已经是最后一页了") }, can.user.copy(event, can, can.misc.MergeURL(can, {_path: can.onimport._file(can, can.list[can.order].path)}, true))
prevpage: function(event, can) { if (can.db.begin > 0) { can.db.begin -= can.db.limit, can.onimport.page(can, can.db.list) } else { can.user.toast(can, "已经是第一页了") } },
nextpage: function(event, can) { if (can.db.begin + can.db.limit < can.db.list.length) { can.db.begin += can.db.limit, can.onimport.page(can, can.db.list) } else { can.user.toast(can, "已经是最后一页了") } },
})
Volcanos(chat.ONEXPORT, {list: [cli.BEGIN, mdb.LIMIT, mdb.TOTAL, mdb.NAME, nfs.SIZE, mdb.TIME, "position"],
progress: function(can, path, time) { return can.onexport.storage(can, path.split("?")[0], time) },
position: function(can, index, total) { total = total || can.max; return parseInt((index+1)*100/total)+"%"+" = "+(parseInt(index)+1)+nfs.PS+parseInt(total) },
})
Volcanos(chat.ONKEYMAP, {
_mode: {
plugin: {
Escape: function(event, can) { can.onaction.fullscreen(event, can) },
ArrowLeft: function(event, can) { if (can.ui.video) { can.ui.video.currentTime -= 15 } else { can.onaction.prev(event, can) } },
ArrowRight: function(event, can) { if (can.ui.video) { can.ui.video.currentTime += 15 } else { can.onaction.next(event, can) } },
ArrowDown: function(event, can) { try { can.user.toast(can, "volume: "+parseInt((can.ui.video.volume -= 0.1)*100)) } catch (e) {} },
ArrowUp: function(event, can) { try { can.user.toast(can, "volume: "+parseInt((can.ui.video.volume += 0.1)*100)) } catch (e) {} },
" ": function(event, can) { if (can.ui.video) { can.ui.video.paused? can.ui.video.play(): can.ui.video.pause() } },
},
}, },
}) })
Volcanos("onexport", {help: "导出数据", list: ["begin", "limit", "total", "position", "file"],
position: function(can, index, total) { total = total || can.max
return parseInt((index+1)*100/total)+"%"+" = "+(parseInt(index)+1)+ice.PS+parseInt(total)
},
})

View File

@ -1,41 +1,156 @@
fieldset.word>div.output { padding:var(--plugin-padding); } fieldset.word>div.output fieldset.span>fieldset {
fieldset.word>div.output p { margin:var(--title-margin) auto; } float:left; overflow:auto;
fieldset.word>div.output h3 { margin-top:var(--title-margin); } }
fieldset.word>div.output h2.story[data-type=spark][data-name=title] { text-align:center; }
fieldset.word>div.output code { font-style: italic; }
fieldset.word>div.output ul { margin:20px; font-family:var(--code-font-family); word-break:break-all; }
fieldset.word>div.output ul>li:hover { background-color:var(--hover-bg-color); color:var(--hover-fg-color); cursor:pointer; }
fieldset.word>div.output img { display:block; margin:auto; max-height:100%; max-width:100%; }
fieldset.word>div.output div.project img { margin:unset; }
fieldset.word>div.output table.content img { margin:unset; max-width:unset; }
fieldset.word>div.output table { width:100%; }
fieldset.word>div.output video { max-height:100%; width:100%; }
fieldset.word>div.output iframe { height:var(--iframe-height); width:100%; }
fieldset.word>div.output svg.story[data-index] text { cursor:pointer; }
fieldset.word>div.output input.story[type=button] { font-family:system-ui; font-weight:bold; padding:10px 40px; margin:var(--button-margin); height:var(--header-height); box-shadow:var(--input-box-shadow); }
body.mobile fieldset.word>div.output input.story[type=button] { padding:10px 20px; }
fieldset.word>div.output fieldset.web.code.inner.output div.output td.line { border-right:var(--box-border); }
fieldset.word>div.navmenu { background-color:inherit; overflow:auto; min-width:120px; clear:both; float:left; }
fieldset.word>div.navmenu div.list { margin-left:var(--title-margin); }
fieldset.word>div.navmenu div.item { font-size:1.4em; font-weight:bold; font-family:cursive; padding:var(--input-padding) var(--title-margin); }
fieldset.word>div.navmenu>div.item { font-size:1.6em; }
div.story[data-type=spark] label { padding:3px; -webkit-user-select:none; } fieldset.word>div.navmenu {
div.story[data-type=spark_tabs] { margin-top:var(--title-margin); } clear:both;
div.story[data-type=spark_tabs]>div.tabs>div.item { font-style:italic; padding:var(--input-padding) var(--button-padding); height:var(--action-height); float:left; } float:left;
div.story[data-type=spark_tabs]>div.tabs>div.item.select { border-top:var(--box-notice3); } min-width:120px;
body.dark div.story[data-type=spark_tabs]>div.tabs>div.item.select { background-color:var(--code-bg-color); } background-color:inherit;
div.story[data-type=spark_tabs]>div.story:not(.select) { display:none; } margin-right:10px;
overflow:auto;
}
fieldset.word>div.navmenu>div.item {
font-weight:bold;
font-size:2em;
padding:4px 10px;
}
fieldset.word>div.navmenu>div.list>div.item {
font-weight:bold;
font-size:1.6em;
}
fieldset.word>div.navmenu div.item {
font-family:cursive;
padding:4px 10px;
}
fieldset.word>div.navmenu div.item.select {
background-color:red;
}
fieldset.word>div.navmenu div.item:hover {
cursor:pointer;
background-color:red;
}
fieldset.word>div.navmenu div.list {
margin-left:20px;
}
fieldset.word a {
word-break:break-word;
}
fieldset.word ul.story[data-type=premenu] {
cursor:pointer;
}
fieldset.word ul.story[data-type=premenu] li:hover {
background:cyan;
color:blue;
}
fieldset.word ul.story[data-type=endmenu] {
clear:both;
}
fieldset.word ul.story li.H2 {
font-weight:bold;
font-size:2em;
}
fieldset.word br.story {
clear:both;
}
fieldset.word p.story {
white-space:pre;
}
fieldset.word p.story[data-name=inner] {
padding:4px 10px; margin:10px 0px;
background-color:#4b6c8a7a;
border-left:solid 4px blue;
}
fieldset.word p.story[data-name=inner]:hover {
background-color:#c10c8a;
cursor:copy;
}
fieldset.word svg.story {
display:block; float:left;
}
fieldset.word code.story {
display:block; border:solid 3px green;
color:white; background-color:#272822;
max-height:640px; overflow:auto;
padding:10px; white-space:pre;
clear:both;
}
fieldset.word video.story {
max-height:320px;
}
fieldset.word fieldset.story {
margin:10px; border:0;
clear:both; float:left;
box-shadow:4px 4px 10px 1px #626bd0;
}
fieldset.word fieldset.story:hover {
box-shadow:12px 12px 12px 6px #5764efd1;
}
fieldset.word.float {
width:-webkit-fill-available;
position:fixed; left:0; top:0;
background-color:aliceblue;
color:black;
}
fieldset.word.float>div.output {
background-color:#f0f8ff80;
overflow:auto;
padding:20px;
}
fieldset.word.float>div.output>div.project {
background:cornsilk;
left:0; top:25px;
position:fixed;
padding:10px;
z-index:100;
}
fieldset.word.float div.content div.page {
background-color:#194c79d4;
margin-top:30px;
display:none;
}
fieldset.word.float div.content div.page.show {
display:block;
}
fieldset.word.float div.content.grid div.page {
float:left; display:block;
width:200px; height:200px;
overflow:auto; margin:10px;
background-color:#a4cbecb5;
}
fieldset.word.float h1 {
text-align:center;
}
fieldset.word.float h2 {
text-align:center;
}
fieldset.word.float h3 {
text-align:center;
}
fieldset.word.float div.status {
clear:none;
}
fieldset.word.float div.status label {
color:black;
}
fieldset.word.float div.status span {
color:black;
}
fieldset.panel.cmd fieldset.word>legend {
display:none;
}
fieldset.panel.cmd fieldset.word>form.option {
display:none;
}
fieldset.panel.cmd fieldset.word>div.action {
display:none;
}
fieldset.panel.cmd fieldset.word>div.status {
display:none;
}
fieldset.word.play.float { top:0; }
fieldset.word.play.float>div.action { display:contents; }
fieldset.word.play.float>div.status { clear:none; display:contents; }
fieldset.word.play.float>div.output>div.project { background-color:var(--plugin-bg-color); padding:var(--plugin-padding); position:fixed; right:0; top:var(--action-height); z-index:11; }
fieldset.word.play.float div.content div.page { display:none; }
fieldset.word.play.float div.content div.page.show { display:block; }
fieldset.word.play.float div.content div.page ul { text-align:left; }
fieldset.word.play.float div.content.grid div.page { background-color:var(--plugin-bg-color); margin:var(--plugin-padding); height:var(--qrcode-height); width:30%; overflow:auto; display:block; float:left; }
fieldset.word.play.float h1 { text-align:center; }
fieldset.word.play.float h2 { text-align:center; }
fieldset.word.play.float h3 { text-align:center; }
fieldset.word.play.float svg { display:block; margin:0 auto; }

View File

@ -1,172 +1,182 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", _init: function(can, msg, cb, target) {
_init: function(can, msg, target) { can.Conf(html.PADDING, html.PLUGIN_PADDING) can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
can.page.Modify(can, target, msg.Results()), can.onimport._content(can, target) if (msg.Length() > 0) { return can.onappend.table(can, msg) }
can.onmotion.delay(can, function() { can.onappend.scroll(can) })
can.onexport.title(can, can.Option(nfs.PATH)) can.page.Modify(can, target, msg.Result())
}, can.page.Select(can, target, wiki.ITEM, function(item) { var data = item.dataset||{}
_content: function(can, target, cb) { can.onappend.style(can, web.WIKI_WORD) can.core.CallFunc([can.onimport, data.type], [can, data, item])
can.page.Select(can, target, wiki.STORY_ITEM, function(target) { var meta = target.dataset||{}; cb && cb(target, meta) can.page.Modify(can, item, {style: can.base.Obj(data.style)})
can.core.CallFunc([can.onimport, can.onimport[meta.name]? meta.name: meta.type||target.tagName.toLowerCase()], [can, meta, target])
var _meta = can.base.Obj(meta.meta);
if (_meta && _meta.style) {
if (can.user.isMobile && _meta.style.width == "480px") { _meta.style.width = can.ConfWidth() - 2*can.Conf(html.PADDING) }
can.page.style(can, target, can.base.Obj(_meta.style))
}
meta.style && can.page.style(can, target, can.base.Obj(meta.style))
})
can.page.Select(can, target, html.A, function(target) {
target.innerText = target.innerText || target.href, target.href = target.href || target.innerText, target.target = target || "_blank"
}) })
}, },
list: function(can, root, cb, cbs, target) { target = target||can._output navmenu: function(can, data, target) { var nav = can.sup._navmenu
can.core.List(root.list, function(item) { var ui = can.page.Append(can, target, [{view: [[html.ITEM, "open"]], list: [{text: item.meta.name}, item.list && {icon: icon.CHEVRON_DOWN}], onclick: function(event) { nav = nav||can.page.Append(can, can._fields, [{view: wiki.NAVMENU}]).first
can.page.ClassList.set(can, ui.item, "open", can.base.isFunc(cb) && cb(event, item) || can.onmotion.toggle(can, ui.list)) can.onmotion.clear(can, nav), can._fields.insertBefore(nav, can._output)
can.onmotion.select(can, target, html.DIV_ITEM, event.currentTarget)
}, _init: function(target) { if (item.meta.name == "_") { target.innerHTML = "", can.onappend.style(can, html.SPACE, target) } can.onappend.list(can, can.base.Obj(data.data), function(event, item) {
cbs && cbs(target, item) var link = item.meta.link, list = can.core.Split(item.meta.link)
}}, {view: html.LIST}]); can.onimport.list(can, item, cb, cbs, ui.list) }) if (can.core.Value(can, list[0])) { return can.core.CallFunc([can, list[0]], list.slice(1)) }
}, if (!link || link == can.Option(nfs.PATH)) { return false }
navmenu: function(can, meta, target) { var nav = can.sup._navmenu
nav = can.onmotion.clear(can, nav||can.page.insertBefore(can, [wiki.NAVMENU], can._output)), can.sup._navmenu = nav if (can.onmotion.cache(can, function() { can.user.mod.isCmd && can.user.title(item.meta.name); return can.Option(nfs.PATH, link) })) { return }
can.onimport.list(can, can.base.Obj(meta.data), function(event, item) {
var link = item.meta.link; if (!link || link == can.Option(nfs.PATH)) { return false }
if (can.base.beginWith(link, nfs.PS, web.HTTP)) { return can.user.opens(link) }
if (can.onmotion.cache(can, function() { return can.onexport.title(can, item.meta.name), can.Option(nfs.PATH, link) })) { return }
return can.sup.Update(event, [link]) return can.sup.Update(event, [link])
}, function() {}, nav) }, nav), can.sup._navmenu = nav
can.onimport.layout(can)
can.getActionSize(function(msg) {
can.page.style(can, nav, html.HEIGHT, can.Conf(html.HEIGHT)+(can.user.mod.isCmd? msg.Option(html.MARGIN_Y): 0))
can.Conf(html.WIDTH, can.Conf(html.WIDTH)-nav.offsetWidth-(can.user.mod.isCmd? 10: 20))
can.page.Modify(can, can._output, {style: kit.Dict(
html.HEIGHT, can.sup._navmenu.offsetHeight, html.MAX_WIDTH, can.Conf(html.WIDTH),
html.FLOAT, html.LEFT, html.CLEAR, html.NONE
)})
})
}, },
premenu: function(can, meta, target) { can.page.Select(can, can._output, can.page.Keys(html.H2, html.H3), function(_target) { premenu: function(can, data, target) {
can.onimport.item(can, {name: _target.innerHTML}, function() { can.onmotion.scrollIntoView(can, _target) }, function() {}, target) can.page.Select(can, can._output, can.page.Keys(wiki.H2, wiki.H3), function(item) {
_target.onclick = function(event) { can.onmotion.scrollIntoView(can, target) } can.page.Append(can, target, [{text: [item.innerHTML, html.LI, item.tagName], onclick: function() {
}) }, item.scrollIntoView()
endmenu: function(can, meta, target) { can.page.Select(can, can._output, can.page.Keys(html.H2, html.H3), function(_target) { }}]), item.onclick = function(event) { target.scrollIntoView() }
can.onimport.item(can, {name: _target.innerHTML}, function() { can.onmotion.scrollIntoView(can, _target) }, function() {}, target) })
}) },
spark: function(can, meta, target) {
if (meta[mdb.NAME] == html.INNER) { return can.onmotion.copy(can, target) }
can.page.Select(can, target, "kbd,samp", function(item) { can.onmotion.copy(can, item, function() {
meta.type == "shell" && can.onappend.float(can, {index: web.CODE_XTERM, args: ["sh"]})
}) })
}, },
spark_tabs: function(can, meta, target) { var select title: function(can, data, target) {
can.page.Select(can, target, "div.tabs>div.item", function(tabs, index) { can.user.mod.isCmd && target.tagName == "H1" && can.user.title(data.text)
(index == 0 || can.user.isMacOSX && can.base.isIn(tabs.innerText, cli.DARWIN, "macos") || can.user.isWindows && tabs.innerText == cli.WINDOWS) && (select = tabs)
tabs.onclick = function() { can.onmotion.select(can, tabs.parentNode, "div.tabs>div.item", tabs), can.onmotion.select(can, target, "div.story", index) }
return tabs
}); select && select.click()
}, },
table: function(can, meta, target) { spark: function(can, data, target) {
if (data[mdb.NAME] == html.INNER) { return can.onmotion.copy(can, target) }
can.page.Select(can, target, html.A, function(item) { can.onmotion.link(can, item) })
can.page.Select(can, target, html.SPAN, function(item) { can.onmotion.copy(can, item) })
},
chart: function(can, data, target) {
target.oncontextmenu = function(event) {
can.user.carteClient(event, can, kit.Dict(mdb.EXPORT, function(event, can, button) {
can.user.toPNG(can, can.user.prompt("please input file name", "hi")+".png", target.outerHTML,
parseInt(target.getAttribute(html.HEIGHT))||200, parseInt(target.getAttribute(html.WIDTH))||200)
}), [mdb.EXPORT])
}
},
table: function(can, data, target) {
can.page.OrderTable(can, target), can.page.ClassList.add(can, target, chat.CONTENT) can.page.OrderTable(can, target), can.page.ClassList.add(can, target, chat.CONTENT)
can.page.Select(can, target, html.TD, function(item) { can.onmotion.copy(can, item) }) can.page.Select(can, target, html.TD, function(item) { can.onmotion.copy(can, item) })
}, },
order: function(can, meta, target) { field: function(can, data, target, width) { var item = can.base.Obj(data.meta)
target.onclick = function(event) { can.onappend._init(can, item, [chat.PLUGIN_STATE_JS], function(sub) {
can.user.copy(event, can, event.target.innerText) sub.run = function(event, cmds, cb, silent) {
} can.run(event, can.misc.concat(can, [ctx.ACTION, chat.STORY, data.type, data.name, data.text], cmds), cb, true)
}, }
chart: function(can, meta, target) { sub.Conf(html.HEIGHT, can.Conf(html.HEIGHT))
if (!meta.fg && !meta.bg) { target.className.baseVal = "story auto" } sub.Conf(html.WIDTH, item.width = (width||can.Conf(html.WIDTH))-20)
target.onclick = function(event) { can.misc.Event(event, can, function(msg) {
meta.index && can.onappend._float(can, meta.index, can.base.Obj(meta.args, []).concat([event.target.innerHTML])) can.core.Value(item, "auto.cmd") && can.core.Timer300ms(function() {
}) } var msg = sub.request({}, can.core.Value(item, "opts")); msg.Option(ice.MSG_HANDLE, ice.TRUE)
target.oncontextmenu = function(event) { can.misc.Event(event, can, function(msg) { sub.Update(msg._event, [ctx.ACTION, can.core.Value(item, "auto.cmd")])
var ui = can.user.carte(event, can, kit.Dict(mdb.EXPORT, function(event, can, button) { })
can.user.toimage(can, "hi", target)
})); can.page.style(can, ui._target, {left: event.clientX, top: event.clientY})
}) }
},
field: function(can, meta, target) { var item = can.base.Obj(meta.meta), padding = can.Conf(html.PADDING)
var height = can.base.Max(html.STORY_HEIGHT, can.ConfHeight()-4*html.ACTION_HEIGHT-2*padding), width = item.width||can.ConfWidth()-2*padding
can.core.Item(item, function(key, value) { if (can.base.beginWith(key, "meta.")) { can.core.Value(item, key, value), delete(item[key]) } })
can.onappend.plugin(can, item, function(sub) { can._plugins = (can._plugins||[]).concat([sub])
can.user.isMobile || sub.Conf("__width", item.width)
can.core.Value(item, "auto.cmd") && can.onmotion.delay(function() { sub.runAction(sub.request({}, can.core.Value(item, "opts")), can.core.Value(item, "auto.cmd")) })
var size = sub.onimport.size; sub.onimport.size = function(can, height, width, auto, mode) { size(can, height, width, auto, mode)
can.page.style(can, sub._output, html.MAX_HEIGHT, "", "overflow-y", "hidden")
sub.sub && sub.sub.ui.content && can.page.style(can, sub.sub.ui.content, html.HEIGHT, "", "overflow-y", "hidden")
}, sub.onimport.size(sub, height, width, true)
can.onimport.layout(can)
}, can._output, target) }, can._output, target)
}, },
layout: function(can) { padding = can.Conf(html.PADDING) iframe: function(can, data, target) { var meta = can.base.Obj(data.meta)
if (can.sup._navmenu) { can.ConfWidth(can.ConfWidth()-can.sup._navmenu.offsetWidth) can.page.Modify(can, target, {width: can.Conf(html.WIDTH)-200})
can.page.style(can, can.sup._navmenu, html.HEIGHT, can.ConfHeight())
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth(), "clear", "none", "float", "left")
}
can.core.List(can._plugins, function(sub) { sub.onimport.size(sub, can.base.Min(can.ConfHeight()/2, 300, 600), (can.ConfWidth()-2*padding), true) })
can.page.Select(can, can._output, html.IMG, function(target) { can.page.style(can, target, html.MAX_HEIGHT, can.base.Max(can.ConfHeight(), 420)) })
}, },
}, [""]) }, [""])
Volcanos(chat.ONACTION, { Volcanos("onkeymap", {help: "键盘交互", list: [],
_mode: {
normal: {
"n": function(event, can) { can.ondetail.next(can.sub) },
"j": function(event, can) { can.ondetail.next(can.sub) },
"ArrowRight": function(event, can) { can.ondetail.next(can.sub) },
"ArrowLeft": function(event, can) { can.ondetail.prev(can.sub) },
"k": function(event, can) { can.ondetail.prev(can.sub) },
"p": function(event, can) { can.ondetail.prev(can.sub) },
"q": function(event, can) { can.ondetail["结束"](event, can.sub) },
"h": function(event, can) { can.ondetail["隐藏"](event, can.sub) },
},
}, _engine: {},
})
Volcanos("onaction", {help: "控件交互", list: [],
play: function(event, can) { var list = [], current = [] play: function(event, can) { var list = [], current = []
can.page.Select(can, can._output, wiki.STORY_ITEM, function(item) { can.page.tagis(item, "h1", "h2", "h3") && list.push(current = []), current.push(item) }) can.page.Select(can, can._output, wiki.ITEM, function(item) {
can.onappend._init(can, {type: "story word play float", height: can.page.height(), width: can.page.width(), padding: 10}, [], function(sub) { sub._legend.onclick = can._legend.onclick switch (item.tagName) {
sub._trans = {input: {page: "页码", from: "开始"}} case "H1":
sub.run = can.run, sub.sup = can, can.sub = sub, can.onappend._action(sub, can.user.isMobile && can.page.height() > can.page.width()? [ case "H2":
"大纲", "上一页", "下一页", "结束", case "H3":
]: [ list.push(current = [])
["布局", "开讲", "网格", "快闪"], "大纲", "首页", "上一页", break
}
current.push(item)
})
can.onappend._init(can, {type: "story word float"}, [], function(sub) {
sub.run = can.run, sub.sup = can, can.sub = sub, can.onappend._action(sub, [
["布局", "开讲", "快闪", "网格"], "大纲", "首页", "上一页",
["菜单"].concat(can.core.List(list, function(page) { return page[0].innerHTML })), ["菜单"].concat(can.core.List(list, function(page) { return page[0].innerHTML })),
"下一页", "隐藏", "结束", "下一页", "隐藏", "结束",
], sub._action, can.ondetail, false, 10), can.onkeymap._build(can) ], sub._action, can.ondetail)
sub.page.style(sub, sub._target, "background", can._root._target.style.background)
sub.page.style(sub, sub._output, html.HEIGHT, can.page.height()-2*html.ACTION_HEIGHT) can.onengine.signal(can, "keymap.focus", can.request(event, {cb: function(event) {
sub.page.style(sub, sub._output, html.WIDTH, can.page.width()) can.keylist = can.onkeymap._parse(event, can, "normal", can.keylist)
sub.ui = sub.page.Append(sub, sub._output, [chat.PROJECT, chat.CONTENT]) }})), can.onkeymap._build(can)
sub.page.style(sub, sub._target, html.BACKGROUND, document.body.style.background)
sub.page.style(sub, sub._output, html.HEIGHT, window.innerHeight-4*html.PLUGIN_MARGIN-2*html.ACTION_HEIGHT)
sub.page.style(sub, sub._output, html.WIDTH, window.innerWidth-4*html.PLUGIN_MARGIN)
sub.ui = sub.page.Append(sub, sub._output, [{view: chat.PROJECT}, {view: chat.CONTENT}])
can.core.List(sub.list = list, function(page, index) { can.core.List(sub.list = list, function(page, index) {
can.onimport.item(can, {name: page[0].innerHTML}, function(event) { can.ondetail.show(sub, index) }, function(event) {}, sub.ui.project) can.onappend.item(can, html.ITEM, {name: page[0].innerHTML}, function(event) {
can.ondetail.show(sub, index)
}, function(event) {}, sub.ui.project)
sub.page.Append(sub, sub.ui.content, [{view: "page"+(index==0? " first": ""), list: can.core.List(page, function(item) { var data = item.dataset||{} sub.page.Append(sub, sub.ui.content, [{view: "page"+(index==0? " first": ""), list: can.core.List(page, function(item) { var data = item.dataset||{}
switch (data.type) { switch (data.type) {
case wiki.PREMENU: item = item.cloneNode(false); break case wiki.PREMENU: item = item.cloneNode(false); break
case chat.FIELD: item = can.onappend.field(can, chat.STORY, can.base.Copy(can.base.Obj(data.meta), {height: can.page.height(), width: can.page.width()}), sub.ui.content)._target; break case chat.FIELD: item = can.onappend.field(can, chat.STORY, can.base.Obj(data.meta), sub.ui.content).first; break
default: item = item.cloneNode(true) default: item = item.cloneNode(true)
} }
return can.core.CallFunc([can.onimport, data.type], [sub, data, item, can.page.width()]), item return can.core.CallFunc([can.onimport, data.type], [sub, data, item, window.innerWidth-4*html.PLUGIN_MARGIN]), item
}), }]) }), }])
}), can.onmotion.hidden(can, sub.ui.project), can.ondetail.show(sub, 0) }), can.onmotion.hidden(can, sub.ui.project), can.ondetail.show(sub, 0)
sub.onappend._status(sub, [mdb.PAGE, cli.FROM, cli.COST]), sub.Status(cli.FROM, can.base.Time()), sub.Status(mdb.PAGE, list.length)
var from = new Date(); can.core.Timer({interval: 100}, function() { var now = new Date(); sub.Status(cli.COST, can.base.Duration(now-from)) }) sub.onappend._status(sub, [mdb.PAGE, cli.FROM, cli.COST]), sub.Status(cli.FROM, can.base.Time())
}, can._root._target) var from = new Date(); can.core.Timer({interval: 100}, function() { var now = new Date()
sub.Status(cli.COST, can.base.Duration(now-from))
})
}, document.body)
}, },
}) })
Volcanos(chat.ONDETAIL, { Volcanos("ondetail", {help: "交互操作", list: ["删除"], _init: function(can, msg, list, cb, target) {
show: function(sub, which) { sub.page.styleClass(sub, sub.ui.content, chat.CONTENT) },
sub.page.Select(sub, sub.ui.content, html.DIV_PAGE, function(page, index) { show: function(sub, which) { sub.page.Modify(sub, sub.ui.content, {className: chat.CONTENT})
sub.page.Select(sub, sub.ui.content, wiki.DIV_PAGE, function(page, index) {
if (index == which || page == which) { if (index == which || page == which) {
sub.page.Select(sub, page, sub.page.Keys(html.H1, html.H2, html.H3), function(item) { sub.Action("菜单", item.innerHTML) }) sub.page.Select(sub, page, sub.page.Keys(html.H1, html.H2, html.H3), function(item) { sub.Action("菜单", item.innerHTML) })
sub.onmotion.select(sub, sub.ui.project, html.DIV_ITEM, index) sub.onmotion.select(sub, sub.ui.project, html.DIV_ITEM, index)
sub.Status(mdb.PAGE, index+1+nfs.PS+sub.list.length) sub.Status(mdb.PAGE, index+1+ice.PS+sub.list.length)
sub.page.ClassList.add(sub, page, html.SHOW) sub.page.ClassList.add(sub, page, html.SHOW)
} else { } else {
sub.page.ClassList.del(sub, page, html.SHOW) sub.page.ClassList.del(sub, page, html.SHOW)
} }
}) })
}, },
next: function(sub) { sub.page.Select(sub, sub.ui.content, sub.core.Keys(html.DIV_PAGE, html.SHOW), function(page) { next: function(sub) {
page.nextSibling? sub.sup.ondetail.show(sub, page.nextSibling): sub.user.toast(sub.sup, cli.END) sub.page.Select(sub, sub.ui.content, sub.core.Keys(wiki.DIV_PAGE, ice.SHOW), function(page) {
}) }, page.nextSibling? sub.sup.ondetail.show(sub, page.nextSibling): sub.user.toast(sub, cli.END)
prev: function(sub) { sub.page.Select(sub, sub.ui.content, sub.core.Keys(html.DIV_PAGE, html.SHOW), function(page) { })
page.previousSibling? sub.sup.ondetail.show(sub, page.previousSibling): sub.user.toast(sub.sup, cli.END)
}) },
flash: function(sub) { sub.core.Next(sub.page.Select(sub, sub.ui.content, html.DIV_PAGE), function(page, next) {
sub.sup.ondetail.show(sub, page), sub.onmotion.delay(sub, next, 500)
}) },
grid: function(sub) {
sub.page.styleClass(sub, sub.ui.content, "content grid")
}, },
"开讲": function(event, can) { prev: function(sub) {
can.page.SelectChild(can, can.ui.content, "", function(target) { can.page.style(can, target, html.HEIGHT, "", html.WIDTH, "") }) sub.page.Select(sub, sub.ui.content, sub.core.Keys(wiki.DIV_PAGE, ice.SHOW), function(page) {
can.sup.ondetail.show(can, 0) page.previousSibling? sub.sup.ondetail.show(sub, page.previousSibling): sub.user.toast(sub, cli.END)
})
}, },
"网格": function(event, can) { function size(p) { return (p-2*html.PLUGIN_PADDING)/3-2*html.PLUGIN_PADDING } flash: function(sub) {
can.onlayout.expand(can, can.ui.content, can.base.Min(size(can.ConfWidth()), 320, 640), can.base.Min(size(can.ConfHeight()-2*html.ACTION_HEIGHT), 240, 320), html.DIV_PAGE) sub.core.Next(sub.page.Select(sub, sub.ui.content, wiki.DIV_PAGE), function(page, next) {
can.sup.ondetail.grid(can) sub.sup.ondetail.show(sub, page), sub.core.Timer(500, function() { next() })
}, })
"快闪": function(event, can) {
can.page.SelectChild(can, can.ui.content, "", function(target) { can.page.style(can, target, html.HEIGHT, "", html.WIDTH, "") })
can.sup.ondetail.flash(can)
}, },
grid: function(sub) { sub.page.Modify(sub, sub.ui.content, {className: "content grid"}) },
"开讲": function(event, can) { can.sup.ondetail.show(can, 0) },
"快闪": function(event, can) { can.sup.ondetail.flash(can) },
"网格": function(event, can) { can.sup.ondetail.grid(can) },
"大纲": function(event, can) { can.onmotion.toggle(can, can.ui.project) }, "大纲": function(event, can) { can.onmotion.toggle(can, can.ui.project) },
"首页": function(event, can) { can.sup.ondetail.show(can, 0) }, "首页": function(event, can) { can.sup.ondetail.show(can, 0) },
"上一页": function(event, can) { can.sup.ondetail.prev(can, can.ui.content) }, "上一页": function(event, can) { can.sup.ondetail.prev(can, can.ui.content) },
@ -176,17 +186,4 @@ Volcanos(chat.ONDETAIL, {
"结束": function(event, can) { can.page.Remove(can, can._target) }, "结束": function(event, can) { can.page.Remove(can, can._target) },
"删除": function(event, sub) { sub.page.Remove(sub, sub._target) }, "删除": function(event, sub) { sub.page.Remove(sub, sub._target) },
}) })
Volcanos(chat.ONKEYMAP, {
_mode: {
plugin: {
"j": function(event, can) { can.ondetail.next(can.sub) },
"k": function(event, can) { can.ondetail.prev(can.sub) },
"n": function(event, can) { can.ondetail.next(can.sub) },
"p": function(event, can) { can.ondetail.prev(can.sub) },
"ArrowRight": function(event, can) { can.ondetail.next(can.sub) },
"ArrowLeft": function(event, can) { can.ondetail.prev(can.sub) },
"q": function(event, can) { can.ondetail["结束"](event, can.sub) },
"h": function(event, can) { can.ondetail["隐藏"](event, can.sub) },
},
}, _engine: {},
})

View File

@ -1,384 +1,228 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, conf, list, cb, target) {},
_process: function(can, msg) { _process: function(can, msg) {
if (msg.IsErr()) { can.onappend.style(can, "warn", can.user.toastFailure(can, msg.Result())._target) } msg.OptionStatus() && can.onmotion.clear(can, can._status) && can.onappend._status(can, can.base.Obj(msg.OptionStatus()))
if (can.onimport[msg.OptionProcess()]) { return can.core.CallFunc([can.onimport, msg.OptionProcess()], {can: can, sub: can.sub, msg: msg, arg: msg.Option("_arg")}), true } return can.core.CallFunc([can.onimport, msg.OptionProcess()], [can, msg])
}, },
_location: function(can, msg, arg) { can.user.jumps(arg) },
_replace: function(can, msg, arg) { location.replace(arg) }, _location: function(can, msg) { location.href = msg._arg[0] },
_history: function(can, msg) { history.length == 1? can.user.close(): history.back() }, _rewrite: function(can, msg) {
_confirm: function(can, msg, arg) { can.user.toastConfirm(can, arg, "", function() { can.runAction(can.request({}, msg), "confirm") }) }, for (var i = 0; i < msg._arg.length; i += 2) {
_refresh: function(can, msg, arg) { can.core.Timer(parseInt(arg||"30"), function() { can.Update(can.request({}, {_count: parseInt(msg.Option("_count")||"3")-1})) }) }, can.Option(msg._arg[i], msg._arg[i+1])
_rewrite: function(can, msg) { var arg = msg._arg; for (var i = 0; i < arg.length; i += 2) { }
can.Option(arg[i], arg[i+1]), can.Action(arg[i], arg[i+1]) can.Update()
can.misc.sessionStorage(can, [can.ConfIndex(), ctx.ACTION, arg[i]], arg[i+1]) return true
} can.Update() }, },
_display: function(can, msg) { can.onappend._output(can, msg, msg.Option(ice.MSG_DISPLAY)) }, _refresh: function(can, msg) {
_clear: function(can, msg) { can.onmotion.clear(can) }, can.core.Timer(parseInt(msg.Option("_delay")||"500"), function() {
_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) }, var sub = can.request({}, {_count: parseInt(msg.Option("_count"))-1})
_cookie: function(can, msg) { can.misc.Cookie(can, msg._arg[0], msg._arg[1])
if (msg._arg[2]) {
history.go(msg._arg[2])
can.onmotion.delay(can, function() { history.back() }, 300)
} else {
can.Update() can.Update()
}
},
_session: function(can, msg) { can.misc.sessionStorage(can, msg._arg[0], msg._arg[1]), can.Update() },
_field: function(can, msg, cb) {
can.user.isMobile && can.onmotion.clear(can, can._output)
can.page.style(can, can._target, "visibility", ""), can.page.style(can, can._output, "visibility", "")
var height = can.ConfHeight()-can.onexport.actionHeight(can)-(can.onexport.statusHeight(can)||1), width = can.ConfWidth()
var tabs = false, tabHash = msg.Option("field.tabs"); if (tabHash) {
can.sub && can.sub.onimport.tabs(can.sub, [{name: tabHash.slice(0, 6)}], function() { can.onmotion.cache(can, function() { return tabHash }) }), tabs = true
} else {
if (msg.Length() > 1) {
height = height / msg.Length()
} else if (can._output.innerHTML && !can.page.tagis(can._target, html.FIELDSET_OUTPUT)) {
height = can.base.Max(html.STORY_HEIGHT, height)
}
}
var option = can.base.Obj(msg.Option("field.option"))
msg.Table(function(item) { tabs && can.onmotion.cache(can, function() { return tabHash })
var sup = item.space? can._root.Action: can; height = can.base.Max(item._height||height, can.ConfHeight()), width = can.base.Max(item._width||width, can.ConfWidth())
can.onappend._plugin(sup, item, {index: item.index, args: can.base.Obj(item.args||item.arg, []), height: height, width: width, icons: item._icon}, function(sub) { can._plugins = (can._plugins||[]).concat([sub])
sub.run = function(event, cmds, cb) { var index = msg.Option(ice.MSG_INDEX)||item.index; sup.run(can.request(event, {pod: item.space}, option), (msg[ice.FIELD_PREFIX]? msg[ice.FIELD_PREFIX]: index? [ctx.RUN, index]: []).concat(cmds), cb, true) }
can.page.ClassList.has(can, sub._target, html.FLOAT)? can.onmotion.float(sub): sub.onimport.size(sub, height, width, !can.user.isMobile), 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() { if (tabs) { msg.Option(ice.MSG_ACTION) && can.onappend._action(can, msg.Option(ice.MSG_ACTION))
sub.sub.onimport.tabs(sub.sub, [{name: tabHash.slice(0, 6)}], function() { tabs || can.onmotion.cache(can, function() { return tabHash }) }), tabs = false
} }
}, item.style == html.FLOAT && can.page.tagis(can._target, "fieldset.story")? document.body: can._output)
}) })
return true
}, },
_float: function(can, msg) { can.onimport._field(can, msg, function(sub) { can.onmotion.float(sub) }) }, _display: function(can, msg) {
_hold: function(can, msg, arg) { can.user.toast(can, arg||ice.SUCCESS) }, Volcanos("some", {}, [msg.Option(ice.MSG_DISPLAY)].concat(Volcanos.meta.libs, Volcanos.meta.volcano), function(sub) {
_back: function(can, msg, arg) { arg? (history.go(arg), can.onmotion.delay(can, function() { can.onimport.back({}, can) })): can.onimport.back({}, can) }, sub.Conf(can.Conf()), sub.run = can.run
_rich: function(can, msg) { var sub = can.sub sub._option = can._option, sub._action = can._action
function _rich() { sub.onimport._init(sub, msg, [], function() {}, can._output)
if (sub._rich_list.length == 0) { return } if (sub._rich_running) { return } sub._rich_running = true })
var msg = sub._rich_list.shift(), list = msg.detail.slice(1) return true
if (!sub._rich._table) { },
for (var i = 1; i < msg.detail.length; i += 2) { msg.Push(msg.detail[i], msg.detail[i+1]) } _field: function(can, msg) {
sub._rich._table = can.page.SelectOne(can, can.onappend.table(sub._rich, msg), html.TBODY) msg.Table(function(item) { can.onappend._plugin(can, item, {arg: can.base.Obj(item[ice.ARG], [])}, function(sub, meta) {
} else { var list = [] var opt = can.base.Obj(item[ice.OPT], [])
for (var i = 1; i < msg.detail.length; i += 2) { list.push(can.page.Color(msg.detail[i+1])) } sub.Conf(html.HEIGHT, can.Conf(html.HEIGHT))
var tr = can.page.Append(can, sub._rich._table, [{td: list}]).tr; sub._rich._output.scrollTop += 100000 sub.Conf(html.WIDTH, can.Conf(html.WIDTH))
can.onmotion.delayOnce(can, function() { can.onmotion.select(can, tr.parentNode, html.TR, tr) }, 500) sub.run = function(event, cmds, cb, silent) {
sub._rich.onappend._status(sub._rich, msg.Option(ice.MSG_STATUS), null, msg) var res = can.request(event, can.Option())
} can.core.Timer(msg.Option(cli.DELAY)||0, function() { sub._rich_running = false, _rich() }) for (var i = 0; i < opt.length; i += 2) { res.Option(opt[i], opt[i+1]) }
} can.run(event, (msg[ice.MSG_PREFIX]||[]).concat(cmds), cb, true)
if (sub._rich) {
(sub._rich_list = sub._rich_list||[]).push(msg); return _rich()
} else {
(sub._rich_list = sub._rich_list||[]).push(msg); if (sub._rich_list.length > 1) { return }
}
var height = can.onexport.outputHeight(can)
can.onappend.plugin(can, {title: can.core.Keys(msg.Option(ice.MSG_TITLE)||"table.js"), index: "can._filter", height: height, style: "rich"}, function(sub) {
sub.onexport.output = function() {
can.page.style(can, sub._output, html.HEIGHT, "", html.MAX_HEIGHT, "")
can.sub._rich = sub.sub, _rich(), can.onmotion.scrollIntoView(can, sub._target)
} }
}); return }) })
return true
}, },
_grow: function(can, msg, arg) { _inner: function(can, msg) {
var sub = can.sub can.onappend.table(can, msg)
if (sub && sub.onimport && sub.onimport._grow) { return sub.onimport._grow(sub, msg, msg.detail[1], msg.detail[2]) } can.onappend.board(can, msg)
if (sub && sub.onimport && sub.onimport.grow) { return sub.onimport.grow(sub, msg, msg.detail[1], msg.detail[2]) } can.onmotion.story.auto(can)
if (msg.Option(ctx.DISPLAY)) { can.page.Modify(can, can._output, {style: {display: html.BLOCK}})
function _grow() { if (can.sub._grow_list.length == 0) { return } if (can.sub._grow_running) { return } can.sub._grow_running = true return true
var msg = can.sub._grow_list.shift(), text = msg.detail[1]; sub._grow.onappend._status(sub._grow, msg.Option(ice.MSG_STATUS), null, msg) },
sub._grow._size = (sub._grow._size||0)+text.length, text && text.match(/\n/g) && (sub._grow._count = (sub._grow._count||0)+text.match(/\n/g).length)
if (msg.Option(cli.DELAY) && msg.Option(cli.DELAY) != "0") { var list = []; for (var i = 0; i < text.length; i++) { list.push(text[i]) } _open: function(can, msg) { can.user.open(msg.Option("_arg")); return true },
can.core.Next(list, function(text, next) { _hold: function(can, msg) { return true },
can.sub._grow.onimport.grow(can.sub._grow, msg, "current", text), can.core.Timer(msg.Option(cli.DELAY), next) _back: function(can) {
}, function() { can.sub._grow_running = false, _grow() }) can._history.pop(); for (var his = can._history.pop(); his; his = can._history.pop()) {
} else { if (his[0] == ctx.ACTION) { continue }
can.sub._grow.onimport.grow(can.sub._grow, msg, "current", text), can.sub._grow_running = false, _grow() can.page.SelectArgs(can, can._option, "", function(item, index) { item.value = his[index]||"" }), can.Update()
} sub._grow.Status(mdb.COUNT, sub._grow._count), sub._grow.Status("msg", can.base.Size(sub._grow._size)) break
}
if (can.sub._grow) {
(can.sub._grow_list = can.sub._grow_list||[]).push(msg); return _grow()
} else {
(can.sub._grow_list = can.sub._grow_list||[]).push(msg); if (can.sub._grow_list.length > 1) { return }
}
var height = can.onexport.outputHeight(can)
can.onappend.plugin(can, {
index: "can._filter", display: msg.Option(ctx.DISPLAY), height: height,
title: can.core.Keys(msg.Option(ice.MSG_TITLE)||msg.Option(ctx.DISPLAY).split(nfs.PS).pop()),
}, function(sub) {
sub.onexport.output = function() { can.onmotion.scrollIntoView(can, sub._target), can.sub._grow = sub.sub, _grow() }
}); return
} }
arg = can.page.Color(arg); if (!can.page.SelectOne(can, can._output, html.DIV_CODE, function(div) { !his && can.Update()
return can.page.style(can, div, html.MAX_HEIGHT, can.onexport.outputHeight(can)), return true
can.page.Append(can, div, [{text: arg}]), can._output.scrollTop = div.offsetTop, div.scrollBy(0, 10000), true
})) { can.onappend.board(can, arg) }
}, },
_open: function(can, msg, arg) { can.user.open(arg); msg._arg.length > 1 && can.Update() },
_close: function(can, msg) { can.user.close() || history.back() }, _grow: function(can, str) {
change: function(event, can, name, value, cb, data) { return can.page.SelectArgs(can, can._option, "", function(input) { if (input.name != name || value == input.value) { return } if (can.page.Select(can, can._output, "div.code", function(div) {
can.page.Select(can, input.parentNode, "span.value", function(target) { target.innerText = value }) can.page.Modify(can, div, {style: {"max-height": 400}})
return input.value = value, can.Update(event, can.Input([], true, data), cb), input can.page.Append(can, div, [{text: [str]}])
})[0] }, div.scrollBy(0, 10000)
_size: function(can, height, width, auto, mode) {}, return true
size: function(can, height, width, auto, mode) { typeof width == code.STRING && (width = can.base.ParseSize(width)) }).length == 0) {
can.Conf("_auto", auto), can.Mode(mode), can.ConfHeight(height), can.ConfWidth(width), height -= can.onexport.actionHeight(can)+(can.onexport.statusHeight(can)||(can.sub? 0: 1)) can.onappend.board(can, str)
var padding = can.Conf("padding")||0, margin = can.Conf("margin")||0; height -= 2*padding, width -= 2*padding+2*margin
auto || auto == undefined? (can.page.style(can, can._output, html.HEIGHT, "", html.WIDTH, "", html.MAX_HEIGHT, height, html.MAX_WIDTH, width), can.page.style(can, can._target, html.HEIGHT, "", html.WIDTH, "")):
(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) { can.page.tagis(sub._target, "fieldset.float") || 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
},
display_size: function(can, sub) { var border = 1
can.page.style(can, sub._output, html.MAX_HEIGHT, "")
var _height = can.base.Max(sub._target.offsetHeight+border, can.ConfHeight()/2)
sub.onimport.size(sub, _height-border, can.ConfWidth()-(can.ui && can.ui.project? can.ui.project.offsetWidth: 0), true)
},
back: function(event, can) { can._history.pop()
for (var i = 0, his = can._history.pop(); his; his = can._history.pop()) { if (his[0] == ctx.ACTION) { continue }
can.page.SelectArgs(can, can._option, "", function(target) { target.value = his[i++]||"", can.page.Select(can, target.parentNode, "span.value", function(target) { target.innerText = target.value||"" }) })
can.page.SelectArgs(can, can._action, "", function(target) { target.value = his[i++]||"" }); break
} }
can.onexport.hash(can, ""), can.Update(event)
}, },
}) })
Volcanos(chat.ONACTION, { Volcanos("onaction", {help: "交互操作", list: [
list: ["刷新数据", "共享工具", "打开链接", "生成链接", "生成脚本", "生成图片", "清空参数", "刷新数据", [
function(can) { if (!can.user.isMobile) { return "刷新界面" } }, "其它 ->", "复制数据", "下载数据", "清空数据", "删除工具", "摄像头", "生成图片",
function(can) { if (!can.user.isMobile && !can.isCmdMode()) { return "切换浮动" } },
function(can) { if (!can.user.isMobile && !can.isCmdMode()) { return "切换全屏" } },
function(can) { if (can.isCmdMode()) { return "打开首页" } },
function(can) { if (can.ConfSpace() || can.isCmdMode() && can.misc.Search(can, ice.POD)) { return "打开空间" } },
function(can) { if (!can.isCmdMode()) { return "打开链接" } },
"生成链接", "共享工具", "发送聊天",
function(can) { if (can.Conf("_help")) { return "查看文档" } },
function(can) { if (can.misc.Search(can, ice.MSG_DEBUG)) { return "查看脚本" } },
function(can) { if (can.misc.Search(can, ice.MSG_DEBUG)) { return "查看源码" } },
function(can) { if (can.misc.Search(can, ice.MSG_DEBUG)) { return "查看镜像" } },
["视图", "参数", "插件",
function(can) { if (can._action.innerHTML) { return "操作" } },
function(can) { if (can._status.innerHTML) { return "状态" } },
function(can) { if (can.sub && can.sub.ui.project) { return "专注" } },
function(can) { if (can.sub && can.sub.ui.project) { return "项目" } },
function(can) { if (can.sub && can.sub.ui.profile) { return "预览" } },
function(can) { if (can.sub && can.sub.ui.display) { return "演示" } },
], ],
function(can) { if (can.misc.Search(can, ice.MSG_DEBUG)) { ], _init: function(can, msg, list, cb, target) {},
return ["调试", _engine: function(event, can, button) {
function(can) { if (can.Conf("_help")) { return "查看文档" } }, can.Update(event, [ctx.ACTION, button].concat(can.Input([], true)))
"查看脚本", "查看源码", "查看镜像",
"查看通知", "查看视图", "查看数据", "会话存储", "本地存储",
"查看报文", "查看配置", "查看日志", "删除工具",
]
} },
],
_engine: function(event, can, button) { can.Update(event, [ctx.ACTION, button].concat(can.Input())) },
_switch: function(can, sub, mode, save, load) {
if (can.page.ClassList.neg(can, can._target, mode)) { can._mode_list = can._mode_list||[]
can._mode_list.push(kit.Dict(
html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth(), ice.MODE, can.Mode()||"",
html.ACTION, can.page.isDisplay(can._action), html.STATUS, can.page.isDisplay(can._status),
html.OUTPUT, can.base.Copy({}, can._output.style, html.HEIGHT, html.WIDTH, html.MAX_HEIGHT, html.MAX_WIDTH),
ctx.STYLE, can.base.Copy({}, can._target.style, html.LEFT, html.TOP, html.RIGHT, html.BOTTOM), save()
)), can.onimport.size(can, can.ConfHeight(), can.ConfWidth(), false, mode)
} else {
var back = (can._mode_list = can._mode_list||[]).pop(); if (!back) { return }
can.onmotion.toggle(can, can._action, back.action), can.onmotion.toggle(can, can._status, back.status)
can.onimport.size(can, back.height, back.width, false, back.mode), can.page.style(can, can._target, back.style), load && load(back)
}
}, },
"刷新数据": function(event, can) { can.Update(event, can.Input()), can.user.toastSuccess(can) }, "共享工具": function(event, can) { var meta = can.Conf()
"刷新界面": function(event, can) { var sub = can.sub; sub.onlayout._init(sub, sub.ConfHeight(), sub.ConfWidth()), can.user.toastSuccess(can) }, can.onmotion.share(event, can, [{name: chat.TITLE, value: meta.name}, {name: chat.TOPIC, values: [cli.WHITE, cli.BLACK]}], [
"切换浮动": function(event, can, button, sub) { mdb.NAME, meta.index, mdb.TEXT, JSON.stringify(can.Input([], true)),
can.onaction._switch(can, sub, chat.FLOAT, function() { can.onmotion.float(can) }) ])
}, },
"切换全屏": function(event, can, button, sub) { can.onaction._switch(can, sub, chat.FULL, function() { "打开链接": function(event, can) { var meta = can.Conf()
can.page.style(can, can._target, html.LEFT, "", html.TOP, can.onexport.marginTop(), html.BOTTOM, "") var pre = "/chat/cmd/"; if (can.user.mod.isPod) { pre = "/chat/pod/"+can.misc.Search(can, ice.POD)+"/cmd/" }
can.ConfHeight(can.page.height()-can.onexport.marginTop()-can.onexport.marginBottom(can)), can.ConfWidth(can.page.width()) var args = can.Option(); args._path = pre+(meta.index||can.core.Keys(meta.ctx, meta.cmd))
}) }, args._path.indexOf("/cmd/web.wiki.word") > -1 && (args = {_path: pre+args.path})
"远程控制": function(event, can) { can.onaction.keyboard(event, can) },
"共享工具": function(event, can) { var meta = can.Conf(); can.onmotion.share(can.request(event, {pod: can.ConfSpace()}), can, [], [mdb.NAME, meta.index, mdb.TEXT, JSON.stringify(can.Input())]) },
"打开首页": function(event, can) { can.user.open(location.origin) },
"打开空间": function(event, can) { can.user.open(can.misc.MergePodCmd(can, {pod: can.ConfSpace()||can.misc.Search(can, ice.POD)})) },
"打开链接": function(event, can) { can.user.open(can.onexport.link(can)) },
"发送聊天": function(event, can) {
can.user.input(event, can, [{name: chat.MESSAGE, display: "/require/usr/icebergs/core/chat/message.js", run: function(event, cmds, cb) {
can._root.Header.run(can.request(event, {pod: can.ConfSpace()}), [ctx.ACTION, chat.MESSAGE].concat(cmds), function(msg) { cb(msg) })
}}], function(list) { var args = can.core.Item(can.Option(), function(key, value) { return value })
can._root.Header.run(can.request(event, {pod: can.ConfSpace()}), [ctx.ACTION, chat.MESSAGE, list[0],
mdb.TYPE, "plug", ctx.INDEX, can.ConfIndex(), ctx.ARGS, args.length < 2? args[0]||"": JSON.stringify(args)])
can.onappend._float(can, chat.MESSAGE)
})
},
"生成链接": function(event, can) { can.onmotion.share(event, can, [], [web.LINK, can.user.copy(event, can, can.onexport.link(can))]) },
"生成脚本": function(event, can) { var args = can.Input().join(lex.SP), list = [
"export ctx_dev="+location.origin+"; ctx_temp=$(mktemp); curl -o $ctx_temp -fsSL $ctx_dev;"+" source $ctx_temp cmd "+(can.Conf(ctx.INDEX))+lex.SP+args,
"ish_sys_dev_run_command "+args, "ish_sys_dev_run_action", "ish_sys_dev_run_source",
]; can.user.copy(event, can, list[0]) },
"生成图片": function(event, can) { can.user.toimage(can, can.name) },
_view: function(can, cb) { var sub = can.sub; cb(sub), sub.onimport.layout(sub) }, can.user.open(can.misc.MergeURL(can, args))
"参数": function(event, can) { can.onaction._view(can, function(sub) { can.onmotion.toggle(can, can._option) }) },
"操作": function(event, can) { can.onaction._view(can, function(sub) { can.onmotion.toggle(can, can._action) }) },
"状态": function(event, can) { can.onaction._view(can, function(sub) { can.onmotion.toggle(can, can._status) }) },
"专注": function(event, can) { can.onaction._view(can, function(sub) { if (!sub.ui) { return }
sub.ui.project && can.onmotion.hidden(can, sub.ui.project)
sub.ui.profile && can.onmotion.hidden(can, sub.ui.profile)
sub.ui.display && can.onmotion.hidden(can, sub.ui.display)
}) },
"项目": function(event, can) { can.onaction._view(can, function(sub) { sub.ui && sub.ui.project && can.onmotion.toggle(can, sub.ui.project) }) },
"预览": function(event, can) { can.onaction._view(can, function(sub) { sub.ui && sub.ui.project && can.onmotion.toggle(can, sub.ui.profile) }) },
"演示": function(event, can) { can.onaction._view(can, function(sub) { sub.ui && sub.ui.project && can.onmotion.toggle(can, sub.ui.display) }) },
"插件": function(event, can) {
can.user.input(event, can, [ctx.INDEX, ctx.ARGS], function(data) {
var sub = can.sub; sub.onimport.tool(sub, [data], function(sub) { sub.select() })
})
}, },
"生成链接": function(event, can) { var meta = can.Conf()
var pre = "/chat/cmd/"; if (can.user.mod.isPod) { pre = "/chat/pod/"+can.misc.Search(can, ice.POD)+"/cmd/" }
var args = can.Option(); args._path = pre+(meta.index||can.core.Keys(meta.ctx, meta.cmd))
args._path.indexOf("/cmd/web.wiki.word") > -1 && (args = {_path: pre+args.path})
var url = can.misc.MergeURL(can, args)
can.user.copy(event, can, url)
can.onmotion.share(event, can, [], [mdb.LINK, url])
},
"生成脚本": function(event, can, button) { var conf = can.Conf()
var args = can.Input("", true).join(ice.SP); var list = [
"export ctx_dev="+location.origin+"; ctx_temp=$(mktemp); curl -fsSL $ctx_dev -o $ctx_temp;"+" source $ctx_temp "+(conf.index||"")+ice.SP+args,
"ish_sys_dev_run_command "+args, "ish_sys_dev_run_action", "ish_sys_dev_run_source",
]
var ui = can.user.toast(can, {title: button, duration: -1, width: -300,
content: '<div class="story" data-type="spark", data-name="shell">'+
'<label>$ </label>'+'<span>'+list.join("</span><br/><label>$ </label><span>")+'</span>'+'</div>',
action: [cli.CLOSE],
})
can.onmotion.story.auto(can, ui._target)
can.user.copy(event, can, list[0])
},
"生成图片": function(event, can) { can.onmotion.toimage(event, can, can._name) },
"保存参数": function(event, can) { can.search(event, ["River.ondetail.保存参数"]) }, "保存参数": function(event, can) { can.search(event, ["River.ondetail.保存参数"]) },
"清空参数": function(event, can) { can.page.SelectArgs(can, can._option, "", function(target) { return target.value = "" }) }, "清空参数": function(event, can) {
"复制数据": function(event, can) { var sub = can.sub; can.user.copy(event, can, sub.onexport.table(sub)||sub.onexport.board(sub)) }, can.page.SelectArgs(can, can._option, "", function(item) { return item.value = "" })
"下载数据": function(event, can) { var sub = can.sub; can.user.input(event, can, [{name: "filename", value: can.Conf(mdb.NAME)}], function(list) { },
can.user.downloads(can, sub.onexport.table(sub), list[0], nfs.CSV), can.user.downloads(can, sub.onexport.board(sub), list[0], nfs.TXT) "刷新数据": function(event, can) { can.Update({}, can.Input([], true)) },
}) },
"复制数据": function(event, can) { var meta = can.Conf(), msg = can._msg
var res = [msg.append && msg.append.join(",")]; msg.Table(function(line, index, array) {
res.push(can.core.Item(line, function(key, value) { return value }).join(","))
})
res.length > 1 && can.user.copy(event, can, res.join(ice.SP))
msg.result && can.user.copy(event, can, msg.Result())
},
"下载数据": function(event, can) { var meta = can.Conf(), msg = can._msg
var res = [msg.append && msg.append.join(",")]; msg.Table(function(line, index, array) {
res.push(can.core.Item(line, function(key, value) { return value }).join(","))
})
res.length > 1 && can.user.downloads(can, res.join("\n"), meta.name+".csv")
msg.result && can.user.downloads(can, msg.Result(), meta.name+".txt")
},
"清空数据": function(event, can) { can.onmotion.clear(can, can._output) }, "清空数据": function(event, can) { can.onmotion.clear(can, can._output) },
"删除工具": function(event, can) { can.page.Remove(can, can._target) },
// "生成图片": function(event, can) {
// can.user.toPNG(can, "hi.png", can._target.outerHTML, can.Conf(html.HEIGHT), can.Conf(html.WIDTH))
// },
"查看文档": function(event, can) { can.requests(event, {action: ice.HELP}), can.onengine.signal(can, chat.ONDEBUGS, can.requestPodCmd(event)) }, "摄像头": function(event, can) {
"查看脚本": function(event, can) { can.onappend._float(can, web.CODE_VIMER, can.misc.SplitPath(can, can.sub._path)) }, var constraints = {audio: false, video: {width: 200, height: 200}}
"查看源码": function(event, can) { can.requests(event, {action: nfs.SOURCE}), can.onengine.signal(can, chat.ONDEBUGS, can.requestPodCmd(event)) }, var ui = can.page.Append(can, can._output, [{view: ctx.ACTION}, {view: "capture", list: [{type: "video", _init: function(item) {
"查看镜像": function(event, can) { can.onappend._float(can, {index: "web.code.compile"}) }, navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
"查看通知": function(event, can) { can.onappend._float(can, {index: "can.toast"}, [can.ConfIndex()]) }, item.srcObject = stream, item.onloadedmetadata = function(e) {
"查看视图": function(event, can) { can.onappend._float(can, {index: "can.view", _target: can._fields||can._target}) }, item.play()
"查看数据": function(event, can) { can.onappend._float(can, {index: "can.data", _target: can}) }, }, ui.stream = stream
"会话存储": function(event, can) { can.onappend._float(can, {index: "can.sessionStorage"}, [can.ConfIndex()]) }, }).catch(function(err) { console.log(err.name + ": " + err.message); })
"本地存储": function(event, can) { can.onappend._float(can, {index: "can.localStorage"}, [can.ConfIndex()]) }, }}]}])
"查看报文": function(event, can) { var msg = can._msg
can.onappend._float(can, {title: "msg(报文)", index: ice.CAN_PLUGIN, display: "/plugin/story/json.js"}, [], function(sub) { can.onappend._action(can, ["关闭", "抓拍"], ui.action, {
sub.run = function(event, cmds, cb) { var _msg = can.request(event); _msg.result = [JSON.stringify(msg)], cb(_msg) } "抓拍": function(event) {
var canvas = can.page.Append(can, ui.capture, [{type: "canvas", width: ui.video.offsetWidth, height: ui.video.offsetHeight}]).first
canvas.getContext("2d").drawImage(ui.video, 0, 0)
can.page.Append(can, ui.capture, [{img: canvas.toDataURL('image/png'), style: {width: ui.video.offsetWidth, height: ui.video.offsetHeight}}])
can.page.Remove(can, canvas)
},
"关闭": function(event) {
can.core.List(ui.stream.getTracks(), function(track) { track.stop() })
can.page.Remove(can, ui.action)
can.page.Remove(can, ui.video)
can.page.Remove(can, ui.capture)
},
}) })
}, },
"查看配置": function(event, can) { can.requests(event, {action: ctx.CONFIG}), can.onengine.signal(can, chat.ONDEBUGS, can.requestPodCmd(event)) },
"查看日志": function(event, can) { var logid = can.Status("log.id"); can.onappend._float(can, web.CODE_XTERM, ["sh", logid, "grep "+logid+" var/log/bench.log | grep -v grep | grep -v '"+logid+" $'"]) },
"打包页面": function(event, can) { can.onengine.signal(can, "onwebpack", can.request(event)) },
"删除工具": function(event, can) { can.onaction._close(event, can) },
refresh: function(event, can) { can.onimport.size(can, can.ConfHeight(), can.ConfWidth(), true, can.Mode()) },
detail: function(event, can) { var msg = can.request(event)
can.core.Item(can.Option(), function(key, value) {
can.Option(key, msg.Option(key)||"")
}), can.Update()
},
close: function(event, can) {
if (can.isCmdMode()) {
can.user.close()
} else if (can.isFullMode()) {
can.onaction["切换全屏"](event, can, "切换全屏", can.sub)
} else if (can.isFloatMode()) {
can.onaction["切换浮动"](event, can, "切换浮动", can.sub)
} else {
can.onaction._close(event, can), can.onexport.close(can)
}
},
_close: function(event, can) {
can.onengine.signal(can, "onremove", can.request(event, {query: can.page.getquery(can, can._target)}))
can.page.Remove(can, can._target)
},
clear: function(event, can) { can.onmotion.clear(can, can._output) },
actions: function(event, can) { can.onmotion.toggle(can, can._action) }, actions: function(event, can) { can.onmotion.toggle(can, can._action) },
help: function(event, can) { clear: function(event, can, name) { can.onmotion.clear(can, can._output) },
can.onappend._float(can, {index: web.WIKI_WORD}, [can.Conf("_help")]) close: function(event, can) { can.page.Remove(can, can._target) },
},
full: function(event, can) { can.onaction["切换全屏"](event, can, "切换全屏", can.sub) },
prev: function(event, can) { can.runAction(event, mdb.PREV, [can.Status(mdb.TOTAL)||0, can.Option(mdb.LIMIT)||can.Action(mdb.LIMIT)||can._msg.Option("cache.limit")||"", can.Option(mdb.OFFEND)||can.Action(mdb.OFFEND)||""], function(msg) { can.onimport._process(can, msg) }) },
next: function(event, can) { can.runAction(event, mdb.NEXT, [can.Status(mdb.TOTAL)||0, can.Option(mdb.LIMIT)||can.Action(mdb.LIMIT)||can._msg.Option("cache.limit")||"", can.Option(mdb.OFFEND)||can.Action(mdb.OFFEND)||""], function(msg) { can.onimport._process(can, msg) }) },
upload: function(event, can) { can.user.upload(event, can) }, upload: function(event, can) { can.user.upload(event, can) },
keyboard: function(event, can) { change: function(event, can, name, value, cb) {
can.base.isUndefined(can._daemon) && can.ondaemon._list[0] && (can._daemon = can.ondaemon._list.push(can)-1) return can.page.SelectArgs(can, can._option, "", function(input) {
can.request(event, kit.Dict(ctx.INDEX, can._index, ice.MSG_DAEMON, can.core.Keys(can.ondaemon._list[0], can._daemon))) if (input.name == name && value != input.value) { input.value = value
can.runAction(event, "keyboard", [], function(msg) { can.user.copy(msg._event, can, msg.Append(mdb.NAME)) var data = input.dataset||{}; can.Update(event, can.Input(), cb)
can.user.toast(can, {title: msg.Append(mdb.NAME), duration: -1, content: msg.Append(mdb.TEXT), action: [cli.CLOSE, cli.OPEN]}) return input
}
}) })
}, },
getClipboardData: function(event, can, button) { next: function(event, can) {
function add(text) { can.runAction(event, button, can.base.Simple(can.base.ParseJSON(text)), function() { can.Update() }) } can.Update(event, [ctx.ACTION, "next", can.Status("total")||0, can.Option("limit"), can.Option("offend")])
navigator.clipboard? navigator.clipboard.readText().then(add).catch(function(err) { can.misc.Log(err) }):
can.user.input(event, can, [{type: html.TEXTAREA, name: mdb.TEXT}], function(list) { add(list[0]) })
}, },
getLocation: function(event, can, button) { can.user.agent.getLocation(can, function(data) { prev: function(event, can) {
can.user.input(can.request(event, data), can, [mdb.TYPE, mdb.NAME, mdb.TEXT, aaa.LATITUDE, aaa.LONGITUDE], function(args) { can.Update(event, [ctx.ACTION, "prev", can.Status("total")||0, can.Option("limit"), can.Option("offend")])
can.runAction(event, button, args, function() { can.Update() }) },
})
}) }, listTags: function(event, can, button) { var list = []
openLocation: function(event, can) { can.user.agent.openLocation(can, can.request(event)) }, can.core.List([can.base, can.core, can.misc, can.page, can.user,
scanQRCode0: function(event, can, button) { can.user.agent.scanQRCode(can) }, can.onengine, can.ondaemon, can.onappend, can.onlayout, can.onmotion, can.onkeymap,
scanQRCode: function(event, can, button) { can.user.agent.scanQRCode(can, function(data) { can.runAction(event, button, can.base.Simple(data), function() { can.Update() }) }) }, ], function(lib) {
record0: function(event, can, name, cb) { can.user.input(event, can, [{name: nfs.FILE, value: name}], function(list) { can.core.Item(lib, function(key, value) { if (key.indexOf("_") == 0 || !lib.hasOwnProperty(key)) { return }
navigator.mediaDevices.getDisplayMedia({video: {height: window.innerHeight}}).then(function(stream) { var toast list.push({zone: lib._name, type: typeof value, name: key, text: can.base.isObject(value)? "": (value+"").split(ice.NL)[0],
can.core.Next([3, 2, 1], function(item, next) { toast = can.user.toast(can, item + "s 后开始截图"), can.onmotion.delay(can, next, 1000) }, function() { toast.close() path: "usr/volcanos/", file: lib._path, line: 1,
cb(stream, function(blobs, ext) { var msg = can.request(event); msg._upload = new File(blobs, list[0]+nfs.PT+ext)
can.runAction(msg, html.UPLOAD, [], function() { can.user.toastSuccess(can), can.Update() })
can.core.List(stream.getTracks(), function(item) { item.stop() })
}) })
}) })
}).catch(function(err) { can.user.toast(can, err.name + ": " + err.message) }) })
}) }, var msg = can.request(event, {_handle: true, text: can.base.Format(list)})
record1: function(event, can) { can.onaction.record0(event, can, "shot", function(stream, cb) { var height = window.innerHeight can.run(event, [ctx.ACTION, button], function() { can.user.toastSuccess(can) })
var video = can.page.Append(can, document.body, [{type: html.VIDEO, height: height}])._target; video.srcObject = stream, video.onloadedmetadata = function() { video.play(), width = video.offsetWidth },
var canvas = can.page.Append(can, document.body, [{type: html.CANVAS, height: height, width: width}])._target; canvas.getContext("2d").drawImage(video, 0, 0, width, height) getClipboardData: function(event, can, button) {
canvas.toBlob(function(blob) { cb([blob], nfs.PNG) }) function add(text) {
can.run(event, can.base.Simple(ctx.ACTION, button, can.base.ParseJSON(text)), function(msg) {
can.user.toastSuccess(can), can.Update()
}, true)
} }
}) }, if (navigator.clipboard) {
record2: function(event, can) { can.onaction.record0(event, can, "shot", function(stream, cb) { navigator.clipboard.readText().then(add).catch(function(err) { can.misc.Log(err) })
var recorder = new MediaRecorder(stream, {mimeType: html.VIDEO_WEBM}), blobs = []; recorder.ondataavailable = function(res) { blobs.push(res.data) } } else {
recorder.onstop = function() { cb(blobs, nfs.WEBM) }, recorder.start(1) can.user.input(event, can, [{type: html.TEXTAREA, name: mdb.TEXT}], function(ev, button, data, list, args) { add(list[0]) })
}) },
})
Volcanos(chat.ONEXPORT, {
_output: function(can, msg) {},
output: function(can, msg) {}, action: function(can, button, data) {}, record: function(can, value, key, data) {},
marginTop: function() { return 0 }, marginBottom: function() { return 0 }, outputMargin: function(can) { return 0 },
actionHeight: function(can) { return can.page.ClassList.has(can, can._target, html.OUTPUT)? 0: html.ACTION_HEIGHT },
outputHeight: function(can) { var height = can.ConfHeight() - can.onexport.actionHeight(can) - can.onexport.statusHeight(can)
if (can.user.isMobile) { return height } height -= can.onexport.outputMargin(can)
can.page.SelectChild(can, can._output, html.TABLE, function(target) { height -= target.offsetHeight })
return can.base.Max(can.base.Min(height, can.ConfHeight()/2), can.ConfHeight()-2*html.ACTION_HEIGHT, 320)
},
statusHeight: function(can) {
return can.page.ClassList.has(can, can._target, html.OUTPUT) || !can.page.isDisplay(can._status) || (can._target.offsetHeight > 0 && can._status.offsetHeight == 0) ||
can._status.innerHTML == "" && !can.page.ClassList.has(can, can._target, html.PLUG)? 0: html.STATUS_HEIGHT
},
session: function(can, key, value) { if (value) { value = JSON.stringify(value) }
return can.misc.sessionStorage(can, [can.ConfSpace()||can.misc.Search(can, ice.POD), can.ConfIndex(), key, location.pathname], value)
},
storage: function(can, key, value) { if (value) { value = JSON.stringify(value) }
return can.misc.localStorage(can, [can.ConfSpace()||can.misc.Search(can, ice.POD), can.ConfIndex(), key], value)
},
hash: function(can, hash) {
if (can.user.isMobile) { return }
can.misc.SearchHash(can, hash), can.onexport.storage(can, "hash", hash)
return hash
},
title: function(can, title) { if (!can.isCmdMode()) { return }
var list = []; function push(p) { p && list.indexOf(p) == -1 && list.push(p) }
if (!can.user.isMobile) {
if (arguments.length == 2 && !can.base.isIn(can.ConfIndex(), web.PORTAL, code.VIMER, wiki.FEEL)) { push(can.user.trans(can, can.ConfIndex().split(".").pop(), can.ConfHelp())) }
} }
can.core.List(arguments, function(title, index) { index > 0 && push(title) })
can.user.isMobile || push(can.user.mod.isPod? can.user.info.titles||can.ConfSpace()||can.misc.Search(can, ice.POD): location.host)
can.user.title(list.join(" "))
}, },
args: function(can) { return can.Option() }, getLocation: function(event, can, button) {
link: function(can) { can.user.agent.getLocation(function(data) { can.request(event, data)
// if (can.sub && can.sub.onexport.link) { return can.sub.onexport.link(can.sub) } can.user.input(event, can, [mdb.TYPE, mdb.NAME, mdb.TEXT, "latitude", "longitude"], function(ev, bu, data, list, args) {
var args = can.Option(); args.pod = can.ConfSpace()||can.misc.Search(can, ice.POD), args.cmd = can.ConfIndex() can.run(event, [ctx.ACTION, button].concat(can.base.Simple(args, data)), function(msg) {
can.core.Item(args, function(key, value) { key != ice.POD && !value && delete(args[key]) }) can.user.toastSuccess(can), can.Update()
var hash = can.onexport.storage(can, "hash")||""; can.base.isArray(hash) && (hash = hash.join(":")), hash && (hash = "#"+hash) }, true)
return can.base.replaceAll(can.misc.MergePodCmd(can, args, true), "%2F", "/")+hash })
})
}, },
close: function(can, msg) {}, openLocation: function(event, can) { can.user.agent.openLocation(can.request(event)) },
}) })
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,27 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { var field = can.Conf(mdb.FIELD)||mdb.VALUE, cache = {}, path = msg.Option(nfs.PATH)||can.Conf(nfs.PATH)||"10"
var max = 0, data = msg.Table(function(value) { if (parseFloat(value[field]) > max) { max = parseFloat(value[field]) } return {name: value.name, value: value[field]} })
var option = {title: {text: msg.Option("title")||can.Conf("title"), textStyle: {fontSize: '24'}, left: '5%'},
tooltip: {formatter: function (item) { return item.name+': '+(item.value||"0") }}, visualMap: {min: 0, max: max, text: [max]},
}
if (can.Conf(ctx.STYLE) == html.FLOAT && !can.page.ClassList.has(can, can._fields, html.FLOAT)) { msg.Option(ice.MSG_STATUS, ""), can.onlayout._float(can) }
can.page.requireModules(can, ["echarts/dist/echarts.min.js"], function() { can.misc.GET(can, "/wiki/geoarea/city.json", function(text) { can.onimport.adcode = JSON.parse(text)
!can.onimport.adcode[path] && can.core.Item(can.onimport.adcode, function(code, list) { list.name == path && (path = code) })
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth())
function load(path, name) { if (cache[path]) { return cache[path]._tabs.click() } can.onimport.load(can, path, function(text) { echarts.registerMap(path, JSON.parse(text))
can.onimport.tabs(can, [{name: name}], function(event, tabs) { var list = can.onimport.adcode[path]; msg.Length() == 0 && can.Status(mdb.COUNT, list && list.list? can.core.Item(list.list).length: 0)
if (cache[path]) { return can.page.SelectChild(can, can._output, html.DIV_ITEM, function(target) { can.onmotion.toggle(can, target, target == cache[path]) }) }
var chart = echarts.init(cache[path] = can.page.Append(can, can._output, [{view: html.ITEM, style: {height: can.ConfHeight(), width: can.ConfWidth()}}])._target)
option.series = [{data: data, mapType: path, type: "map"}], option.geo = {map: path}, chart.setOption(option)
chart.on(html.CLICK, function(item) { if (list && list.list) { var code = list.list[item.name]; code && load(code, item.name) } })
cache[path]._tabs = tabs._target, can.page.SelectChild(can, can._output, html.DIV_ITEM, function(target) { can.onmotion.toggle(can, target, target == cache[path]) })
}, function() { can.page.Remove(can, cache[path]), delete(cache[path]) })
}) } load(path, can.onimport.adcode[path].name)
}) })
}, adcode: {},
load: function(can, path, cb) { var _path = path
path.length == 2 && (path += "0000"), path.length == 4 && (path += "00")
path = "/wiki/geoarea/"+path+(can.base.endWith(path, "00")? "_full": "")+".json"
can.misc.GET(can, path, function(text) { text? cb(text): can.misc.GET(can, path.replace("_full", ""), cb) })
},
})

View File

@ -1,42 +0,0 @@
fieldset.tinymce div.tox-tinymce,
fieldset.tinymce div.tox:not(.tox-tinymce-inline) .tox-editor-header {
border:none;
}
fieldset.tinymce div.tox-promotion { display:none; }
fieldset.tinymce div.tox div.tox-sidebar-wrap div.tox-edit-area iframe {
background-color:var(--output-bg-color);
}
div.tox .tox-collection--list .tox-collection__item--active,
div.tox .tox-collection--list .tox-collection__item--active:not(.tox-collection__item--state-disabled),
div.tox .tox-collection--list .tox-collection__item--enabled,
fieldset.tinymce div.tox .tox-mbtn:hover:not(:disabled):not(.tox-mbtn--active),
fieldset.tinymce div.tox .tox-mbtn:focus:not(:disabled),
fieldset.tinymce div.tox .tox-mbtn--active,
fieldset.tinymce div.tox .tox-tbtn:hover {
background-color:var(--hover-bg-color);
color:var(--hover-fg-color);
}
div.tox .tox-menu,
div.tox .tox-collection__item,
fieldset.tinymce div.tox .tox-editor-header,
fieldset.tinymce div.tox .tox-mbtn,
fieldset.tinymce div.tox .tox-menubar,
fieldset.tinymce div.tox .tox-toolbar,
fieldset.tinymce div.tox .tox-toolbar-overlord,
fieldset.tinymce div.tox .tox-toolbar__overflow,
fieldset.tinymce div.tox .tox-toolbar__primary,
fieldset.tinymce div.tox .tox-statusbar,
fieldset.tinymce div.tox .tox-statusbar__path-item,
fieldset.tinymce div.tox .tox-statusbar__wordcount,
fieldset.tinymce div.tox .tox-statusbar a {
background-color:var(--plugin-bg-color);
color:var(--plugin-fg-color);
}
fieldset.tinymce div.tox .tox-tbtn svg,
fieldset.tinymce div.tox .tox-tbtn:disabled svg,
fieldset.tinymce div.tox .tox-tbtn:disabled:hover svg,
fieldset.tinymce div.tox .tox-tbtn--disabled svg,
fieldset.tinymce div.tox .tox-tbtn--disabled:hover svg,
fieldset.tinymce div.tox .tox-statusbar__branding svg {
fill:var(--plugin-fg-color);
}

View File

@ -1,67 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) {
can.require(["/require/modules/tinymce/tinymce.min.js", "/plugin/local/code/vimer.js"], function(can) { can.onimport._last_init(can, msg, function(msg) {
can.onappend.style(can, "tinymce"), cb && cb(msg)
}) })
},
content: function(can, text) { return can.ui.editor.setContent(text) },
layout: function(can) { can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth()) },
}, [""])
Volcanos(chat.ONSYNTAX, {
_split: function(can, msg, target) {
var _target = can.page.Appends(can, target, [{type: html.TEXTAREA}])._target
tinymce.init({target: _target, height: can.ConfHeight(), // menubar: false,
save_onsavecallback: function () { can.onaction.save({}, can, nfs.SAVE) },
content_style: "body#tinymce { background:transparent; color:silver; }",
toolbar: [[
"save code undo redo cut copy paste",
"backcolor forecolor bold italic underline strikethrough subscript superscript",
"alignleft aligncenter alignright alignjustify outdent indent",
"bullist numlist table image media link charmap",
"blockquote removeformat hr pagebreak anchor insertdatetime",
"fullscreen wordcount preview print help",
].join("|")],
plugins: [
"save",
"code",
"lists",
"advlist",
"table",
"image",
"media",
"link",
"insertdatetime",
"charmap",
"anchor",
"pagebreak",
"fullscreen",
"wordcount",
"preview",
"help",
"autosave",
"codesample",
"directionality",
"emoticons",
"importcss",
"font_size",
"autolink",
"nonbreaking",
"searchreplace",
"visualblocks",
"visualchars",
].join(" ")
}).then(function(list) { can.ui.editor = list[0], can.ui.editor.setContent(msg.Result()) }).catch(function(err) { can.misc.Warn(err) })
},
})
Volcanos(chat.ONEXPORT, {
content: function(can) { return can.ui.editor.getContent() },
})
Volcanos(chat.ONPLUGIN, {
tinymce: shy("富文本", {
save: shy(function(can, msg) { can.user.toast(can, msg.Option(nfs.CONTENT)) }),
}, [nfs.PATH, nfs.FILE, nfs.LINE, ice.LIST, nfs.SAVE], function(can, msg, meta) {
msg.Display(meta._path)
}),
})

View File

@ -1,21 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.onappend.style(can, html.FORM, can._output)
if (can.isCmdMode()) { can.onappend.style(can, html.OUTPUT) }
can.page.Append(can, can._output, msg.Table(function(item) {
return {view: [[html.ITEM, item.type]], list: [item.type != html.BUTTON && {text: [can.user.trans(can, item.name, item._trans, html.INPUT), "", mdb.NAME]}, item.need == "must" && {text: ["*", "", "need"]}], _init: function(target) {
item.type == html.BUTTON && (item.onclick = function(event) { var args = []
can.core.Item(can.page.SelectArgs(can, can._output)[0], function(key, value) { args.push(key, value) })
can.Update(can.request(event, {_handle: ice.TRUE}), [ctx.ACTION, item.name].concat(args), function(msg) {
if (msg.IsErr()) {
can.user.toastFailure(can, msg.Result())
return
}
can.Update()
})
}), can.onappend.input(can, item, "", target)
}, onclick: function(event) {
can.page.Select(can, event.currentTarget, html.INPUT, function(target) { target.focus() })
}}
})), can.onappend.board(can, msg)
},
})

View File

@ -1,8 +1,23 @@
div.output.json { font-family:var(--code-font-family); font-size:var(--code-font-size); white-space:pre; } fieldset.plugin div.output div.item div.item {
div.output.json div.item { cursor:text; } border:solid 1px #0000000d;
div.output.json div.item:hover { background-color:transparent; color:unset; } border-left:dashed 1px lightblue;
div.output.json div.item div.item { border:transparent solid 1px; border-left:var(--disable-fg-color) dashed 1px; padding-left:15px; margin-left:5px; } margin-left:5px; padding-left:15px;
div.output.json div.item div.item:hover { border:var(--box-border); } cursor:pointer;
div.output.json div.item span.key { cursor:pointer; } }
div.output.json div.item span.string { color:var(--code-string); } fieldset.plugin div.output div.item div.item:hover {
div.output.json div.item label.nonce { color:var(--disable-fg-color); user-select:none; } border:solid 1px red;
}
fieldset.plugin div.output div.item span.nonce {
color:lightblue;
cursor:pointer;
}
fieldset.plugin div.output div.item span.key {
color:yellow;
}
fieldset.plugin div.output div.item span.string {
color:magenta;
}
fieldset.plugin div.output div.item span.const {
color:cyan;
}

View File

@ -1,43 +1,60 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(can, target), can.onappend.table(can, msg) Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.onappend.style(can, nfs.JSON, can._output), can.onimport.show(can, can.base.Obj(msg.Result(), {}), target, msg) can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
can.onimport.show(can, can.base.Obj(msg.Result(), {}), target)
}, },
show: function(can, data, target, msg) { show: function(can, data, target) {
if (data.append && !can.page.tagis(can._fields, "fieldset.float")) {
var msg = can.request(); msg.Copy(data), can.onappend.table(can, msg)
msg._xhr = {responseText: msg.Result()}
can.onmotion.delay(can, function() { can.onappend._status(can, msg) })
return
}
var hidden = data.detail && data.option
function show(data, target, index, total) { var list function show(data, target, index, total) { var list
switch (typeof data) { switch (typeof data) {
case code.OBJECT: if (data == null) { can.page.Append(can, target, [{text: "null"}]); break } case lang.OBJECT:
function wrap(begin, end, add, cb, inner) { can.page.Append(can, target, [{text: begin}]) if (data == null) {
add && can.page.Append(can, target, inner||[{text: [can.page.unicode.inner, html.LABEL, ["nonce", html.HIDE]]}]), cb(), can.page.Append(can, target, [{text: end}]) return can.page.Append(can, list, [{text: "null"}]).item
return
} }
function format(data) { return can.page.trans(can, JSON.stringify(data)) } function wrap(begin, end, add, cb) {
function toggle(list) { return list && can.onmotion.toggle(can, list) } can.page.Append(can, target, [{text: begin}])
function _item() { return can.page.Append(can, list = list || can.page.Append(can, target, [html.LIST])._target, [html.ITEM])._target } add && can.page.Append(can, target, [{text: ["...", html.SPAN, "nonce"]}]), cb()
if (can.base.isArray(data)) { var inner = "" can.page.Append(can, target, [{text: end}])
if (hidden && can.core.List(data, function(item) { if (can.base.isIn(typeof item, code.STRING, code.NUMBER, code.BOOLEAN)) { return item } }).length == data.length) { }
inner = [], can.core.List(data, function(item, index) { inner.push({text: [format(item), "", [code.STRING, code.INNER]]}, index < data.length-1 && {text: [", ", "", [code.INNER]]}) }) function toggle(list) { list && can.onmotion.toggle(can, list) }
} function _item() {
list = list || can.page.Append(can, target, [{view: html.LIST}]).list
return can.page.Append(can, list, [{view: html.ITEM}]).item
}
if (can.base.isArray(data)) { // 数组
wrap("[", "]", data.length > 0, function() { can.core.List(data, function(value, index) { var item = _item() wrap("[", "]", data.length > 0, function() { can.core.List(data, function(value, index) { var item = _item()
show(value, item, index, data.length) show(value, item, index, data.length)
}) }, inner)
} else { var length = can.core.Item(data).length, count = 0
wrap("{", "}", length > 0, function() { can.core.Item(data, function(key, value) { var item = _item()
can.page.Append(can, item, [{text: [format(key), "", mdb.KEY], onclick: function(event) { var display = !toggle(sub)
sub && can.page.SelectChild(can, sub.parentNode, "span.inner", function(target) { can.onmotion.toggle(can, target, display) })
sub && can.page.SelectChild(can, sub.parentNode, "label.nonce", function(target) { can.onmotion.toggle(can, target, display) })
}}, {text: ": "}]); key == ice.MSG_STATUS && (value = can.base.Obj(value[0])||value)
var sub = show(value, item, count++, length); hidden && sub && can.onmotion.hidden(can, sub)
key == ice.MSG_STATUS && (can.page.SelectChild(can, item, "label.nonce", function(target) { can.onmotion.toggle(can, target, true) }))
}) }) }) })
} break } else { // 对象
case code.STRING: can.page.Append(can, target, [{text: [format(data), "", code.STRING]}]); break var length = can.core.Item(data).length, count = 0
default: can.page.Append(can, target, [{text: [format(data), "", code.CONSTANT]}]) wrap("{", "}", length > 0, function() { can.core.Item(data, function(key, value) { var item = _item()
} (index < total-1) && can.page.Append(can, target, [{text: mdb.FS}]); return list can.page.Append(can, item, [{text: ['"'+key+'"', html.SPAN, "key"], onclick: function(event) { toggle(sub) }}, {text: ': '}])
}; show(data, can.page.Append(can, target, [html.ITEM])._target, 0, 0) var sub = show(value, item, count++, length)
}) })
}
break
case lang.STRING: /* 字串 */ can.page.Append(can, target, [{text: ['"'+data+'"', html.SPAN, lang.STRING]}]); break
default: /* 其它 */ can.page.Append(can, target, [{text: [''+data+'', html.SPAN, "const"]}])
}
(index < total-1) && can.page.Append(can, target, [{text: ice.FS}])
return list
}; show(data, can.page.Append(can, target, [{view: html.ITEM}]).item, 0, 0)
}, },
}, [""]) }, [""])
Volcanos("onaction", {help: "组件菜单", list: ["展开", "折叠", "复制"],
"展开": function(event, can) {
can.page.Select(can, can._output, "div.list div.list", function(list) {
can.onmotion.hidden(can, list, true)
})
},
"折叠": function(event, can) {
can.page.Select(can, can._output, "div.list div.list", function(list) {
can.onmotion.hidden(can, list)
})
},
"复制": function(event, can) {
can.user.copy(event, can, can._msg.Result())
},
})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,6 +0,0 @@
fieldset.monaco .monaco-editor,
fieldset.monaco .monaco-editor .margin,
fieldset.monaco .monaco-editor-background,
fieldset.monaco .monaco-diff-editor {
background-color:var(--output-bg-color);
}

View File

@ -1,31 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) {
can.require(["/require/modules/monaco-editor/min/vs/loader.js"], function() {
require.config({paths: {vs: "/require/modules/monaco-editor/min/vs"}})
require(["vs/editor/editor.main"], function () {
can.require(["/plugin/local/code/vimer.js"], function(can) { can.onimport._last_init(can, msg, function(msg) {
can.onappend.style(can, "monaco"), cb && cb(msg)
}) })
})
})
},
_theme: function(can) { if (can.base.isIn(can.getHeaderTheme(), html.LIGHT, html.WHITE)) { monaco.editor.setTheme("vs") } else { monaco.editor.setTheme("vs-dark") } },
layout: function(can) { can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth()), can.ui.editor && can.ui.editor.layout() },
content: function(can, text) { return can.ui.editor.setValue(text) },
}, [""])
Volcanos(chat.ONSYNTAX, {
_split: function(can, msg, target) { can.onimport._theme(can), can.onengine.listen(can, chat.ONTHEMECHANGE, function() { can.onimport._theme(can) })
can.ui.editor = monaco.editor.create(target, {value: msg.Result(), language: "javascript", automaticLayout: true, resize: true})
can.ui.editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () { can.onaction.save({}, can, nfs.SAVE) })
},
})
Volcanos(chat.ONEXPORT, {
content: function(can) { return can.ui.editor.getValue() },
})
Volcanos(chat.ONPLUGIN, {
monaco: shy("编辑器", {
save: shy(function(can, msg) { can.user.toast(can, msg.Option(nfs.CONTENT)) }),
}, [nfs.PATH, nfs.FILE, nfs.LINE, ice.LIST, nfs.SAVE], function(can, msg, meta) {
msg.Display(meta._path)
}),
})

View File

@ -1,86 +1,44 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
_init: function(can, msg, cb) { can.ui = can.onappend.layout(can) can.require(["/plugin/local/wiki/draw.js", "/plugin/local/wiki/draw/path.js"], function() {
can.page.requireDraw(can, function() { can.db.delay = 50, can.onappend.style(can, "pie"), can.onaction.list = [] can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
can.list = can.onimport._data(can, msg, can.Conf(mdb.FIELD)||msg.append[1]||mdb.VALUE) can.onmotion.clear(can), can.onimport._show(can, msg)
can.core.List(can.list, function(item) { msg.Push("weight", item.value.weight = parseInt(item.span*100/360)+"%").Push(cli.COLOR, '<span style="background-color:'+item.color+'"> </span>') }) var r = 200, margin = 20; can.svg.Val(html.WIDTH, 2*(r+margin)), can.svg.Val(html.HEIGHT, 2*(r+margin))
can.onappend.table(can, msg, null, can.ui.profile), can.page.Select(can, can.ui.profile, html.TR, function(tr, index) { can.ui.table = tr.parentNode can._args = can.base.Copy({field: "value"}, can.base.ParseURL(can._display))
can.page.Modify(can, tr, {onmouseenter: function(event) { can._draw(can.db.which = index-1) }}) can.onimport._draw(can, msg, can._args.field, r+margin, r+margin, r, margin, 0)
}), can.base.isFunc(cb) && cb(msg), can.onappend._status(can, msg.append) can.onmotion.clear(can, can.ui.project), can.onappend.table(can, msg, null, can.ui.project)
can.onmotion.hidden(can, can.ui.project, true)
can.page.Modify(can, can.ui.project, {style: {"max-width": 480}})
can.page.Select(can, can.ui.project, html.TR, function(tr, index) {
can.page.Modify(can, tr, {onmouseenter: function(event) {
can.onmotion.clear(can, can.svg), can.onimport._draw(can, msg, can._args.field, r+margin, r+margin, r, margin, index-1)
}})
})
}) })
}, },
_data: function(can, msg, field) { var list = [] _draw: function(can, msg, field, x, y, r, margin, which) {
var color = [ function pos(x, y, r, angle) { angle -= 90
"#8085e9", return [x + r * Math.cos(angle * Math.PI / 180), y + r * Math.sin(angle * Math.PI / 180)]
"#95a2ff", }
"#73abf5", function pie(x, y, r, begin, span, color, cb) { can.onimport.draw({}, can, {shape: "path", style: {
"#3cb9fc", "stroke-width": 1, stroke: color, fill: color, d: can.base.joins([
"#0082fc",
"#87e885",
"#90ed7d",
"#22ed7c",
"#05f8d6",
"#cb9bff",
"#bf19ff",
"#f47a75",
"#fa8080",
"#f7a35c",
"#ffc076",
"#f9e264",
"#fae768",
"#5f45ff",
"#02cdff",
"#0090ff",
"#854cff",
"#09b0d3",
"#1d27c9",
"#765005",
"#314976",
"#009db2",
"#024b51",
"#0780cf",
]
var total = 0; msg.Table(function(value) { total += can.onimport._parseInt(can, value[field]) })
var begin = 0; msg[cli.COLOR] = [], msg["weight"] = [], msg.Table(function(value, index) {
list.push({span: can.onimport._parseInt(can, value[field])/total*360, color: color[index%color.length], value: value})
}); return list
},
_draw: function(can, x, y, r, margin, which) { if (which == can._last) { return } can._last = which
if (can.list.length == 1) { return can.onimport.draw(can, {shape: svg.CIRCLE, points: [{x: x, y: y}, {x: x, y: y+r}], style: {fill: cli.BLUE}}) }
function pos(x, y, r, angle) { angle -= 90; return [x + r * Math.cos(angle * Math.PI / 180), y + r * Math.sin(angle * Math.PI / 180)] }
function pie(x, y, r, begin, span, color, title, cb) { can.onimport.draw(can, {shape: svg.PATH, style: kit.Dict(
svg.STROKE, color, svg.FILL, color, "d", can.base.joins([
["M", x, y], ["L"].concat(pos(x, y, r, begin)), ["A", r, r, "0", span>180? "1": "0", "1"].concat(pos(x, y, r, begin+span)), ["Z"] ["M", x, y], ["L"].concat(pos(x, y, r, begin)), ["A", r, r, "0", span>180? "1": "0", "1"].concat(pos(x, y, r, begin+span)), ["Z"]
], lex.SP, mdb.FS), ], ice.SP, ice.FS),
), onmouseenter: function(event) { can.base.isFunc(cb) && cb(event) } }) } }, onmouseenter: function(event) {
can.onmotion.clear(can, can.ui.svg), can.ui.svg.Value(mdb.COUNT, 0) can.base.isFunc(cb) && cb(event)
var begin = 0; can.core.Next(can.list, function(item, next, index) { var p = index==which? pos(x, y, 1*margin, begin+item.span/2): [x, y] } }) }
pie(p[0], p[1], r, begin, item.span, item.color, item.name||item.command, function(event) { can.onimport._draw(can, x, y, r, margin, can.db.which = index) }), begin += item.span
index == which && (can.db.current = item.value)
can.onmotion.select(can, can.ui.table, html.TR, index), can.Status(item.value), can.onmotion.delay(can, next, can.db.delay)
}, function() {
can.onmotion.select(can, can.ui.table, html.TR, which), can.Status(can.db.current), can.db.delay = 0
})
},
_parseInt: function(can, value) { value = value.toLowerCase()
if (can.base.endWith(value, "m")) { return parseInt(value)*1000000 }
if (can.base.endWith(value, "g")) { return parseInt(value)*1000000000 }
if (can.base.endWith(value, "gi")) { return parseInt(value)*1000000000 }
if (can.base.endWith(value, "mi")) { return parseInt(value)*1000000 }
return parseInt(value)
},
layout: function(can) { if (!can.ui || !can.ui.svg) { return }
can.onmotion.hidden(can, can.ui.project), can.onmotion.hidden(can, can.ui.display), can.onmotion.toggle(can, can.ui.profile, true)
var _width = can.base.Max(can.ConfWidth()-can.ConfHeight(), 600, 200)
can.page.style(can, can.ui.profile, html.HEIGHT, can.ConfHeight(), html.WIDTH, _width, html.FLEX, "0 0 "+(_width)+"px")
var width = can.ConfWidth()-_width, height = can.ConfHeight()-4, margin = 40, r = can.base.Max(height, width)/2-1*margin-margin
can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, width)
can.ui.svg.Val(html.WIDTH, width), can.ui.svg.Val(html.HEIGHT, height)
can._draw = function(which) { can.onimport._draw(can, width/2-margin/2, height/2-margin/2, r, margin, which) }, can._draw(can.db.which||0)
return
var height = can.base.Max(can.ConfHeight(), can.ConfWidth()/2), margin = 10, r = height/2-1*margin-margin var total = 0; msg.Table(function(value) { total += parseInt(value[field]) })
can.page.style(can, can.ui.display, html.WIDTH, can.ConfWidth()-height-1), can.ui.svg.Val(html.HEIGHT, height), can.ui.svg.Val(html.WIDTH, height) var color = [cli.RED, cli.YELLOW, cli.GREEN, cli.CYAN, cli.BLUE, cli.PURPLE, cli.WHITE, cli.BLACK]
can._draw = function(which) { can.onimport._draw(can, height/2-margin/2, can.ConfHeight()/2-margin/2, r, margin, which) }, can._draw(can.db.which||0) var begin = 0; msg["color"] = [], msg["weight"] = [], msg.Table(function(value, index) { var span = parseInt(value[field])/total*360
can.page.style(can, can._output, html.HEIGHT, can.ConfHeight(), html.WIDTH, can.ConfWidth()) var p = index==which? pos(x, y, margin, begin+span/2): [x, y]; index == which && can.Status(value)
var c = color[index%color.length]; pie(p[0], p[1], r, begin, span, c, function(event) {
if (index == can._last) { return } can._last = index
can.onmotion.clear(can, can.svg), can.svg.Value("count", 0)
can.onimport._draw(can, msg, field, x, y, r, margin, index)
can.onimport._profile(can, event.target)
}), begin += span, msg.Push("color", '<span style="background-color:'+c+'"> </span>')
msg.Push("weight", parseInt(parseInt(value[field])*10000/total)/100+"%")
})
}, },
}) })

View File

@ -1,3 +0,0 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg) {
msg.Dump(can)
}})

9
plugin/story/spide.css Normal file
View File

@ -0,0 +1,9 @@
fieldset.draw.spide div.output {
font-family:monospace;
}
fieldset.draw.spide div.output div.toggle {
display:none;
}
fieldset.inner.float div.output {
background-color:#332f1ecf;
}

191
plugin/story/spide.js Normal file
View File

@ -0,0 +1,191 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
if (msg.Length() == 0) { return }
can._args = can.base.Copy({root: "ice", field: msg.append[0], split: ice.PS}, can.base.ParseURL(can._display))
can.dir_root = msg.Option(nfs.DIR_ROOT)||can._args.root||""
can._tree = can.onimport._tree(can, msg.Table(), can._args.field, can._args.split)
if (!can._tree[""]) { return }
can._tree[""].name = can._args.root
can.size = 30, can.margin = 30
can.require(["/plugin/local/wiki/draw.js", "/plugin/local/wiki/draw/path.js"], function() {
can.page.ClassList.add(can, can._fields, "draw")
can.onimport._show(can, msg), can.onmotion.hidden(can, can.ui.project)
var p = can.Action(ice.VIEW, can.sup.view||can.Action(ice.VIEW))
can.onaction[p](event, can, p)
})
},
_tree: function(can, list, field, split) {
var node = {}; can.core.List(list, function(item) { if (!item[field]) { return }
can.core.List(can.base.trimPrefix(item[field], can.dir_root+can._args.split).split(split), function(value, index, array) {
var last = array.slice(0, index).join(split)||"", name = array.slice(0, index+1).join(split)
if (!value || node[name]) { return }
node[last] = node[last]||{name: last, meta: {}, list: []}
node[last].list.push(node[name] = {
name: value+(index==array.length-1? "": split),
meta: item, list: [], last: node[last],
file: item[field]||item.file, hide: true,
})
})
})
return node
},
_height: function(can, tree, deep) { if (!tree) { return 0 }
tree.deep = deep||0
if (tree.list.length == 0 || tree.hide) { return tree.height = 1 }
var height = 0; can.core.List(tree.list, function(item) {
height += can.onimport._height(can, item, (deep||0)+1)
})
return tree.height = height
},
_width: function(can, tree, deep) { if (!tree) { return 0 }
tree.deep = deep||0
if (tree.list.length == 0 || tree.hide) {
tree.view = can.onimport.draw({}, can, {shape: html.TEXT, point: [{x: 0, y: 0}], style: {inner: tree.name}})
return tree.width = tree.view.Val("textLength")+can.margin
}
var width = 0; can.core.List(tree.list, function(item) {
width += can.onimport._width(can, item, (deep||0)+1)
})
return tree.width = width
},
_color: function(can, tree) {
return tree.meta&&tree.meta.color || (tree.list == 0? cli.PURPLE: cli.YELLOW)
},
}, [""])
Volcanos("onaction", {help: "用户操作", list: ["编辑", [ice.VIEW, "横向", "纵向"], "生成图片"],
"编辑": function(event, can) {
can.onmotion.toggle(can, can._action)
can.onmotion.toggle(can, can._status)
},
"横向": function(event, can) {
can.onimport._height(can, can._tree[""])
can.sup.view = "横向", can.onmotion.clear(can, can.svg)
can.svg.Val(html.HEIGHT, can._tree[""].height*can.size+2*can.margin)
can.width = 0, can.onaction._draw_horizontal(can, can._tree[""], can.margin, can.margin)
can.svg.Val(html.WIDTH, can.width+can.margin)
},
"纵向": function(event, can) {
can.onimport._width(can, can._tree[""])
can.sup.view = "纵向", can.onmotion.clear(can, can.svg)
can.svg.Val(html.WIDTH, can._tree[""].width+2*can.margin)
can.height = 0, can.onaction._draw_vertical(can, can._tree[""], can.margin, can.margin+can.size)
can.svg.Val(html.HEIGHT, can.height+can.margin)
},
"生成图片": function(event, can) {
can.user.toPNG(can, "hi.png", can.svg.outerHTML, can.svg.Val(html.HEIGHT), can.svg.Val(html.WIDTH))
},
_draw: function(can, tree, x, y, style) {
var color = can.onimport._color(can, tree)
tree.view = can.onimport.draw({}, can, {
shape: html.TEXT, point: [{x: x, y: y}], style: can.base.Copy({
stroke: color, fill: color, "text-anchor": "start", inner: tree.name||tree.file,
}, style),
}), can.core.ItemCB(can.ondetail, tree.view, can, tree)
},
_draw_vertical: function(can, tree, x, y) { tree.x = x, tree.y = y
can.onaction._draw(can, tree, x+tree.width/2, y, {"text-anchor": "middle"})
tree.height = can.size
if (y+tree.height > can.height) { can.height = y+tree.height }
if (tree.hide) { return }
var offset = 0; can.core.List(tree.list, function(item) {
can.onimport.draw({}, can, {shape: "path2v", point: [
{x: x+tree.width/2, y: y+tree.height-can.margin/2},
{x: x+offset+item.width/2, y: y+tree.height+can.margin/2},
], style: {stroke: cli.CYAN}})
can.onaction._draw_vertical(can, item, x+offset, y+tree.height+can.margin)
offset += item.width
})
},
_draw_horizontal: function(can, tree, x, y) { tree.x = x, tree.y = y
can.onaction._draw(can, tree, x, y+tree.height*can.size/2, {"text-anchor": "start"})
tree.width = tree.view.Val("textLength")||(tree.name||"").length*10
if (x+tree.width > can.width) { can.width = x+tree.width }
if (tree.hide) { return }
var offset = 0; can.core.List(tree.list, function(item) {
can.onimport.draw({}, can, {shape: "path2h", point: [
{x: x+tree.width+can.margin/8, y: y+tree.height*can.size/2},
{x: x+tree.width+can.margin*2-2*can.margin/8, y: y+offset+item.height*can.size/2}
], style: {stroke: cli.CYAN}})
can.onaction._draw_horizontal(can, item, x+tree.width+2*can.margin, y+offset)
offset += item.height*can.size
})
},
})
Volcanos("ondetail", {help: "用户交互", list: [],
onmouseenter: function(event, can, tree) { var y = tree.y+tree.height*can.size/2
can.page.Remove(can, can.pos), can.pos = can.onimport.draw({}, can, {
shape: svg.RECT, point: [
{x: tree.x-can.margin/4, y: y-can.size/2},
{x: tree.x+tree.width+can.margin/8, y: y+can.size/2},
], style: {stroke: cli.RED, fill: html.NONE},
}), can.onkeymap.prevent(event)
},
onclick: function(event, can, tree) {
if (tree.list.length > 0 || tree.tags || tree.name.endsWith(can._args.split)) {
return tree.hide = !tree.hide, can.onaction[can.Action(ice.VIEW)](event, can)
}
for (var node = tree; node; node = node.last) {
can.request(event, node.meta)
}
var msg = can.request(event, can.Option())
can.run(event, can.base.Obj(can._args.prefix, []).concat([can.Option("repos")||"", tree.file||"", tree.name]), function(msg) {
if (msg.Length() == 0) {
return can.ondetail.plugin(can, tree, {}, "web.code.inner", [can.dir_root, tree.file, tree.line], [ctx.ACTION, "inner"])
}
if (msg.Append(mdb.INDEX)) { msg.Table(function(value) {
can.ondetail.plugin(can, tree, value, value.index, [], [ctx.ACTION, ice.RUN, value.index])
}); return }
tree.tags = true
if (msg.Option("split")) {
tree.list = can.onimport._tree(can, msg.Table(), msg.Option("field")||msg.append[0], msg.Option("split"))[""].list||[]
can.core.List(tree.list, function(item) { item.last = tree })
} else {
msg.Table(function(item) { tree.list.push({
type: "tags", name: item.name||item.file||item[msg.append[0]],
meta: item, list: [], last: tree,
file: item.file, line: item.line, hide: true,
}) })
}
tree.hide = !tree.hide, can.onaction[can.Action(ice.VIEW)](event, can)
}, true)
},
plugin: function(can, tree, value, index, args, prefix) {
for (var node = tree; node; node = node.last) {
can.base.Copy(value, node.meta)
}
can.onappend.plugin(can, can.base.Copy({type: chat.FLOAT, index: index, args: args}, value), function(sub) {
sub.run = function(event, cmds, cb) { var msg = can.request(event)
can.run(event, can.misc.concat(can, prefix, cmds), cb, true)
}, can.ondetail.figure(can, sub)
})
},
figure: function(can, sub, msg, cb) {
can.getActionSize(function(left, top, width, height) { left = left||0
var top = 120, margin = 20; if (can.user.isMobile) { margin = 0
top = can.user.isLandscape()? 24: 48
}
can.onmotion.move(can, sub._target, {position: html.FIXED, left: left+margin, top: top})
can.page.style(can, sub._output, html.MAX_WIDTH, width-margin*2)
sub.Conf(html.HEIGHT, height-top-2*html.ACTION_HEIGHT)
can.base.isFunc(cb) && cb(msg)
})
},
})

View File

@ -1,89 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) { can.page.requireDraw(can, function() { msg.append && can.ConfDefault({field: msg.append[0], split: nfs.PS})
can.db.count = msg.Length()
can.onmotion.toggle(can, can._action, true)
can.dir_root = can.Conf(nfs.DIR_ROOT)||msg.Option(nfs.DIR_ROOT), can._tree = can.onimport._tree(can, msg.Table(), can.Conf(mdb.FIELD), can.Conf(lex.SPLIT))
can.onaction.list = [], can.base.isFunc(cb) && cb(msg), can.onappend._status(can, msg.Option(ice.MSG_STATUS)), can.onimport.layout(can)
can.onappend.style(can, "spides")
}) },
_tree: function(can, list, field, split) { var node = {}; can.core.List(list, function(item) { can.core.List(item[field].split(split), function(value, index, array) {
var last = array.slice(0, index).join(split)||can.dir_root, name = array.slice(0, index+1).join(split)
value && !node[name] && (node[last] = node[last]||{name: last, meta: {}, list: []}).list.push(node[name] = {
name: value+(index==array.length-1? "": split), file: item.file||item[field]||item.file, hide: true, meta: item, list: [], last: node[last],
})
}) }); return node },
_height: function(can, tree) { tree.height = 0; if (tree.list.length == 0 || tree.hide) { return tree.height = 1 }
can.core.List(tree.list, function(item) { tree.height += can.onimport._height(can, item) }); return tree.height
},
_width: function(can, tree) { tree.width = 0; if (tree.list.length == 0 || tree.hide) {
return tree.width = can.onimport.draw(can, {shape: html.TEXT, points: [{x: 0, y: 0}], style: {inner: tree.name}}).Val(svg.TEXT_LENGTH)+can.margin
} can.core.List(tree.list, function(item) { tree.width += can.onimport._width(can, item) }); return tree.width },
_color: function(can, tree) {
return tree.meta.color || (tree.list == 0? cli.PURPLE: cli.YELLOW)
},
layout: function(can) {
can.ui.svg && can.ui.svg.Val(svg.FONT_SIZE, can.size = parseInt(can.Action(html.SIZE)||24)), can.margin = parseInt(can.Action(html.MARGIN)||10)
can._tree && can._tree[can.dir_root] && can.core.CallFunc(can.onaction[can.Action(html.VIEW)||"横向"], [event, can, can.Action(html.VIEW)])
},
})
Volcanos(chat.ONACTION, {list: [[html.VIEW, "横向", "纵向"], [html.SIZE, 24, 32, 48], [html.MARGIN, 10, 30, 50]],
size: function(event, can) { can.onimport.layout(can) }, margin: function(event, can) { can.onimport.layout(can) },
"横向": function(event, can, button) { can.onimport._height(can, can._tree[can.dir_root]), can.onmotion.clear(can, can.ui.svg)
can.ui.svg.Val(html.HEIGHT, can._tree[can.dir_root].height*(can.size+can.margin)+2*can.margin), can.ui.svg.Value(svg.TEXT_ANCHOR, "start")
can.onaction._draw_horizontal(can, can._tree[can.dir_root], can.margin, can.margin)
},
"纵向": function(event, can, button) { can.onimport._width(can, can._tree[can.dir_root]), can.onmotion.clear(can, can.ui.svg)
can.ui.svg.Val(html.WIDTH, can._tree[can.dir_root].width+2*can.margin), can.ui.svg.Value(svg.TEXT_ANCHOR, "middle")
can.onaction._draw_vertical(can, can._tree[can.dir_root], can.margin, can.margin+(can.size+can.margin)/2)
},
_draw: function(can, tree, x, y, style) { var color = can.onimport._color(can, tree)
tree.view = can.onimport.draw(can, {shape: html.TEXT, points: [{x: x, y: y-(can.user.isChrome? 4: 0)}], style: can.base.Copy(kit.Dict(html.INNER, tree.name||" "), style)})
tree.meta.status && tree.view.Value("class", tree.meta.status)
return can.core.ItemCB(can.ondetail, tree.view, can, tree), tree.view
},
_draw_vertical: function(can, tree, x, y) {
tree.height = can.size+can.margin, can.onaction._draw(can, tree, tree.x = x+tree.width/2, tree.y = y); if (y+tree.height > can.ui.svg.Val(html.HEIGHT)) { can.ui.svg.Val(html.HEIGHT, y+tree.height) }
var offset = 0; tree.hide || can.core.List(tree.list, function(item) {
can.onimport.draw(can, {shape: svg.PATH2V, points: [
{x: x+tree.width/2, y: y+tree.height/2-can.margin/2}, {x: x+offset+item.width/2, y: y+tree.height/2+8*can.margin-can.margin/2},
]}), can.onaction._draw_vertical(can, item, x+offset, y+tree.height+8*can.margin), offset += item.width
})
},
_draw_horizontal: function(can, tree, x, y) { var height = can.size+can.margin
tree.width = can.onaction._draw(can, tree, tree.x = x, tree.y = y+tree.height*(can.size+can.margin)/2).Val(svg.TEXT_LENGTH)||(tree.name.length*16); if (x+tree.width > can.ui.svg.Val(html.WIDTH)) { can.ui.svg.Val(html.WIDTH, x+tree.width) }
var offset = 0; tree.hide || can.core.List(tree.list, function(item) {
can.onimport.draw(can, {shape: svg.PATH2H, points: [
{x: x+tree.width+can.margin/2, y: y+tree.height*height/2-can.size/4}, {x: x+tree.width+8*can.margin-can.margin/2, y: y+offset+item.height*height/2-can.size/4}
]}), can.onaction._draw_horizontal(can, item, x+tree.width+8*can.margin, y+offset), offset += item.height*(can.size+can.margin)
})
},
})
Volcanos(chat.ONDETAIL, {
onclick: function(event, can, tree) {
if (tree.list.length > 0 || tree.name.endsWith(can.Conf(lex.SPLIT))) { return tree.hide = !tree.hide, can.onaction[can.Action(html.VIEW)||"横向"](event, can) }
for (var node = tree; node; node = node.last) { can.request(event, node.meta) }
can.run(can.request(event, can.Option()), can.base.Obj(can.Conf(lex.PREFIX), []).concat(can.Conf(ctx.ACTION)||[], [tree.file||"", tree.name]), function(msg) {
if (msg.Length() == 0) { return can.onappend._float(can, web.CODE_INNER, [can._msg.Option(nfs.DIR_ROOT), tree.file, tree.line]) }
if (msg.Append(mdb.INDEX)) {
return msg.Table(function(value) { value.style = html.FLOAT, can.onappend.plugin(can, value, function(sub) {}) })
}
can.Status(mdb.COUNT, can.db.count += msg.Length())
tree.list = can.onimport._tree(can, msg.Table(), can.Conf(mdb.FIELD), can.Conf(lex.SPLIT))[can.dir_root].list
tree.hide = false, can.onimport.layout(can)
}, true)
},
oncontextmenu: function(event, can, tree) {
can.user.carte(event, can, {}, [
wiki.PORTAL, chat.DESKTOP, chat.ADMIN, wiki.WORD, web.DREAM, web.STORE,
code.VIMER, code.STATUS, code.COMPILE, cli.RUNTIME, code.XTERM,
], function(event, button) {
if (button == web.ADMIN) {
can.onappend.plugin(can, {index: web.CHAT_IFRAME, args: [
can.misc.MergePodCmd(can, {pod: tree.file, cmd: web.ADMIN})
], title: tree.name+"."+web.ADMIN, style: html.FLOAT}, function(sub) {})
} else {
can.onappend.plugin(can, {space: tree.file, index: button, style: html.FLOAT}, function(sub) {})
}
})
},
})

View File

@ -1,23 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.onappend.style(can, [web.STATS, html.FLEX], can._output)
var FIELD = can.Conf(mdb.FIELD)||mdb.NAME, VALUE = can.Conf(mdb.VALUE)||mdb.VALUE
var list = {}, stats = {}, units = {}, trans = {}, index = {}; msg.Table(function(value) {
stats[value[FIELD]] = parseFloat(stats[value[FIELD]]||"0") + parseFloat(value[VALUE])
units[value[FIELD]] = value.units, trans[value[FIELD]] = value._trans
index[value[FIELD]] = value.index, list[value[FIELD]] = value
})
function fmts(value) { var ls = []
while (value > 0) { ls.push(value%1000)
if (ls.length == 1) { ls[0] = ls[0].toFixed(2) }
value = parseInt(value/1000)
} return ls.reverse().join(", ")
}
can.user.trans(can, trans, null, html.INPUT)
can.core.Item(stats, function(name, value) { can.page.Append(can, can._output, [{view: [[html.ITEM, name, html.FLEX]], list: [
{view: mdb.VALUE, list: [{text: can.base.trimSuffix(fmts(parseFloat(value).toFixed(2))+"", ".00")}, {text: [units[name], "", mall.UNITS]}]},
{view: [mdb.NAME, "", can.user.trans(can, name, trans[name]||null, html.INPUT)]},
], onclick: function() {
can.onappend.plugin(can, {space: list[name].space, index: index[name], style: html.FLOAT})
}}]) }), can.isCmdMode() && can.onappend.table(can, msg)
},
})

View File

@ -1,19 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) {
can.onmotion.hidden(can, can._status), cb && cb(msg), can.onimport._tabs(can, msg)
},
_tabs: function(can, msg) { can.onappend.style(can, web.STUDIO), can.onmotion.clear(can, can._action)
var margin = html.PLUGIN_MARGIN*2
msg.Table(function(value, index) { value.nick = can.user.trans(can, value.index.split(nfs.PT).pop(), value.help)
value._select = index == 0
var target = can.onimport.item(can, value, function() {
if (value._plugin) { return can.onmotion.select(can, can._output, html.FIELDSET, value._plugin._target) }
can.onappend.plugin(can, value, function(sub) { value._plugin = sub
can.onmotion.select(can, can._output, html.FIELDSET, value._plugin._target)
sub.onexport.output = function() { sub.onimport.size(sub, can.ConfHeight()-margin, can.ConfWidth()-margin, false) }
target.oncontextmenu = function(event) { sub._legend.onclick(event) }, can.onmotion.hidden(can, sub._legend)
}, can._output)
}, null, can._action); can.onappend.style(can, "cmds", target)
})
},
})

View File

@ -1,9 +0,0 @@
fieldset.studiolayout>div.output>div.layout>div.display>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.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.display>fieldset.story>form.option>div.item.sess { display:none; }
fieldset.studiolayout>div.output>div.layout>div.display>fieldset.story>div.action>div.item.full.state { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.profile>fieldset.story>div.action>div.item.full.state { display:none; }
fieldset.studiolayout>div.output>div.layout>div.layout>div.content>fieldset.story>div.action>div.item.full.state { display:none; }

View File

@ -1,19 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg) {
can.onimport.project(can, msg, aaa.SESS, function(event, sess, value) { return {
profile: {index: "web.code.redis.configs", args: sess, style: html.OUTPUT},
display: {index: "web.code.redis.shells", args: sess, style: html.OUTPUT},
content: {index: "web.code.redis.keys", args: sess},
} })
},
project: function(can, msg, key, cb) { can.ui = can.onappend.layout(can), can.onappend.style(can, "studiolayout")
msg.Table(function(value) { var hash = value[key]; value._hash = hash, value._title = hash
can.onimport.item(can, value, function(event, value, show, target) { if (value._tabs) { return value._tabs.click() }
var msg = can.request(event), list = cb(event, hash, value)
can.core.List("content,display,profile".split(","), function(field) {
list[field] && can.core.List("index,args,style,_init".split(","), function(key) { msg.Push(key, list[field][key]||"") })
}), can.onimport.tabsCache(can, value, target, msg)
})
})
},
}, [""])

4
plugin/story/trend.css Normal file
View File

@ -0,0 +1,4 @@
fieldset.draw.trend div.output div.toggle {
display:none;
}

153
plugin/story/trend.js Normal file
View File

@ -0,0 +1,153 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
if (msg.Option("branch")) { return can.onappend.table(can, msg) }
can.onappend._status(can, ["from", "commit", "total", "max", "date", "text", "add", "del"])
can.Conf(html.HEIGHT, can.Conf(html.HEIGHT)||200)
can.msg = msg, can.data = msg.Table(), can.onimport._sum(can)
can.Action(html.HEIGHT, msg.Option(html.HEIGHT)||can.user.mod.isCmd? "max": can.user.isMobile&&can.user.isLandscape()? "200": "400")
can.Action("speed", parseInt(msg.Option("speed")||"100"))
can.require(["/plugin/local/wiki/draw.js", "/plugin/local/wiki/draw/path.js"], function() {
can.page.ClassList.add(can, can._fields, "draw")
can.onimport._show(can, msg), can.onmotion.hidden(can, can.ui.project)
can.onaction[can.Action("view")](event, can)
})
},
_sum: function(can) {
var begin = "", count = 0, rest = 0, add = 0, del = 0, max = 0
can.max = 0, can.min = 0, can.list = can.core.List(can.data, function(value, index) {
var line = {
date: value[can.msg.append[0]],
text: value[can.msg.append[4]],
add: parseInt(value[can.msg.append[1]]),
del: parseInt(value[can.msg.append[2]]),
}
line.begin = rest
line.max = rest + line.add
line.min = rest - line.del
line.close = rest + line.add - line.del
begin = begin || value.date, count++
rest = line.close, add += line.add, del += line.del
if (line.max - line.min > max) { max = line.max - line.min }
if (line.max > can.max) { can.max = line.max }
if (line.min < can.min) { can.min = line.min }
return line
})
can.Status({"from": begin, "commit": count, "total": add+del, "max": max})
},
}, [""])
Volcanos("onaction", {help: "组件菜单", list: ["编辑", ["view", "趋势图", "柱状图", "数据源"], ["height", "100", "200", "400", "600", "800", "max"], ["speed", "10", "20", "50", "100"]],
"编辑": function(event, can) {
can.onmotion.toggle(can, can._action)
can.onmotion.toggle(can, can._status)
},
"趋势图": function(event, can) { var height = can.Action(html.HEIGHT)
if (height == "max") { height = can.Conf(html.HEIGHT) }
height = parseInt(height)
var space = 10, width = parseInt(can.Conf(html.WIDTH))
var step = parseInt((width-2*space) / can.list.length)
can.onmotion.clear(can, can.svg)
can.svg.Val(html.HEIGHT, height)
can.svg.Val(html.WIDTH, width)
function scale(y) { return (y - can.min)/(can.max - can.min)*(height-2*space) }
function order(index, x, y) { return {x: space+step*index+x, y: height-space-scale(y)} }
can.core.Next(can.list, function(line, next, index) { can.Status(line, ["date", "text", "add", "del"])
can.onimport.draw({}, can, {
shape: "line", point: [
order(index, step/2, line.min), order(index, step/2, line.max),
], style: {
"stroke-width": 1, "stroke": line.begin < line.close? chat.WHITE: chat.BLACK,
},
})
can.onimport.draw({}, can, {
shape: "rect", point: [
order(index, step/4, line.close), order(index, step/4*3, line.begin),
], style: can.base.Copy({"stroke-width": 1, "rx": 0, "ry": 0}, line.begin < line.close? {
"stroke": chat.WHITE, "fill": chat.WHITE,
}: {
"stroke": chat.BLACK, "fill": chat.BLACK,
}),
_init: function(view) {
can.core.ItemCB(can.ondetail, function(key, cb) {
view[key] = function(event) { cb(event, can, line) }
})
},
})
can.core.Timer(parseInt(can.Action("speed")), next)
})
},
"柱状图": function(event, can) {
var max = {}, min = {}
can.core.List(can.msg.append, function(key, which) {
can.core.List(can.data, function(value, index) {
var v = parseInt(value[key])||0; if (index == 0) {
max[key] = v, min[key] = v
return
}
if (v > max[key]) { max[key] = v }
if (v < min[key]) { min[key] = v }
})
})
var height = parseInt(can.Action(html.HEIGHT))
var space = 10, width = parseInt(can.Conf(html.WIDTH))
var step = parseInt((width-2*space) / can.list.length)
can.onmotion.clear(can, can.svg)
can.svg.Val(html.HEIGHT, height)
can.svg.Val(html.WIDTH, width)
function scale(key, y) { return (y - min[key])/(max[key] - min[key])*(height-2*space) }
function order(index, key, x, y) { return {x: space+step*index+x, y: space+scale(key, y)} }
var width = (step-4)/can.msg.append.length
can.core.List(can.msg.append, function(key, which) {
max[key] != min[key] && can.core.Next(can.data, function(line, next, index) {
var y = scale(key, parseFloat(line[key]))
y && can.onimport.draw({}, can, {
shape: "rect", point: [
order(index, key, width*which+2, 0), order(index, key, width*which+2+width, y),
], style: {
"stroke-width": 1, "stroke": chat.WHITE, "fill": chat.WHITE, "rx": 0, "ry": 0,
},
_init: function(view) {
can.core.ItemCB(can.ondetail, function(key, cb) {
view[key] = function(event) { cb(event, can, line) }
})
},
})
can.core.Timer(parseInt(can.Action("speed")), next)
})
})
},
"数据源": function(event, can) {
can.onmotion.clear(can, can.ui.display)
can.onappend.table(can, can.msg, null, can.ui.display)
can.onmotion.show(can, can.ui.display)
},
height: function(event, can) {
can.onaction[can.Action("view")](event, can)
},
speed: function(event, can) {
can.onaction[can.Action("view")](event, can)
},
})
Volcanos("ondetail", {help: "用户交互", list: [],
onmouseenter: function(event, can, line) {
can.Status(line, ["date", "text", "add", "del"])
},
})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,102 +0,0 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb) {
can.page.requireDraw(can, function() { can.base.isFunc(cb) && cb(msg)
can.Conf(html.VIEW) && can.Action(html.VIEW, can.Conf(html.VIEW))
can.onmotion.toggle(can, can._option, !can.user.isMobile)
can.onmotion.toggle(can, can._action, can.page.tagis(document.body, "body.width6"))
can.db.data = msg.Table(), can.onimport.layout(can)
})
},
_sum: function(can) { if (can.db.list) { return can.db.list }
var begin = "", count = 0, rest = 0, add = 0, del = 0, max = 0
can.max = 0, can.min = 0, can.db.list = can.core.List(can.db.data, function(value, index) {
var item = {date: value[can._msg.append[0]], text: value[can._msg.append[4]], add: parseInt(value[can._msg.append[1]]), del: parseInt(value[can._msg.append[2]]), hash: value.hash}
item.begin = rest, item.max = rest + item.add, item.min = rest - item.del, item.close = rest + item.add - item.del
begin = begin || item.date, count++, rest = item.close, add += item.add, del += item.del
if (item.max - item.min > max) { max = item.max - item.min }
if (item.max > can.max) { can.max = item.max }
if (item.min < can.min) { can.min = item.min }
return item
}), can.Status({"from": begin, "commit": count, "total": add+del, "max": max})
return can.db.list
},
_layout: function(can) { var height = can.onexport.height(can), width = parseInt(can.ConfWidth())
can.onmotion.clear(can, can.ui.svg), can.ui.svg.Val(html.HEIGHT, height), can.ui.svg.Val(html.WIDTH, width)
var margin = can.onexport.margin(can), step = parseFloat((width-2*margin) / can._msg.Length())
can.page.style(can, can._output, html.MAX_HEIGHT, "")
return {height: height, width: width, margin: margin, step: step}
},
layout: function(can) { can.db.data && can.core.CallFunc(can.onaction[can.Action(html.VIEW)], [{}, can]) },
transform: function(can, target) { target.Value("transform", "translate(0, "+parseInt(can.ConfHeight())+") scale(1, -1)") },
})
Volcanos(chat.ONACTION, {list: [[html.VIEW, "趋势图", "柱状图", "折线图", "数据源"],
[html.HEIGHT, html.HEIGHT, 100, 200, 400, 600, 800, "max"], [html.MARGIN, html.MARGIN, 10, 20, 50, 100], [html.SPEED, html.SPEED, 10, 20, 50, 100],
],
"趋势图": function(event, can) { var args = can.onimport._layout(can)
function scale(y) { return (y - can.min)/(can.max - can.min)*(args.height-2*args.margin) }
function order(index, x, y) { return {x: args.margin+args.step*index+x, y: args.height-args.margin-scale(y)} }
var black = can.onimport.group(can, cli.BLACK, kit.Dict(svg.STROKE, cli.BLACK, svg.FILL, cli.BLACK))
var white = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.WHITE, svg.FILL, cli.WHITE))
can.core.Next(can.onimport._sum(can), function(item, next, index) { can.core.Timer(can.onexport.speed(can), next), can.Status(item)
can.onimport.draw(can, {shape: svg.LINE, points: [order(index, args.step/2, item.min), order(index, args.step/2, item.max)]}, item.begin < item.close? white: black)
can.onimport.draw(can, {shape: svg.RECT, points: [order(index, args.step/4, item.close), order(index, args.step/4*3, item.begin)], style: {rx: 0, ry:0}, _init: function(target) {
can.core.ItemCB(can.ondetail, function(key, cb) { target[key] = function(event) { can.misc.Event(event, can, function(msg) { cb(event, can, item) }) } })
}}, item.begin < item.close? white: black)
})
},
"折线图": function(event, can) { var args = can.onimport._layout(can); args.step = parseFloat((args.width-2*args.margin) / (can._msg.Length()-1))
var black = can.onimport.group(can, cli.BLACK, kit.Dict(svg.STROKE, cli.BLACK, svg.FILL, cli.BLACK))
var white = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.WHITE, svg.FILL, cli.WHITE))
var group = can.getHeaderTheme() == cli.BLACK? white: black;
var color = can.core.List(can.base.Obj(can.Conf(cli.COLOR), []), function(color) { return can.onimport.group(can, color, kit.Dict(svg.STROKE, color, svg.FILL, color)) })
can.onimport.transform(can, black), can.onimport.transform(can, white), can.core.List(color, function(color) { can.onimport.transform(can, color) })
var max, min; can.core.List(can.core.List(can.base.Obj(can.Conf(mdb.FIELD), can._msg.append), function(field) {
if (can.base.isIn(field, mdb.TIME, mdb.ID)) { return } return field
}), function(field, index) { max = can.db.data[0][field], min = can.db.data[0][field]
for (var i = 1; i < can.db.data.length; i += 1) { var value = can.db.data[i][field]; if (value > max) { max = value } if (value < min) { min = value } }
max = parseFloat(can.Conf("max")||max), min = parseFloat(can.Conf("min")||min)
function order(i) { return i*args.step+args.margin } function scale(y) { return (y - min)/(max - min)*(args.height-2*args.margin)+args.margin }
for (var i = 1; i < can.db.data.length; i += 1) { can.onimport.draw(can, {shape: svg.LINE, points: [{x: order(i-1), y: scale(can.db.data[i-1][field])}, {x: order(i), y: scale(can.db.data[i][field])}]}, color[index]||group) }
}), can.onappend._status(can, can._msg.Option(ice.MSG_STATUS))
var gray = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.GRAY, svg.FILL, cli.GRAY)); can.onimport.transform(can, gray)
var vline = can.onimport.draw(can, {shape: svg.LINE, points: [{x: 0, y: 0}, {x: 0, y: can.ConfHeight()}]}, gray)
var hline = can.onimport.draw(can, {shape: svg.LINE, points: [{x: 0, y: 0}, {x: can.ConfWidth(), y: 0}]}, gray)
can.ui.svg.onmousemove = function(event) { var p = can._output.getBoundingClientRect(); p = {x: event.clientX - p.x, y: event.clientY - p.y}
vline.Val("x1", p.x), vline.Val("x2", p.x), hline.Val("y1", can.ConfHeight()-p.y), hline.Val("y2", can.ConfHeight()-p.y)
var item = can.db.data[parseInt((p.x - args.margin)/args.step)]
item && can.Status(item), can.Status("cursor", parseInt((can.ConfHeight()-p.y-args.margin)/(can.ConfHeight()-2*args.margin)*max))
}
},
"柱状图": function(event, can) { var args = can.onimport._layout(can)
var black = can.onimport.group(can, cli.BLACK, kit.Dict(svg.STROKE, cli.BLACK, svg.FILL, cli.BLACK))
var white = can.onimport.group(can, cli.WHITE, kit.Dict(svg.STROKE, cli.WHITE, svg.FILL, cli.WHITE))
var group = can.getHeaderTheme() == cli.BLACK? black: white
can.onimport.transform(can, black), can.onimport.transform(can, white)
can.core.List(can.base.Obj(can.Conf(mdb.FIELD), can._msg.append), function(field) { var max = can.db.data[0][field], min = can.db.data[0][field]
for (var i = 1; i < can.db.data.length; i += 1) { var value = can.db.data[i][field]; if (value > max) { max = value } if (value < min) { min = value } }
function order(i) { return i*args.step+args.margin } function scale(y) { return (y - min)/(max - min)*(args.height-2*args.margin)+args.margin }
can.core.Next(can.db.data, function(item, next, i) { can.core.Timer(can.onexport.speed(can), next)
can.onimport.draw(can, {shape: svg.RECT, style: {rx: 0, ry: 0}, points: [{x: order(i)+args.step/8.0, y: args.margin}, {x: order(i)+args.step/8.0*7, y: scale(item[field])}], _init: function(target) {
can.core.ItemCB(can.ondetail, function(key, cb) { target[key] = function(event) { can.misc.Event(event, can, function(msg) { cb(event, can, item) }) } })
}}, group)
})
})
},
"数据源": function(event, can) { can.onmotion.clear(can), can.onappend.table(can, can._msg) },
height: function(event, can) { can.onimport.layout(can) },
margin: function(event, can) { can.onimport.layout(can) },
speed: function(event, can) { can.onimport.layout(can) },
})
Volcanos(chat.ONDETAIL, {
onmouseenter: function(event, can, item) { can.Status(item) },
onclick: function(event, can, item) { can.run(can.request(event, item, can.Option()), [mdb.DETAIL], function(msg) {
msg.Append(ctx.STYLE, html.FLOAT), can.sup.onimport._field(can.sup, msg)
}) },
})
Volcanos(chat.ONEXPORT, {list: ["from", "commit", "total", "max", "date", "text", "add", "del"],
height: function(can) {
var height = can.onexport.action_value(can, html.HEIGHT, can.ConfHeight())
return can.base.Min(height, 200, can.ConfHeight())
},
margin: function(can) { return parseInt(can.onexport.action_value(can, html.MARGIN, 10)) },
speed: function(can) { return parseInt(can.onexport.action_value(can, html.SPEED, 10)) },
})

48
plugin/story/video.js Normal file
View File

@ -0,0 +1,48 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.onimport.select(can, msg)
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
can.onappend.table(can, msg), can.onappend.board(can, msg)
can.core.Timer(12000, function() { can.onaction.play(event, can) })
can.page.Select(can, can._output, "td a", function(a) {
can.page.Modify(can, a, {target: ""})
})
},
select: function(can, msg) {
msg.Clear(), can.page.Select(can, document.body, can.Option("tags"), function(a, index) {
msg.Push(mdb.INDEX, index)
msg.Push(mdb.NAME, a.innerText)
msg.Push(mdb.LINK, a.href)
a.href == location.href && can.core.Timer(100, function() {
can.page.Select(can, can._output, html.TR, function(tr, i) {
i-1 == index && can.page.ClassList.add(can, tr, "select")
})
})
})
msg.Option(ice.MSG_STATUS, JSON.stringify([
{name: "time", value: can.base.Time(null, "%y-%m-%d %H:%M:%S")},
{name: "count", value: msg.Length()},
]))
},
})
Volcanos("onaction", {help: "控件交互", list: [],
next: function(event, can) { var msg = can._msg
msg.Table(function(line, index) {
if (line.link == location.href) {
location.href = msg.link[index+1]
}
})
},
play: function(event, can) {
can.page.SelectAll(can, document.body, html.VIDEO, function(video) {
video.playbackRate = parseFloat(can.Option("rate"))
video.currentTime = parseInt(can.Option("skip"))
video.ontimeupdate = function(event) {
if (video.currentTime > parseInt(can.Option("next"))) {
can.onaction.next(event, can)
}
}, video.play(), video.requestFullscreen()
})
},
})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -1,81 +0,0 @@
Volcanos(chat.ONIMPORT, {
_init: function(can, msg, cb) { can.ui = can.onappend.layout(can)
can.page.requireDraw(can, function() { can.db.delay = 50, can.onappend.style(can, "pie"), can.onaction.list = []
can.list = can.onimport._data(can, msg, can.Conf(mdb.FIELD)||msg.append[1]||mdb.VALUE)
can.core.List(can.list, function(item) { msg.Push("weight", item.value.weight = parseInt(item.span*100/360)+"%").Push(cli.COLOR, '<span style="background-color:'+item.color+'"> </span>') })
can.onappend.table(can, msg, null, can.ui.profile), can.page.Select(can, can.ui.profile, html.TR, function(tr, index) { can.ui.table = tr.parentNode
can.page.Modify(can, tr, {onmouseenter: function(event) { can._draw(can.db.which = index-1) }})
}), can.base.isFunc(cb) && cb(msg), can.onappend._status(can, msg.append)
})
},
_data: function(can, msg, field) { var list = []
var color = [
"#8085e9",
"#95a2ff",
"#73abf5",
"#3cb9fc",
"#0082fc",
"#87e885",
"#90ed7d",
"#22ed7c",
"#05f8d6",
"#cb9bff",
"#bf19ff",
"#f47a75",
"#fa8080",
"#f7a35c",
"#ffc076",
"#f9e264",
"#fae768",
"#5f45ff",
"#02cdff",
"#0090ff",
"#854cff",
"#09b0d3",
"#1d27c9",
"#765005",
"#314976",
"#009db2",
"#024b51",
"#0780cf",
]
var total = 0; msg.Table(function(value) { total += can.onimport._parseInt(can, value[field]) })
var begin = 0; msg[cli.COLOR] = [], msg["weight"] = [], msg.Table(function(value, index) {
list.push({span: can.onimport._parseInt(can, value[field])/total*360, color: color[index%color.length], value: value})
}); return list
},
_draw: function(can, x, y, r, margin, which) { if (which == can._last) { return } can._last = which
if (can.list.length == 1) { return can.onimport.draw(can, {shape: svg.CIRCLE, points: [{x: x, y: y}, {x: x, y: y+r}], style: {fill: cli.BLUE}}) }
function pos(x, y, r, angle) { angle -= 90; return [x + r * Math.cos(angle * Math.PI / 180), y + r * Math.sin(angle * Math.PI / 180)] }
function pie(x, y, r, begin, span, color, title, cb) { can.onimport.draw(can, {shape: svg.PATH, style: kit.Dict(
svg.STROKE, color, svg.FILL, color, "d", can.base.joins([
["M", x, y], ["L"].concat(pos(x, y, r, begin)), ["A", r, r, "0", span>180? "1": "0", "1"].concat(pos(x, y, r, begin+span)), ["Z"]
], lex.SP, mdb.FS),
), onmouseenter: function(event) { can.base.isFunc(cb) && cb(event) } }) }
can.onmotion.clear(can, can.ui.svg), can.ui.svg.Value(mdb.COUNT, 0)
var begin = 0; can.core.Next(can.list, function(item, next, index) { var p = index==which? pos(x, y, 1*margin, begin+item.span/2): [x, y]
if (item.value.name == "rest") { return can.onmotion.delay(can, next, can.db.delay) }
pie(p[0], p[1], r, begin, item.span, item.color, item.name||item.command, function(event) { can.onimport._draw(can, x, y, r, margin, can.db.which = index) }), begin += item.span
index == which && (can.db.current = item.value)
can.onmotion.select(can, can.ui.table, html.TR, index), can.Status(item.value), can.onmotion.delay(can, next, can.db.delay)
}, function() {
can.onmotion.select(can, can.ui.table, html.TR, which), can.Status(can.db.current), can.db.delay = 0
})
},
_parseInt: function(can, value) { value = value.toLowerCase()
if (can.base.endWith(value, "m")) { return parseInt(value)*1000000 }
if (can.base.endWith(value, "g")) { return parseInt(value)*1000000000 }
if (can.base.endWith(value, "gi")) { return parseInt(value)*1000000000 }
if (can.base.endWith(value, "mi")) { return parseInt(value)*1000000 }
return parseInt(value)
},
layout: function(can) { if (!can.ui || !can.ui.svg) { return }
can.onmotion.hidden(can, can.ui.project), can.onmotion.hidden(can, can.ui.display), can.onmotion.toggle(can, can.ui.profile, true)
var _width = can.base.Max(can.ConfWidth()-can.ConfHeight(), 600, 200)
can.page.style(can, can.ui.profile, html.HEIGHT, can.ConfHeight(), html.WIDTH, _width, html.FLEX, "0 0 "+(_width)+"px")
var width = can.ConfWidth()-_width, height = can.ConfHeight()-4, margin = 40, r = can.base.Max(height, width)/2-1*margin-margin
can.page.style(can, can.ui.content, html.HEIGHT, can.ConfHeight(), html.WIDTH, width)
can.ui.svg.Val(html.WIDTH, width), can.ui.svg.Val(html.HEIGHT, height)
can._draw = function(which) { can.onimport._draw(can, width/2-margin/2, height/2-margin/2, r, margin, which) }, can._draw(can.db.which||-1)
},
})

View File

@ -1,602 +1,16 @@
Volcanos(chat.ONIMPORT, { Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, cb, target) {
_init: function(can, msg, target, cb) { can.onmotion.clear(can)
if (can.Mode() == html.ZONE) { return can.onimport._vimer_zone(can, msg, target), cb && cb(msg) } can.onappend.table(can, msg)
if (msg.index && msg.meta && msg.list) { return cb && cb(msg), can.sup.onimport._field(can.sup, msg) } can.onappend.board(can, msg)
can.page.ClassList.del(can, can._fields, html.FORM), can.page.ClassList.del(can, can._fields, html.OUTPUT) can.onmotion.story.auto(can)
if (can.isCmdMode() && can.Conf(ctx.STYLE) == html.FORM) { can.page.ClassList.add(can, can._fields, html.FORM), can.onappend.style(can, html.OUTPUT) } can.base.isFunc(cb) && cb(msg)
var cbs = can.onimport[can.Conf(ctx.STYLE)||msg.Option(ctx.STYLE)]; if (can.base.isFunc(cbs)) {
can.onappend.style(can, can._args[ctx.STYLE], target), can.core.CallFunc(cbs, {can: can, msg: msg, target: target})
} else {
can.onappend.table(can, msg, null, target), can.onappend.board(can, msg, target), can.onmotion.story.auto(can, target)
} cb && cb(msg)
},
card: function(can, msg, target, filter) { target = target||can.ui.content||can._output
can.page.Append(can, target, msg.Table(function(value) { if (filter && filter(value)) { return }
var img = can.misc.ResourceIcons(can, value.icon = value.icons||value.icon||value.image)
return {view: [[html.ITEM, value.type, value.status, "s-"+value.name]], list: [
{view: [wiki.TITLE, html.DIV], list: [
img && {className: can.base.contains(img, ".jpg")? "jpg": "", img: img},
{view: wiki.TITLE, list: [{text: value.name}, value.exists == "true" && {text: ["●", "", "exists"]}, can.onappend.label(can, value)]},
]}, {view: [wiki.CONTENT, html.DIV, value.text]},
{view: html.ACTION, inner: value.action, _init: function(target) { can.onappend.mores(can, target, value, html.CARD_BUTTON)
can.page.Select(can, target, html.INPUT, function(target) { can.onappend.style(can, target.name, target) })
}},
]}
})), can.onimport.layout = can.onimport.layout||function() {
var height = can.onlayout.expand(can, target); can.sup.onexport.outputMargin = function() { return height }
can.onmotion.delay(can, function() { can.onlayout.expand(can, target) })
}
},
icon: function(can, msg, target, cb) { msg.Table(function(value) {
var icon = can.misc.Resource(can, value.icons||value.icon||can.page.drawText(can, value.name, 80), value.space||msg.Option(ice.MSG_USERPOD), msg.Option(ice.MSG_USERWEB))
return can.page.Append(can, target, [{view: [[html.ITEM, value.status]], list: [{view: html.ICON, list: [{img: icon}]}, {view: [mdb.NAME, "", value.name]}], _init: function(target) {
cb && cb(target, value)
}, onclick: function(event) { can.sup.onexport.record(can.sup, value.name, mdb.NAME, value) }}])._target
}) },
_icon: function(can, name, button, target) {
var _icon = can.page.icons(can, name) || (can.page.unicode[name] && {text: [can.page.unicode[name]||name, html.SPAN, [html.ICON, name]]})
if (!_icon) { return }
_icon.onclick = function(event) { can.base.isFunc(button)? button(event, button): can.onaction[button](event, can, button), can.onkeymap.prevent(event) }
can.page.Append(can, target, [_icon])
},
_vimer_zone: function(can, msg, target) { msg.Table(function(value) { value._select = value.name == can.Conf("_select")
can.onimport.item(can, value, function(event) { can.sup.onexport.record(can, value.name, mdb.NAME, value, event, event.currentTarget||event.target) })
}) },
_zone_icon: function(can, msg, zone, cb) {
var action = can.core.List(can.Conf(ctx.INPUTS), function(item) { if (item.type == html.BUTTON && [ice.LIST, ice.BACK].indexOf(item.name) == -1) { return item.name } })
var _menu = shy({}, action.concat(can.base.Obj(msg.Option(ice.MSG_ACTION), [])), function(event, button, meta, carte) {
cb? cb(event, button): can.Update(event, [ctx.ACTION, button]), carte.close() })
if (_menu.list.length == 0) {
zone._icon(kit.Dict(web.REFRESH, function(event) { zone.refresh() }))
return
}
zone._icon(kit.Dict(web.REFRESH, function(event) { zone.refresh() }, "menu", function() { can.user.carte(event, can, _menu.meta, _menu.list, _menu) }))
},
_zone: function(can, zone, index, field, hash) { zone._delay_init = function() { can.onimport.plug(can, can.base.isObject(index)? index: {
index: index, style: html.OUTPUT, mode: mdb.ZONE, field: field, _select: hash[2] == zone.name? hash[1]: "",
}, function(sub) { sub.run = function(event, cmds, cb) { can.runActionCommand(can.request(event, {mode: mdb.ZONE}), index.index||index, cmds, cb) }
sub.onexport.output = function(_sub, msg) { can.onimport._zone_icon(sub, msg, zone), zone._total(msg.Length())
sub.onimport.size(sub, zone._target.offsetHeight, zone._target.offsetWidth, false), can.page.style(can, sub._output, html.MAX_HEIGHT, "", html.HEIGHT, "")
can.user.toastSuccess(can)
}, can.ui.zone[zone.name].refresh = function() { sub.Update() }
sub.onimport._field = function(msg) {
msg.Table(function(value) { var pod = msg.Option(ice.MSG_USERPOD), cmd = value._command||value.index, args = can.base.Obj(value.args, [])
can.onimport.tabview(can, "", cmd == chat.IFRAME && args.length > 0? args[0]: "/s/"+pod+"/c/"+cmd, web.SPACE, function(msg) {
can.page.SelectOne(can, msg._tab, html.SPAN, function(target) { can.page.Modify(can, target, value.title||can.core.Keys(pod, cmd)) })
})
})
}
sub.onimport._open = function(msg, arg) { can.onimport.tabview(can, "", arg, web.SPACE, function(msg) {}) }
sub.onexport.record = function(sub, value, key, item, event, target) { can.onimport.tabview(can, "", value, zone.name, function(msg) {
can.onappend.style(can, [item.type, item.status], msg._tab)
msg._item = target
}) }
}, zone._target) } },
zone: function(can, list, target) { target = target||can.ui.project
return can.page.Append(can, target, can.core.List(list, function(zone) { can.base.isString(zone) && (zone = {name: zone}); if (!zone) { return }
zone._layout = function() { var height = target.offsetHeight, count = 0
can.page.SelectChild(can, target, "", function(target) {
can.page.SelectChild(can, target, html.DIV_ITEM, function(target) { height -= target.offsetHeight })
can.page.SelectChild(can, target, html.DIV_ACTION, function(target) { height -= target.offsetHeight })
can.page.SelectChild(can, target, html.DIV_LIST, function(target) { count += can.page.isDisplay(target)? 1: 0 })
})
count && can.page.SelectChild(can, target, "", function(target) {
can.page.SelectChild(can, target, html.DIV_LIST, function(target) {
can.page.style(can, target, html.HEIGHT, can.page.isDisplay(target)? can.base.Min(height/count, 180): "")
})
})
}
return {view: [[html.ZONE, zone.name]], list: [
{view: html.ITEM, list: [{text: can.user.trans(can, zone.name)}], _init: function(target) { zone._legend = target }, onclick: function() {
if (zone._delay_init) { zone._delay_init(zone._target, zone), delete(zone._delay_init) } zone.toggle(), zone._toggle && zone._toggle(zone)
}, oncontextmenu: function(event) { var menu = zone._menu
menu? can.user.carteRight(event, can, menu.meta, menu.list||can.core.Item(menu.meta), can.base.isFunc(menu)? menu: function(event, button, meta, carte) {
can.runAction(event, button), carte.close()
}): can.onmotion.clearCarte(can)
}},
{view: html.ACTION, _init: function(target) { var value; zone._action = target
can.onappend._action(can, [{type: html.TEXT, name: mdb.SEARCH, icon: icon.SEARCH, _init: function(target) { zone._search = target }, onkeyup: function(event) { value = event.target.value
can.page.Select(can, zone._target, html.DIV_EXPAND, function(target) { can.page.ClassList.set(can, target, cli.OPEN, value != "") })
can.page.Select(can, zone._target, html.DIV_LIST, function(item) { can.onmotion.toggle(can, item, value != "") })
can.onmotion.delayOnce(can, function() { value && can.onkeymap.selectItems(event, can, zone._target) }, value.length<3? 500: 150)
}}], target, {})
}},
{view: html.LIST, _init: function(target) { can.ui.zone = can.ui.zone||{}, can.ui.zone[zone.name] = zone, zone._target = target
zone._total = function(total) { return can.page.Modify(can, zone._search, {placeholder: "search in "+total+" items"}), total }
zone._icon = function(list) { can.page.Select(can, zone._legend, html.SPAN_ICON, function(target) { can.page.Remove(can, target) })
can.core.Item(list, function(name, button) { can.onimport._icon(can, name, button, zone._legend) })
}
zone.refresh = function() { can.onmotion.clear(can, target), zone._init(target, zone) }
zone.toggle = function(show) { can.onmotion.toggle(can, zone._target, show), can.onmotion.toggle(can, zone._action, show) }
can.base.isFunc(zone._init)? (zone._menu = zone._init(target, zone)||zone._menu): zone.toggle(false)
}},
]}
}))
},
_icons: function(can, item) { var icon = item.icons||item.icon||item.image
return icon && (can.base.contains(icon, ice.HTTP, ".ico", ".png", ".jpg")? {img: can.misc.Resource(can, icon)}: {icon: icon})
},
_nick: function(can, item) {
if (can.base.isArray(item.nick)) { return item.nick }
if (can.base.isObject(item.nick)) { return item.nick }
return {text: [item.nick||item.name||item.zone||item.sess, "", html.NAME], className: html.NAME}
},
_menu: function(event, can, item, cbs, target) { target = target||event.currentTarget
if (can.base.isFunc(cbs)) { var menu = cbs(event, item, target); if (menu) { return can.user.carteRight(event, can, menu.meta, menu.list, menu) } }
can.user.carteItem(event, can, item)
},
_item: function(can, item, cb, cbs) {
item._hash = item._hash||item.sess||item.hash||item.zone||item.path||item.name
item._hash && item._hash.replaceAll && (item._hash = item._hash.replaceAll(":", "_"))
item._title = item._title||item.name||item.path||item.zone||item.hash
item._select == undefined && can.db.hash[0] && (item._select = can.db.hash[0] == item._hash)
if (typeof item._hash == code.OBJECT) { item._select = true
for (var i = 0; i < item._hash.length; i++) {
if (item._hash[i] != can.db.hash[i]) { item._select = false; break }
}
}
return {view: [[html.ITEM, item.type, item.role, item.status]], title: item.title||item.nick, list: [
can.onimport._icons(can, item),
].concat(can.onimport._nick(can, item), item._label||[], [
(item.action||cbs) && {icon: "bi bi-three-dots", onclick: function(event) { can.onimport._menu(event, can, item, cbs) }},
]), _init: function(target) { target._item = item, item._item = target, can.ui[item.path] = target
item._select && can.onmotion.delay(can, function() { target.click() })
}, onclick: function(event) {
if (cb(event)) { return }
can.db.value = item, can.onexport.hash(can, item._hash)
item.__title? can.user.title(item.__title): can.onexport.title(can, item._title)
}, oncontextmenu: function(event) {
can.onimport._menu(event, can, item, cbs)
}}
},
item: function(can, item, cb, cbs, _target) {
return can.page.Append(can, _target||can.ui.project||can._output, [can.onimport._item(can, item, function(event) { var target = event.currentTarget
can.onmotion.select(can, target.parentNode, html.DIV_ITEM, target)
can.onengine.signal(can, "onproject", can.request(event, {type: "item", query: can.page.getquery(can, can._fields)+","+item.path}))
var show = target._list && can.onmotion.toggle(can, target._list); if (show === false) { return true }
return cb(event, item, show, target)
}, cbs)])._target
},
_itemselect: function(can, target) {
can.page.Select(can, can.ui.project, html.DIV_ITEM, function(target) { can.page.ClassList.del(can, target, html.SELECT) })
for (var p = target; p; p = p.parentNode.previousElementSibling) { can.page.ClassList.add(can, p, html.SELECT), can.onmotion.toggle(can, p.nextSibling, true) }
},
itemlist: function(can, list, cb, cbs, target) { if (!list || list.length == 0) { return }
if (!target) { return can.core.List(list, function(value) { can.onimport.item(can, value, cb, cbs) }) }
if (!target._list) { target._list = can.page.insertBefore(can, [html.LIST], target.nextSibling, target.parentNode) }
return can.page.Append(can, target._list, can.core.List(list, function(item) {
return can.onimport._item(can, item, function(event) { var target = event.currentTarget
if (target._list && target._list.childElementCount > 0 && target._list && can.onmotion.toggle(can, target._list) == false) { return true }
if (cb && cb(event, item, target._list && true, target)) { return }
can.onimport._itemselect(can, target)
}, cbs)
})), target._list
},
tree: function(can, list, cb, cbs, target, node, field, split) { node = node||{"": target||can.ui.project||can._output}, field = field||nfs.PATH, split = split||nfs.PS
can.core.List(list, function(item) { var key = item[field]; key && can.core.List(key.split(split), function(value, index, array) { if (!value) { return }
var last = array.slice(0, index).join(split), name = array.slice(0, index+1).join(split); if (node[name]) { return }
last && node[last] && can.page.Select(can, node[last].previousSibling, "div.expand", function(target) { target.innerHTML == "" && (target.innerHTML = can.page.unicode.closes) })
item.expand = item.expand||item._select||(can.db.hash && (can.db.hash[0] == key))
item._hash = item._hash||item.hash||item.zone||item.path||item.name
item._title = item._title||item.name||item.path||item.path||item.hash
var ui = can.page.Append(can, node[last], [{view: html.ITEM, list: [
{view: [[html.EXPAND], html.DIV, (index==array.length-1? "": can.page.unicode.closes)]},
{view: [mdb.NAME], list: [{text: [value, "", html.NAME]}].concat(item._label||[])},
item.action && {view: [mdb.ICON], list: [{icon: "bi bi-three-dots", onclick: function(event) { can.onimport._menu(event, can, item, cbs) }}]},
], onclick: function(event) { var target = event.currentTarget
if (index < array.length-1 && !can.page.ClassList.set(can, ui[html.EXPAND], cli.OPEN, !can.page.ClassList.neg(can, node[name], html.HIDE))) { return }
can.db.value = item, can.onexport.hash(can, item._hash), can.onexport.title(can, item._title)
can.onimport._itemselect(can, target), can.base.isFunc(cb) && cb(event, item, ui.item)
node[key] && can.page.ClassList.add(can, node[key].previousSibling, html.SELECT)
if (node[name].childElementCount == 2) { can.onmotion.delay(can, function() { node[name].firstChild.click() }) }
}, oncontextmenu: function(event) {
can.onimport._menu(event, can, item, cbs)
}, ondragenter: function(event) {
can.onkeymap.prevent(event)
}, ondragover: function(event) {
can.onkeymap.prevent(event)
}, ondrop: function(event) {
var msg = can.request(event, can.Option(), item, {_handle: ice.TRUE})
can.core.List(event.dataTransfer.files, function(file) {
debugger
msg._upload = file
can.runAction(event, html.UPLOAD, [], function(msg) {
})
})
// msg._upload = event.dataTransfer.files[0]
can.onkeymap.prevent(event)
}, _init: item._init}, {view: [[html.LIST, html.HIDE]]}]); node[name] = ui.list, item.expand && ui.item.click()
}) }); return node
},
tabs: function(can, list, cb, cbs, action) { action = action||can.ui.tabs||can._action; return can.page.Append(can, action, can.core.List(list, function(tabs) { if (typeof tabs == code.STRING) { tabs = {name: tabs} }
function close(target) {
if (can.page.ClassList.has(can, target, html.SELECT)) {
var next = can.page.tagis(target.nextSibling, html.DIV_TABS)? target.nextSibling: can.page.tagis(target.previousSibling, html.DIV_TABS)? target.previousSibling: null
if (!next) { return true } next && next.click()
} can.page.Remove(can, target), can.onexport.tabs && can.onexport.tabs(can)
}
return {view: [[html.TABS, tabs.type, tabs.role, tabs.status]], title: tabs.title||tabs.text, list: [].concat(
can.onimport._icons(can, tabs), can.onimport._nick(can, tabs), {icon: mdb.DELETE, onclick: function(event) { tabs._target._close(), can.onkeymap.prevent(event) }}
), onclick: function(event) {
can.onmotion.delay(can, function() { can.onmotion.scrollIntoView(can, tabs._target) })
if (can.page.ClassList.has(can, tabs._target, html.SELECT)) { return }
can.onmotion.select(can, action, html.DIV_TABS, tabs._target), can.base.isFunc(cb) && cb(event, tabs)
}, oncontextmenu: function(event) { var target = tabs._target, _action = can.page.parseAction(can, tabs)
var menu = tabs._menu||shy(function(event, button) { can.Update(event, [ctx.ACTION, button]) })
can.user.carte(event, can, kit.Dict(
"Close", function(event) { target._close() },
"Close Other", function(event) { target.click(), can.page.SelectChild(can, action, html.DIV_TABS, function(target) { target == tabs._target || target._close() }) },
"Rename Tabs", function(event) { can.user.input(event, can, [mdb.NAME], function(list) {
can.page.SelectOne(can, target, html.SPAN, function(target) { can.page.Modify(can, target, list[0]||tabs.name) })
}) }, menu.meta
), ["Close", "Close Other", "Rename Tabs", ""].concat(can.base.getValid(menu.list, can.core.Item(menu.meta)), _action), function(event, button, meta) {
(meta[button]||menu)(can.request(event, tabs), button, meta)
})
}, _init: function(target) {
action == can._action && can.page.Select(can, can._action, "div.item._space.state", function(space) { can.page.insertBefore(can, target, space) })
target._item = tabs, tabs._target = target, target._close = function() { close(target) || cbs && cbs(tabs) }, target.click()
can.page.Modify(can, target, {draggable: true,
ondragstart: function(event) { action._drop = function(before) { before.parentNode == action && action.insertBefore(target, before), can.onexport.tabs(can) } },
ondragover: function(event) { event.preventDefault(), action._drop(event.target) },
})
}}
}))._target },
tabsCache: function(can, value, target, cb) { if (value._tabs) { return value._tabs.click() }
value._tabs = can.onimport.tabs(can, [value], function() { can.page.isSelect(target) || can.onmotion.delay(can, function() { target.click() })
can.page.SelectOne(can, can._status, html.LEGEND) || can.onmotion.cache(can, function() { return value._hash }, can._status)
if (can.onmotion.cache(can, function() { return value._hash }, can.ui.content, can.ui.profile, can.ui.display)) { return can.onimport.layout(can) }
can.Status(value); if (can.base.isFunc(cb)) { return cb() } var msg = cb
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)
index == 1 && can.onappend.plugin(can, value, function(sub) {
can.onmotion.toggle(can, can.ui.display, true)
can.db.value._display_plugin = sub, can.onimport.layout(can)
}, can.ui.display)
index == 2 && can.onappend.plugin(can, value, function(sub) {
can.onmotion.toggle(can, can.ui.profile, true)
can.db.value._profile_plugin = sub, can.onimport.layout(can)
}, can.ui.profile)
can.onmotion.delay(can, function() { can.onimport.layout(can) })
can.onmotion.delay(can, function() { can.onimport.layout(can) }, 100)
can.onmotion.delay(can, function() { can.onimport.layout(can) }, 300)
}) } else { can.onappend.table(can, msg), can.onappend.board(can, msg) }
}, function() { delete(value._tabs), can.onmotion.cacheClear(can, value._hash, can.ui.content, can.ui.profile, can.ui.display) })
},
tool: function(can, list, cb, target, status) { target = target||can._status, status = status||can._status
var height = can.base.Max(html.PLUG_HEIGHT, can.ConfHeight()-3*html.ACTION_HEIGHT, 240), width = can.base.Max(html.PLUG_WIDTH, can.ConfWidth()-(can.user.isMobile? 0: html.PROJECT_WIDTH))
can.core.Next(list.reverse(), function(meta, next) { can.base.isString(meta) && (meta = {index: meta}), meta.mode = html.FLOAT
can.onimport.plug(can, meta, function(sub) {
sub.onexport.output = function() {
can.page.style(can, sub._output, html.MAX_HEIGHT, "", html.HEIGHT, "", html.WIDTH, "", html.MAX_WIDTH, "")
sub.onimport.size(sub, height, width, false), can.onmotion.delay(can, function() { sub.onimport.size(sub, height, width, false) })
}, sub.onimport.size(sub, height, width, false)
can.page.Append(can, sub._legend,[{text: [can.page.unicode.remove, "", mdb.REMOVE], onclick: function(event) {
can.page.Remove(can, sub._target), can.page.Remove(can, sub._legend), can.onexport.tool(can), can.onkeymap.prevent(event)
}}]), sub._legend._target = sub._target, sub._legend._meta = {index: meta.index}
status.appendChild(sub._legend), sub._legend.oncontextmenu = sub._legend.onclick, sub._legend.onclick = function(event) { can.misc.Event(event, can, function(msg) {
if (can.page.SelectOne(can, status, "legend.select", function(target) {
can.onmotion.hidden(can, target._target), can.page.ClassList.del(can, target, html.SELECT); return target }) == sub._legend) { return }
can.onmotion.select(can, status, html.LEGEND, sub._legend), can.onmotion.toggle(can, sub._target, true)
can.onmotion.select(can, target, html.FIELDSET_PLUG, sub._target)
sub.onimport.size(sub, sub.ConfHeight(), sub.ConfWidth(), false)
if (sub._delay_init || meta.msg) { sub._delay_init = false, meta.msg = false, (sub._inputs && sub._inputs.list || sub._inputs && sub._inputs.refresh) && sub.Update() }
}) }, sub._delay_init = true, sub.select = function(show) {
if (show && can.page.ClassList.has(can, sub._legend, html.SELECT)) { return sub }
return sub._legend.click(), sub
}, can.onmotion.hidden(can, sub._target)
sub.hidden = function() { can.onmotion.hidden(can, sub._target), can.page.ClassList.del(can, sub._legend, html.SELECT) }
sub.onaction._close = function() { can.page.Remove(can, sub._target), can.page.Remove(can, sub._legend), can.onexport.tool(can) }
sub.onaction.close = function() { sub.select() }, can.base.isFunc(cb) && cb(sub), can.onexport.tool(can)
next()
}, target)
})
},
plug: function(can, meta, cb, target, field) { if (!meta || !meta.index) { return }
meta.type = meta.type||html.PLUG, meta.name = meta.index, can.onappend.plugin(can, meta, function(sub) { sub.sup = can
sub.onaction.close = function() { can.onmotion.hidden(can, target) }, can.base.isFunc(cb) && cb(sub)
}, target, field)
},
_float: function(can, index, args) { args = args||[]
can.user.isMobile? can.user.jumps(can.misc.MergePodCmd(can, {cmd: index+"/"+args.join("/")})): can.onappend._float(can, index, args)
}, },
myOption: function(can) { var sub = can.sub; if (!sub) { return } var plugin = sub._stacks_current[0]; current = plugin.current||{} _process: function(can, msg) {
if (plugin == sub._stacks_root) { var PLACE_UID = can.core.Item(can.Option())[0] msg.Option(ice.MSG_TOAST) && can.user.toast(can, msg.Option(ice.MSG_TOAST))
if (sub._stacks_current.length == 1) { return can.core.CallFunc([can.onimport, msg.Option(ice.MSG_PROCESS)], [can, msg])
plugin.sub.onexport.hash(plugin.sub, can.Option(PLACE_UID))
} else {
plugin.sub.onexport.hash(plugin.sub, can.Option(PLACE_UID), can.ConfIndex(), can.Option(UID))
}
}
can.user.isMobile || sub._stacks_root.onexport.title(sub._stacks_root, current._name, can.ConfHelp(),
can._msg.Option("_share_title")||(can._msg && can._msg.IsDetail()? can._msg.Append(html.TITLE)||can._msg.Append(mdb.NAME)||(can._msg.Append(UID)||"").slice(0, 6): "")
// ||can.user.info.titles
)
can.user.agent.init(can,
can._msg.Option("_share_content")||(can._msg && can._msg.IsDetail()? can._msg.Append(html.CONTENT)||can._msg.Append(mdb.INFO)||"": "")||current.city_name+" "+current._street,
can._msg.Option("_share_icons")||(can.Conf(mdb.ICONS)? can.misc.Resource(can, can.Conf(mdb.ICONS)): can.user.info.nodetype == web.WORKER? can.misc.Resource(can, can.user.info.favicon, can.user.info.nodename): ""),
)
},
myField: function(can, sub) {
sub.onexport._output = function(_sub) {
_sub._stacks_current = can._stacks_current, _sub._stacks_root = can._stacks_root
can.core.Item(can.onimport, function(key, value) { _sub.onimport[key] = _sub.onimport[key]||value })
can.core.Item(can.onaction, function(key, value) { _sub.onaction[key] = _sub.onaction[key]||value })
can.core.Item(can.onexport, function(key, value) { _sub.onexport[key] = _sub.onexport[key]||value })
}
},
myPluginSelect: function(can, sub, _output) {
can.page.SelectChild(can, _output, html.FIELDSET, function(target) { can.onmotion.toggle(can, target, target == sub._target) })
can.page.SelectChild(can, sub._output, "*", function(target) { can.onmotion.toggle(can, target, true) })
can.page.style(can, sub._action, html.DISPLAY, html.NONE)
can.user.isMobile? sub.onimport.size(sub, window.innerHeight, window.innerWidth, false): sub.onimport.size(sub, sub.ConfHeight(), sub.ConfWidth(), false)
can.onimport.myOption(sub)
},
myPlugin: function(can, value, cb) {
var key = [value.space||can.ConfSpace(), value.index||can.ConfIndex()].concat(value.args||"").join(",")
var sup = can._stacks_root; sup._stacks = sup._stacks||{}; var sub = (sup._stacks[key]||[])[0]; if (sub) { return sub._select() }
var _output = sup._target.parentNode; value.height = sup.ConfHeight(), value.width = sup.ConfWidth()
value.style = html.OUTPUT
sup.onappend.plugin(can._root.Action, value, function(sub) { can.onimport.myField(can, sub)
sub.misc.localStorage(sub, [sub.ConfSpace(), sub.ConfIndex(), mdb.HASH].join(","), "")
sub.onexport.output = function(_sub, msg) { _sub._stacks_current = sup._stacks[key] = [sub], _sub._stacks_root = sup, sub._select() }
sub._select = function() { can.onimport.myPluginSelect(can, sub, _output) }, sub._select(), cb && cb(sub)
}, _output)
},
myStory: function(can, value) { var ACTION_HEIGHT = 48
if (!can._stacks_current) { var sup = can.sup; can._stacks_root = sup, sup._stacks = {}
var key = [can.ConfSpace(), can.ConfIndex()].concat(can.base.trim(can.core.Item(can.Option(), function(key, value) { return value }))).join(",")
can._stacks_current = sup._stacks[key] = [can.sup]
sup._select = function() { can.onimport.myPluginSelect(can, sup, sup._target.parentNode) }
} var plugin = can._stacks_current[0], _action = plugin._action, _output = plugin._output; current = plugin.current||{}
value.index == "web.team.renzhengshouquan.profile" && (ACTION_HEIGHT = 0)
value.index.split(".").pop() == "credit" && (ACTION_HEIGHT = 0)
value.type = html.STORY, value.style = html.OUTPUT, value.height = (can.user.isMobile? window.innerHeight: can.ConfHeight())-ACTION_HEIGHT
can.onappend.plugin(can, value, function(sub) {
can._stacks_current.push(sub)
can.core.List(["_trans", "_style", "_icons", "_trans.input", "_trans.value"], function(key) {
var value = sub.Conf(key); value && can.core.Item(can.Conf(key), function(k, v) { value[k] = value[k]||v })
})
var STREET_NAME = plugin.sub.Conf("_street_name"), PLACE_NAME = plugin.sub.Conf("_place_name")
var run = sub.run; sub.run = function(event, cmds, cb) {
run(sub.request(event, {
city_name: current[CITY_NAME], street_name: current[STREET_NAME], place_name: current[PLACE_NAME],
dashboard_uid: current["dashboard_uid"], storage_uid: current["storage_uid"],
command_uid: sub.Conf("command_uid"), portal_name: can.ConfHelp(),
}, can.base.Obj(sub.Conf("field.option"))), cmds, cb)
}
can.onimport.myField(can, sub), can.onmotion.slideIn(sub)
sub.onexport.output = function(_sub, msg) {
sub._select(), msg.Option(ice.MSG_ACTION) && can.onappend._action(sub, msg.Option(ice.MSG_ACTION), _action, null, true)
sub.sub.onaction._goback = goback
}
sub.onimport._field = function(msg) { var sup = sub
can.onmotion.clear(can, sub._output)
msg.Table(function(value) { value.style = html.OUTPUT
can.onappend.plugin(can, value, function(sub) { can.onimport.myField(can, sub)
can._stacks_current.push(sub)
sub.onexport.output = function(_sub, msg) { can.onimport.myOption(sub)
can.user.isMobile && sub.onimport.size(sub, window.innerHeight-ACTION_HEIGHT, window.innerWidth, false)
}
var run = sub.run; sub.run = function(event, cmds, cb) {
run(sub.request(event, {
city_name: current[CITY_NAME], street_name: current[STREET_NAME], place_name: current[PLACE_NAME],
dashboard_uid: current["dashboard_uid"], storage_uid: current["storage_uid"],
command_uid: sub.Conf("command_uid"), portal_name: can.ConfHelp(),
}, can.base.Obj(sub.Conf("field.option")), sup.Option()), cmds, cb)
}
}, sub._output)
})
}
function goback(event, cb) {
if (can._stacks_current.length == 1) { return cb && cb()}
if (sub._history.length > 1) { sub.request(event, {_toast: "reload"}); return sub.onimport.back(event, sub), cb && cb() }
var _last = can._stacks_current.pop()
can.onmotion.slideOut(_last, function() { var last = can._stacks_current[can._stacks_current.length-1]; last._select()
can.onmotion.delay(can, function() { can._root.Action.onlayout._init(can) })
last.request(event, {_toast: "reload"})
if (last.ConfIndex().split(".").pop() == "message") { last.Update(event) }
// can._stacks_current.length == 1 && last._output.innerHTML == "" && last.Update(event)
last._output.innerHTML == "" && last.Update(event)
cb && cb()
})
}
function reload(event) {
sub.Update(sub.request(event, {_toast: "reload"}))
}
sub._select = function() { can.onimport.myOption(sub)
can.page.SelectChild(can, _output, "*", function(target) { can.onmotion.toggle(can, target, target == sub._target) })
var list = [can.page.button(can, can.user.trans(can, "goback", "返回"), function(event) { goback(event) }), can.page.button(can, can.user.trans(can, "reload", "刷新"), function(event) { reload(event) })]
can.page.Appends(can, _action, list), can.page.style(can, _action, html.DISPLAY, html.BLOCK)
can.user.isMobile && sub.onimport.size(sub, window.innerHeight-ACTION_HEIGHT, window.innerWidth, false)
}, sub._select()
}, _output)
},
myTabs: function(can, key, list, target) { var last = can.misc.Cookie(can, key)
if (!target && !can.ui.tabs) { can.ui = can.page.Append(can, can._output, [html.TABS, html.LIST]) } target = target||can.ui.tabs
can.page.Append(can, target, can.core.List(list, function(value) {
return {text: [can.user.trans(can, value, "", "value."+key), "", [value, value == "all" && last == "" || value == last? html.SELECT: ""]], onclick: function(event) {
can.onmotion.select(can, target, "*", event.target), can.misc.Cookie(can, key, value == "all"? "": value), can.Update()
}}
}))
},
myView: function(can, msg, cb, cbs, target) {
can.onimport.itemcards(can, msg, cb, cbs, target||can.ui.list)
},
itemcards: function(can, msg, cb, cbs, target) { target = target||can.ui.list||can._output
if (msg.IsDetail()) { var value = msg.TableDetail(); msg.Show(can)
can.page.Select(can, target, html.TR, function(target) {
target.className.indexOf("_uid") > -1 && can.page.ClassList.add(can, target, "hide")
})
} else {
can.page.Append(can, target, msg.Table(function(value) {
return can.onimport.itemcard(can, value, cb(value), cbs)
})), msg.Result() && can.onappend.board(can, msg), can.onappend.style(can, msg.Option(ctx.STYLE))
}
can.page.Select(can, target, html.INPUT_BUTTON, function(target) {
var style = can.Conf("_style."+target.name); style && can.page.ClassList.add(can, target, style)
})
can.onimport.shareTitle(can, msg)
},
itemcard: function(can, value, list, cb) { if (!list) { return }
can.core.List(list, function(item) { if (!item || !item.list) { return }
for (var i = 0; i < item.list.length; i++) { if (item.list[i] && typeof item.list[i] == code.STRING) { item.list[i] = {text: item.list[i]} } }
})
cb = cb|| function(event) { var done = false
if (can.onaction.carddetail && can.onaction.carddetail(event, can, value)) { return }
if (value.uid) { return can.Option(UID, value.uid), can.Update() }
can.core.Item(can.Option(), function(k, v) {
if (!done && !v) { done = true, can.Option(k, value[k]), can.Update() }
})
}
return {view: [[html.ITEM_CARD, value._uid? "uid-"+value._uid: ""].concat(value._style||[])], list: [
{view: html.ACTION, _init: function(target) { can.page.appendAction(can, value, target)
can.user.isMobile && can.page.Select(can, target, "input.notice", function(target) { can.page.Remove(can, target) })
}},
{view: html.OUTPUT, list: [
{img: can.misc.ResourceIcons(can, value.icons||value.icon||value.avatar||
value.auth_avatar||value.command_icon||value.service_icon||value.user_avatar||can.Conf(mdb.ICONS), value.nodename,
), onclick: function(event) { can.onkeymap.prevent(event)
can.onaction.updateAvatar && can.onaction.updateAvatar(event, can)
}},
{view: html.CONTAINER, list: list},
], _init: function(target) {
value.action && can.onmotion.slideAction(can, target)
}},
], onclick: function(event) { cb && cb(event, value)
can.onmotion.select(can, event.currentTarget.parentNode, html.DIV_ITEM, event.currentTarget)
}}
},
textView: function(can, value, key, type) {
key || can.core.Item(value, function(k, v) { if (k == "status" || can.base.endWith(k, "_status")) { key = k } }); if (!type) { type = key.split("_").pop() }
return value[key] && !can.base.isIn(value[key], "finish", "done") && {text: [can.user.transValue(can, value, key), "", [type, value[key], can.Conf("_trans.value."+key+".style."+value[key])||""]]}
},
authView: function(can, value) { return can.base.isIn(value.auth_status, "issued", "2") && {view: [aaa.AUTH, html.SPAN], list: [{icon: "bi bi-patch-check-fill", style: {color: "var(--notice-bg-color)"}}]} },
timeView: function(can, value, key) {
if (key) { return {text: [can.user.trans(can, key, null, html.INPUT)+": "+can.base.TimeTrim(value[key]), "", mdb.TIME]} }
return {text: [can.base.TimeTrim(value[key]||value.browse_time||value.updated_at||value.created_at||value.time), "", mdb.TIME]}
},
unitView: function(can, value, key, unit) { if (!value[key]) { return }
return {text: [[can.user.trans(can, key, null, html.INPUT)+":", value[key]].concat(unit? [unit]: []).join(" "), "", key]}
},
typeStyle: function(can, value, key) { return can.Conf("_trans.value."+key+".style."+value[key])||"" },
roleStyle: function(can, value, key) { return can.Conf("_trans.value."+key+".style."+value[key])||"" },
shareTitle: function(can, msg, title, content, icons) { if (msg.IsDetail()) { var value = msg.TableDetail()
msg.Option("_share_title", msg.Option("_share_title")||(value[title]||value.title||value.name||value.uid).slice(0, 6))
msg.Option("_share_content", msg.Option("_share_content")||value[content]||value.content||value.info)
msg.Option("_share_icons", msg.Option("_share_icons")||value[icons]||value.icons||value.avatar)
} },
titleAction: function(can, value, filter) { var filter = can.core.List(arguments).slice(2)
return {view: html.ACTION, _init: function(target) {
if (value.Option) { return can.onappend._action(can, value.Option(ice.MSG_ACTION), target) }
can.page.appendAction(can, value, target)
can.page.Select(can, target, html.INPUT_BUTTON, function(target) {
target.value = can.user.trans(can, target.name)
if (filter.length > 0) {
filter.indexOf(target.name) == -1 && can.page.Remove(can, target)
} else {
can.page.tagis(target, "input.notice") || can.page.Remove(can, target)
}
})
}}
}, },
}) })
Volcanos(chat.ONLAYOUT, { Volcanos("onaction", {help: "控件交互", list: []})
_init: function(can, height, width) { can.core.CallFunc([can.onimport, html.LAYOUT], {can: can, height: height, width: width}) }, Volcanos("onexport", {help: "导出数据", list: []})
zone: function(can, height, width) { can.onlayout._init(can, height, width) },
result: function(can, height, width) { can.onlayout._init(can, height, width) },
simple: function(can, height, width) { can.onlayout._init(can, height, width) },
output: function(can, height, width) { can.onlayout._init(can, height, width) },
float: function(can, height, width) { can.onlayout._init(can, height, width) },
full: function(can, height, width) { can.onlayout._init(can, height, width) },
cmd: function(can, height, width) { can.onlayout._init(can, height, width) },
})
Volcanos(chat.ONEXPORT, {
title: function(can, title) { can.sup.onexport.title.apply(can.sup.onexport, [can.sup].concat(can.core.List(arguments).slice(1))) },
action_value: function(can, key, def) { var value = can.Action(key); return can.base.isIn(value, ice.AUTO, key, undefined)? def: value },
tabs: function(can) {},
tool: function(can) { can.misc.sessionStorage(can, [can.ConfIndex(), "tool"], JSON.stringify(can.page.Select(can, can._status, html.LEGEND, function(target) { return target._meta }))) },
hash: function(can, hash) { hash = typeof hash == code.STRING? hash.split(":").concat(can.core.List(arguments).slice(2)||[]): hash || can.core.Item(can.Option(), function(key, value) { return value||"" })
return can.sup.onexport.hash(can.sup, hash)
},
session: function(can, key, value) { return can.sup.onexport.session(can.sup, key, value) },
storage: function(can, key, value) { return can.sup.onexport.storage(can.sup, key, value) },
table: function(can) { var msg = can._msg; if (msg.Length() == 0) { return } var res = [msg.append && msg.append.join(mdb.FS)]
msg.Table(function(line, index, array) { res.push(can.core.Item(line, function(key, value) { return value }).join(ice.FS)) })
return res.join(lex.NL)
},
board: function(can) { var msg = can._msg; return msg.Result() },
})
Volcanos(chat.ONACTION, {
onkeydown: function(event, can) {
if (can.onkeymap.selectCtrlN(event, can, can.ui.tabs||can._action, html.DIV_TABS)) { return }
can.onkeymap._parse(event, can)
},
onslidemove: function(event, can, data, direction) {
// can.user.toast(can, [direction, data.spanX, data.spanY].join(","))
},
onslideright: function(event, can, data, direction) {
can.onaction._goback && can.onaction._goback(event)
},
onslideleft: function(event, can, data, direction) {
return
var button = can.base.Obj(can._msg.Option("_action"), [])[0]; if (!button) { return }
can.run({}, [ctx.ACTION, button].concat(can.base.trim(can.core.Item(can.Option(), function(key, value) { return value }))))
},
onslidedown: function(event, can, data, direction) {
return
var target = can.ui.list||can.ui.output||can._output
if (target.scrollTop == 0) {
can.Update(can.request(event, {_toast: "reload"}))
}
},
onslideup: function(event, can, data, direction) {
return
var target = can.ui.list||can._output
if (target.offsetHeight+target.scrollTop == target.scrollHeight) {
can.Update(can.request(event, {_toast: "reload"}))
}
},
})
Volcanos(chat.ONKEYMAP, {
escape: function(event, can) {}, enter: function(event, can) {},
ctrln: function(event, can) { can.onkeymap.selectCtrlN(event, can, can._action, html.DIV_TABS) },
space: function(event, can) { can.ui.filter && (can.ui.filter.focus(), can.onkeymap.prevent(event)) },
tabx: function(event, can) { can.page.Select(can, can._action, html.DIV_TABS_SELECT, function(target) { target._close() }) },
tabs: function(event, can) {},
_mode: {
plugin: {
Escape: shy("清理屏幕", function(event, can) { can.onkeymap.escape(event, can) }),
Enter: shy("执行操作", function(event, can) { can.onkeymap.enter(event, can) }),
" ": shy("搜索项目", function(event, can) { can.onkeymap.space(event, can) }),
f: shy("搜索项目", function(event, can) { can.ui.filter && (can.ui.filter.focus(), can.onkeymap.prevent(event)) }),
a: shy("展示项目", function(event, can) { can.ui.project && (can.onmotion.toggle(can, can.ui.project), can.onimport.layout(can)) }),
v: shy("展示预览", function(event, can) { can.ui.profile && (can.onmotion.toggle(can, can.ui.profile), can.onimport.layout(can)) }),
r: shy("展示输出", function(event, can) { can.ui.display && (can.onmotion.toggle(can, can.ui.display), can.onimport.layout(can)) }),
p: shy("添加插件", function(event, can) { can.sup.onaction["添加工具"](event, can.sup) }),
t: shy("添加标签", function(event, can) { can.onkeymap.tabs(event, can) }),
x: shy("添加标签", function(event, can) { can.onkeymap.tabx(event, can) }),
l: shy("打开右边标签", function(event, can) { can.page.Select(can, can._action, html.DIV_TABS_SELECT, function(target) {
var next = target.nextSibling; next && can.page.ClassList.has(can, next, html.TABS) && next.click()
}) }),
h: shy("打开左边标签", function(event, can) { can.page.Select(can, can._action, html.DIV_TABS_SELECT, function(target) {
var prev = target.previousSibling; prev && can.page.ClassList.has(can, prev, html.TABS) && prev.click()
}) }),
},
}, _engine: {},
})
Volcanos(chat.ONINPUTS, {
_nameicon: function(event, can, msg, target, name, title) { name = name||mdb.NAME
can.page.Appends(can, can._output, msg.Table(function(value) {
var _title = can.user.trans(can.sup, value[title]||value[name]||value[mdb.NAME], null, "value."+name)
var icons = can.sup.Conf("_trans.value."+name+".icons."+value[name])||can.sup.Conf("_trans.value."+name+".icons."+value[title])||value.icons||"usr/icons/icebergs.png"
return {view: html.ITEM, list: [{img: can.misc.Resource(can, icons), },
{view: html.CONTAINER, list: [{view: [html.TITLE, "", _title]},
can.onappend.label(can, value, kit.Dict("version", icon.version, "time", icon.compile, name, icon.data)),
]},
], onclick: function(event) { can.showIcons(value[name]||value[mdb.NAME], icons, _title) }}
}))
},
dream: function(event, can, msg, target, name) { can.sup.sub.oninputs._nameicon(event, can, msg, target, name) },
})

531
proto.js
View File

@ -1,171 +1,396 @@
function shy(help, meta, list, cb) { var arg = arguments, i = 0; function next(type) { var kit = {
if (type == code.OBJECT) { if (typeof arg[i] == code.OBJECT && arg[i].length == undefined) { return arg[i++] } Dict: function() { var res = {}
} else if (type == code.ARRAY) { if (typeof arg[i] == code.OBJECT && arg[i].length != undefined) { return arg[i++] } for (var i = 0; i < arguments.length; i += 2) {
} else if (i < arg.length && (!type || type == typeof arg[i])) { return arg[i++] } res[arguments[i]] = arguments[i+1]
} return cb = typeof arg[arg.length-1] == code.FUNCTION? arg[arg.length-1]: function() {}, cb.help = next(code.STRING)||"", cb.meta = next(code.OBJECT)||{}, cb.list = next(code.ARRAY)||[], cb } return res
}; var _can_name = "", _can_path = ""
var Volcanos = shy({iceberg: "", volcano: "", frame: chat.FRAME_JS, _cache: {}, cache: {}, pack: {}, args: {}}, function(name, can, libs, cb) {
var meta = arguments.callee.meta, list = arguments.callee.list; if (typeof name == code.OBJECT) {
if (name.length > 0) { return Volcanos({panels: [{name: chat.HEADER, style: html.HIDE, state: [mdb.TIME, aaa.USERNICK]}, {name: chat.ACTION, style: html.MAIN, tool: name}, {name: chat.FOOTER, style: html.HIDE}]}) }
var Config = name; name = Config.name||ice.CAN, meta.iceberg = Config.iceberg||meta.iceberg, meta.volcano = Config.volcano||meta.volcano
meta.libs = (Config.libs||chat.libs).concat(Config.list), panels = Config.panels||chat.panel_list, delete(Config.panels)
libs = [], panels.forEach(function(p) { p && (libs = libs.concat(p.list = p.list||["/panel/"+p.name+nfs._JS, "/panel/"+p.name+nfs._CSS])) }), libs = libs.concat(Config.plugins||chat.plugin_list)
cb = can||function(can) { can.require([can.frame], function() { can.onengine._init(can, can.Conf(Config), panels, Config._init||meta._init, can._target) }, function(can, key, sub) { can[key] = sub }) }
can = Config, can._follow = name, can._target = Config.target||meta.target, can._height = Config.height||meta._height, can._width = Config.width||meta._width, _can_name = ""
} }
can = kit.proto(can||{}, kit.proto({_name: name, _path: _can_name, }
_load: function(name, cbs) { var cache = meta.cache[name]||[] var ice = {
for (list.reverse(); list.length > 0; list) { var sub = list.pop(); sub != can && cache.push(sub), sub._path = sub._path||name } meta.cache[name] = cache SP: " ", PS: "/", PT: ".", DF: ":", FS: ",", NL: "\n", LT: "<", GT: ">",
cache.forEach(function(sub) { var name = sub._name POD: "pod", CTX: "ctx", CMD: "cmd", ARG: "arg", OPT: "opt",
if (typeof cbs == code.FUNCTION && cbs(can, name, sub)) { return } RUN: "run", RES: "res", ERR: "err",
can[name] = can[name]||{}, name == chat.ONIMPORT && (can[name]._last_init = sub._init) PWD: "./",
for (var k in sub) { can[name].hasOwnProperty(k) || sub.hasOwnProperty(k) && (can[name][k] = sub[k]) }
}) OK: "ok", TRUE: "true", FALSE: "false", SUCCESS: "success", FAILURE: "failure", PROCESS: "process",
},
require: function(libs, cb, cbs) { AUTO: "auto", HELP: "help", HTTP: "http",
if (!libs || libs.length == 0) { VIEW: "view", MODE: "mode", SHIP: "ship",
if (navigator.userAgent == "nodejs") { return typeof cb == code.FUNCTION && cb(can) } COPY: "copy", SHOW: "show", HIDE: "hide",
return typeof cb == code.FUNCTION && setTimeout(function() { cb(can) }, 30)
MSG_DETAIL: "detail",
MSG_OPTION: "option",
MSG_APPEND: "append",
MSG_RESULT: "result",
MSG_FIELDS: "fields",
MSG_SESSID: "sessid",
MSG_SOURCE: "_source",
MSG_TARGET: "_target",
MSG_HANDLE: "_handle",
MSG_UPLOAD: "_upload",
MSG_DAEMON: "_daemon",
MSG_ACTION: "_action",
MSG_STATUS: "_status",
MSG_DISPLAY: "_display",
MSG_PROCESS: "_process",
MSG_USERNAME: "user.name",
MSG_USERNICK: "user.nick",
MSG_TITLE: "sess.title",
MSG_TOPIC: "sess.topic",
MSG_RIVER: "sess.river",
MSG_STORM: "sess.storm",
MSG_TOAST: "sess.toast",
PROCESS_AGAIN: "_again",
MSG_PREFIX: "_prefix",
ErrWarn: "warn: ",
ErrNotFound: "not found: ",
}
var ctx = {
CONTEXT: "context", COMMAND: "command", ACTION: "action", CONFIG: "config",
INDEX: "index", ARGS: "args", STYLE: "style", INPUTS: "inputs", FEATURE: "feature",
}
var cli = {
START: "start", STOP: "stop",
OPEN: "open", CLOSE: "close",
BEGIN: "begin", END: "end",
MAIN: "main", MAKE: "make", SHOW: "show",
EXEC: "exec", DONE: "done", CODE: "code", COST: "cost",
ERROR: "error", CLEAR: "clear", REFRESH: "refresh",
FROM: "from", BACK: "back",
RED: "red", GREEN: "green", BLUE: "blue",
YELLOW: "yellow", CYAN: "cyan", PURPLE: "purple", MAGENTA: "magenta",
WHITE: "white", BLACK: "black",
}
var web = {
SPACE: "space", SHARE: "share",
}
var aaa = {
USERNAME: "username", USERNICK: "usernick", BACKGROUND: "background", AVATAR: "avatar",
LANGUAGE: "language", ENGLISH: "english", CHINESE: "chinese",
LOGIN: "login", LOGOUT: "logout", INVITE: "invite",
}
var mdb = {
DICT: "dict", META: "meta", HASH: "hash", LIST: "list",
ID: "id", KEY: "key", TIME: "time", ZONE: "zone", TYPE: "type", NAME: "name", TEXT: "text",
LINK: "link", SCAN: "scan", SHOW: "show", HELP: "help",
SHORT: "short", FIELD: "field", TOTAL: "total", COUNT: "count", LIMIT: "limit",
INDEX: "index", VALUE: "value", EXTRA: "extra", ALIAS: "alias", EXPIRE: "expire",
CREATE: "create", REMOVE: "remove", INSERT: "insert", DELETE: "delete",
MODIFY: "modify", SELECT: "select",
INPUTS: "inputs", PRUNES: "prunes", EXPORT: "export", IMPORT: "import",
UPLOAD: "upload",
SEARCH: "search", ENGINE: "engine", RENDER: "render", PLUGIN: "plugin",
NEXT: "next", PREV: "prev", PAGE: "page", MAIN: "main",
FOREACH: "*", RANDOMS: "%",
}
var ssh = {
SCRIPT: "script",
}
var nfs = {
HTML: "html", CSS: "css", JS: "js", GO: "go", SH: "sh", CSV: "csv", JSON: "json",
PATH: "path", FILE: "file", LINE: "line", SIZE: "size",
DIR: "dir", CAT: "cat", DEFS: "defs", TRASH: "trash",
DIR_ROOT: "dir_root",
SAVE: "save", LOAD: "load", TAGS: "tags", FIND: "find", GREP: "grep",
}
var tcp = {
HOST: "host", PORT: "port",
}
var code = {
VIMER: "vimer", INNER: "inner", FAVOR: "favor",
WEBPACK: "webpack",
}
var wiki = {
TITLE: "title", BRIEF: "brief", REFER: "refer", SPARK: "spark",
ORDER: "order", TABLE: "table", CHART: "chart", IMAGE: "image", VIDEO: "video",
FIELD: "field", SHELL: "shell", LOCAL: "local", PARSE: "parse",
NAVMENU: "navmenu", PREMENU: "premenu",
ITEM: ".story",
H2: "h2.story",
H3: "h3.story",
DIV_PAGE: "div.page",
}
var chat = {
LIB: "lib", PAGE: "page", PANEL: "panel", PLUGIN: "plugin", OUTPUT: "output", STORY: "story", FLOAT: "float",
TOAST: "toast", CARTE: "carte", INPUT: "input", UPLOAD: "upload", CONTEXTS: "contexts",
LEGNED: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status",
LAYOUT: "layout", PROJECT: "project", CONTENT: "content", DISPLAY: "display", PROFILE: "profile",
ONIMPORT: "onimport", ONACTION: "onaction", ONKEYMAP: "onkeymap", ONEXPORT: "onexport",
TITLE: "title", TOPIC: "topic", BLACK: "black", WHITE: "white", PRINT: "print",
SHARE: "share", RIVER: "river", STORM: "storm", FIELD: "field",
PUBLIC: "public", PROTECTED: "protected", PRIVATE: "private",
USER: "user", TOOL: "tool", NODE: "node",
AGENT: "agent", CHECK: "check", GRANT: "grant",
STATE: "state", MENUS: "menus", TRANS: "trans",
SSO: "sso",
ONMAIN: "onmain", ONLOGIN: "onlogin", ONSEARCH: "onsearch",
ONSIZE: "onsize", ONTOAST: "ontoast", ONREMOTE: "onremote",
ONKEYDOWN: "onkeydown",
HEAD: "head", LEFT: "left", MAIN: "main", AUTO: "auto", HIDE: "hide", FOOT: "foot",
HEADER: "header", FOOTER: "footer",
ACTION_LAYOUT_FMT: `
fieldset.Action.grid>div.output fieldset.plugin {
width:_width; height:_height;
}
fieldset.Action.grid>div.output fieldset.plugin>div.output {
width:_width; height:_height;
}
`,
PLUGIN_STATE_JS: "/plugin/state.js",
PLUGIN_INPUT_JS: "/plugin/input.js",
PLUGIN_TABLE_JS: "/plugin/table.js",
libs: ["/lib/base.js", "/lib/core.js", "/lib/misc.js", "/lib/page.js", "/lib/user.js"],
panel_list: [
{name: "Header", help: "标题栏", pos: "head", state: ["time", "usernick", "avatar"]},
{name: "River", help: "群聊组", pos: "left", action: ["create", "refresh"]},
{name: "Action", help: "工作台", pos: "main"},
{name: "Search", help: "搜索框", pos: "auto"},
{name: "Footer", help: "状态条", pos: "foot", state: ["ncmd"]},
],
plugin_list: [
"/plugin/state.js",
"/plugin/input.js",
"/plugin/table.js",
"/plugin/input/key.js",
"/plugin/input/date.js",
"/plugin/story/spide.js",
"/plugin/story/trend.js",
"/plugin/local/code/inner.js",
"/plugin/local/code/vimer.js",
"/plugin/local/wiki/draw/path.js",
"/plugin/local/wiki/draw.js",
"/plugin/local/wiki/word.js",
"/plugin/local/chat/div.js",
"/plugin/local/team/plan.js",
"/plugin/input/province.js",
],
}
var team = {
TASK: "task", PLAN: "plan",
}
var mall = {
ASSET: "asset", SALARY: "salary",
}
var svg = {
G: "g", X: "x", Y: "y", R: "r", RECT: "rect",
M: "M", Q: "Q", T: "T",
}
var html = {
FIELDSET: "fieldset", LEGEND: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status",
FORM_OPTION: "form.option", DIV_ACTION: "div.action", DIV_OUTPUT: "div.output", DIV_STATUS: "div.status",
FIELDSET_PANEL: "fieldset.panel", FIELDSET_PLUGIN: "fieldset.plugin", FIELDSET_STORY: "fieldset.story",
FIELDSET_HEAD: "fieldset.head", FIELDSET_FOOT: "fieldset.foot",
FIELDSET_LEFT: "fieldset.left", FIELDSET_MAIN: "fieldset.main",
FIELDSET_AUTO: "fieldset.auto", FIELDSET_FLOAT: "fieldset.float",
OPTION_ARGS: "select.args,input.args,textarea.args",
INPUT_ARGS: "input.args,textarea.args",
INPUT_BUTTON: "input[type=button]",
UPLOAD: "upload", USERNAME: "username", PASSWORD: "password",
INPUT: "input", TEXT: "text", TEXTAREA: "textarea", SELECT: "select", BUTTON: "button",
FORM: "form", FILE: "file", SPACE: "space", CLICK: "click", SUBMIT: "submit", CANCEL: "cancel",
DIV: "div", IMG: "img", CODE: "code", SPAN: "span", VIDEO: "video",
TABLE: "table", TR: "tr", TH: "th", TD: "td", BR: "br", UL: "ul", LI: "li",
A: "a", LABEL: "label", INNER: "inner", TITLE: "title",
H1: "h1", H2: "h2", H3: "h3",
CLASS: "class", FLOAT: "float", CLEAR: "clear", BOTH: "both",
BACKGROUND: "background", SELECT: "select", HIDDEN: "hidden",
DISPLAY: "display", BLOCK: "block", NONE: "none", FIXED: "fixed",
OPACITY: "opacity",
STROKE_WIDTH: "stroke-width", STROKE: "stroke", FILL: "fill", FONT_SIZE: "font-size", MONOSPACE: "monospace",
SCROLL: "scroll", HEIGHT: "height", WIDTH: "width", LEFT: "left", TOP: "top", RIGHT: "right", BOTTOM: "bottom",
MAX_HEIGHT: "max-height", MAX_WIDTH: "max-width", MARGIN_X: "margin-x", MARGIN_Y: "margin-y",
PLUGIN_MARGIN: 10, ACTION_HEIGHT: 29, ACTION_MARGIN: 200,
TOGGLE: "toggle",
WSS: "wss", SVG: "svg", CANVAS: "canvas", IFRAME: "iframe", CHROME: "chrome",
LIST: "list", ITEM: "item", MENU: "menu", NODE: "node",
DIV_ITEM: "div.item", DIV_FLOAT: "div.float",
TABS: "tabs", DIV_TABS: "div.tabs",
HIDE: "hide", SHOW: "show",
}
var lang = {
UNDEFINED: "undefined",
STRING: "string", NUMBER: "number",
OBJECT: "object", FUNCTION: "function",
ESCAPE: "Escape", ENTER: "Enter", TAB: "Tab",
}
function shy(help, meta, list, cb) {
var index = 0, args = arguments; function next(type) {
if (index < args.length && (!type || type == typeof args[index])) { return args[index++] }
}
cb = args[args.length-1]||function() {}
cb.help = next(lang.STRING)||""
cb.meta = next(lang.OBJECT)||{}
cb.list = next(lang.OBJECT)||[]
return cb
}; var _can_name = "", _can_path = ""
var Volcanos = shy("火山架", {iceberg: "/chat/", volcano: "/frame.js", args: {}, pack: {}, libs: [], cache: {}}, function(name, can, libs, cb) {
var meta = arguments.callee.meta, list = arguments.callee.list
if (typeof name == lang.OBJECT) { var Config = name; Config.plugin = Config.plugin||chat.plugin_list
Config.panels = Config.panels||chat.panel_list, Config.main = Config.main||{name: "Header"}
meta.libs = Config.libs||chat.libs, meta.iceberg = Config.iceberg||meta.iceberg
// 预加载
libs = []; for (var i = 0; i < Config.panels.length; i++) { var panel = Config.panels[i]
panel && (libs = libs.concat(panel.list = panel.list||["/panel/"+panel.name+".css", "/panel/"+panel.name+".js"]))
}; libs = libs.concat(Config.plugin, Config.main.list)
// 根模块
_can_name = "", name = Config.name||"chat", cb = can||function(can) {
can.onengine._init(can, can.Conf(Config), Config.panels, Config._init, can._target)
}, can = {_follow: name, _target: Config.target||document.body}, can._root = can
for (var k in Config) { can[k] = Config[k] }
}
var proto = {__proto__: meta, _path: _can_path, _name: name, _load: function(name, each) { // 加载缓存
var cache = meta.cache[name]||[]; for (list.reverse(); list.length > 0; list) {
var sub = list.pop(); sub != can && cache.push(sub)
}; meta.cache[name] = cache
// 加载模块
for (var i = 0; i < cache.length; i++) { var sub = cache[i], name = sub._name
if (typeof each == lang.FUNCTION && each(can, name, sub)) { continue }
!can[name] && (can[name] = {}); for (var k in sub) {
can[name].hasOwnProperty(k) || (can[name][k] = sub[k])
}
} }
if (libs[0] == undefined) { return can.require(libs.slice(1), cb, cbs) }
if (libs[0] == "") { libs[0] = can._path.replace(nfs._JS, nfs._CSS) }
if (libs[0].indexOf(nfs.SRC) == 0 || libs[0].indexOf(nfs.USR) == 0) { libs[0] = nfs.P+libs[0] }
if (libs[0][0] != nfs.PS && libs[0].indexOf(web.HTTP) != 0) { libs[0] = can._path.slice(0, can._path.lastIndexOf(ice.PS)+1)+libs[0] }
// var name = (libs[0].indexOf(web.HTTP) == 0 || libs[0].indexOf("?pod=") > -1? libs[0]: libs[0].split(ice.QS)[0]).toLowerCase()
// var name = (libs[0].indexOf(web.HTTP) == 0 || libs[0].indexOf("?pod=") > -1? libs[0]: libs[0]).toLowerCase()
var name = libs[0].indexOf(web.HTTP) == 0 || libs[0].indexOf("?pod=") > -1? libs[0]: libs[0]
if (name.indexOf("pod=") == -1) { name = name.toLowerCase() }
function next() { can._load(name, cbs), can.require(libs.slice(1), cb, cbs) }
if (name.indexOf("/lib/") == 0) { name = "/v"+name }
if (name.indexOf("/panel/") == 0) { name = "/v"+name }
if (name.indexOf("/plugin/") == 0) { name = "/v"+name }
if (name.indexOf("/volcanos/") == 0 && meta.volcano) { name = meta.volcano+name }
if (name.indexOf("/require/") == 0 && meta.iceberg) { name = meta.iceberg+name }
if (name.indexOf("/p/") == 0 && meta.iceberg) { name = meta.iceberg+name }
if (name.indexOf("/v/") == 0 && meta.iceberg) { name = meta.iceberg+name }
meta.cache[name]? next(): meta._load(name, next)
}, },
request: function(event) { event = event||{}, event = event._event||event require: function(libs, cb, each) { if (!libs || libs.length == 0) {
typeof cb == lang.FUNCTION && setTimeout(function() { cb(can) }, 10)
return // 加载完成
}
// 无效地址
if (!libs[0]) { return can.require(libs.slice(1), cb, each) }
// 补全地址
if (libs[0] == "") {
libs[0] = can._name.replace(".js", ".css")
} else if (libs[0][0] != ice.PS && libs[0].indexOf(ice.HTTP) != 0) {
libs[0] = can._name.slice(0, can._name.lastIndexOf(ice.PS)+1)+libs[0]
}
// 加载模块
libs[0] = libs[0].toLowerCase()
var name = libs[0].split("?")[0]
function next() { can._load(name, each), can.require(libs.slice(1), cb, each) }
meta.cache[name]? next(): (_can_path = libs[0], meta._load(name, next))
},
request: function(event, option) { event = event||{}
var msg = event._msg||can.misc.Message(event, can); event._msg = msg var msg = event._msg||can.misc.Message(event, can); event._msg = msg
function set(key, value) { function set(key, value) { msg.Option(key) || value == "" || msg.Option(key, value) }
if (key == "_method") { return msg._method = value }
if (key == "action" && value.indexOf("<input") == 0) { return } can.core.List(arguments, function(option, index) { if (!option || index == 0) { return }
if (key == "extra") { return } can.base.isFunc(option.Option)? can.core.List(option.Option(), function(key) {
if (typeof value == code.FUNCTION) { return msg[key] = value } set(key, option.Option(key))
value == "" || msg.Option(key) || msg.Option(key, value) }): can.core.Item(can.base.isFunc(option)? option(): option, set)
} }); return msg
can.core.List(arguments, function(item, index) { if (!item || index == 0) { return }
can.base.isFunc(item.Option)? can.core.List(item.Option(), function(key) {
key.indexOf("_") == 0 || key.indexOf("user.") == 0 || set(key, item.Option(key))
}): can.core.Item(can.base.isFunc(item)? item(): item, set)
})
return msg
},
requests: function(event) { var msg = can.request(event); function set(key, value) { msg.Option(key, value) }
can.core.List(arguments, function(item, index) { if (!item || index == 0) { return } can.core.Item(item, set) }); return msg
},
requestPodCmd: function(event) { return can.request(event, {pod: can.ConfSpace(), index: can.ConfIndex()}) },
requestAction: function(event, button) { return can.request(event, {action: button, _toast: event.isTrusted? can.user.trans(can, button): ""}) },
runActionInputs: function(event, cmds, cb) { var msg = can.request(event), meta = can.Conf()
if (msg.Option(ice.MSG_HANDLE) != ice.TRUE && cmds && cmds[0] == ctx.ACTION && meta.feature[cmds[1]]) { var msg = can.request(event, {action: cmds[1]})
if (can.base.isFunc(meta.feature[cmds[1]])) { return meta.feature[cmds[1]](can, msg, cmds.slice(2)) }
return can.user.input(event, can, meta.feature[cmds[1]], function(args) { can.Update(can.request(event, {_handle: ice.TRUE}, can.Option()), cmds.slice(0, 2).concat(args)) })
} can.runAction(event, cmds[1], cmds.slice(2), cb, true)
},
runActionCommand: function(event, index, args, cb) {
var msg = can.request(event, {_handle: ice.TRUE}); can.request(event)._caller()
can.run(event, [ctx.ACTION, ctx.RUN].concat(index, args||[]), cb, true)
},
runAction: function(event, action, args, cb, silent) {
var msg = can.request(event, {_handle: ice.TRUE}); can.request(event, can.Option())._caller()
can.run(event, [ctx.ACTION].concat(action, args||[]), cb, silent)
}, },
search: function(event, cmds, cb) { search: function(event, cmds, cb) {
if (cmds && typeof cmds == code.OBJECT && cmds.length > 0 && typeof cmds[0] == code.OBJECT && cmds[0].length > 0 ) { cmds[0] = cmds[0].join(nfs.PT) } if (cmds && typeof cmds == lang.OBJECT && cmds.length > 0 && typeof cmds[0] == lang.OBJECT && cmds[0].length > 0 ) {
return (can._root||can).run(event, [chat._SEARCH].concat(cmds), cb, true) cmds[0] = cmds[0].join(ice.PT)
}
return can.run && can.run(event, ["_search"].concat(cmds), cb, true)
},
get: function(name, key, cb) { return can.search({}, [can.core.Keys(name, chat.ONEXPORT, key)], cb) },
set: function(name, key, value) { var msg = can.request({}); msg.Option(key, value)
return can.search(msg._event, [[name, chat.ONIMPORT, key]])
}, },
get: function(name, key, cb) { var value; can.search({}, [can.core.Keys(name, chat.ONEXPORT, key)], cb||function(msg) { value = msg.Result() }); return value },
set: function(name, key, value) { var msg = can.request(); msg.Option(key, value); return can.search(msg, [[name, chat.ONIMPORT, key]]) },
setHeaderMenu: function(list, cb) { can._menu && can.page.Remove(can, can._menu) setHeaderMenu: function(list, cb) { can._menu && can.page.Remove(can, can._menu)
return can._menu = can.search(can.request({}, {trans: can.onaction._trans}), [[chat.HEADER, chat.ONIMPORT, html.MENU], can._name].concat(list), cb) var msg = can.request({}, {trans: can.onaction._trans})
return can._menu = can.search(msg._event, [["Header", chat.ONIMPORT, "menu"], can._name].concat(list), cb)
}, },
setFooterMenu: function(list, cb) { can._footer_menu && can.page.Remove(can, can._footer_menu) setHeader: function(key, value) { return can.set("Header", key, value) },
return can._footer_menu = can.search(can.request({}, {trans: can.onaction._trans}), [[chat.FOOTER, chat.ONIMPORT, html.MENU], can._name].concat(list), cb) getHeader: function(key, cb) { return can.get("Header", key, cb) },
}, getAction: function(key, cb) { return can.get("Action", key, cb) },
getHeaderTheme: function(cb) { return can.get(chat.HEADER, chat.THEME, cb) }, getActionSize: function(cb) { return can.get("Action", "size", cb) },
getHeaderLanguage: function(cb) { return can.get(chat.HEADER, aaa.LANGUAGE, cb) },
getHeaderHeight: function() { return can._root.Header? can._root.Header._target.offsetHeight: 0},
getFooterHeight: function() { return can._root.Footer? can._root.Footer._target.offsetHeight: 0},
getHeader: function(key, cb) { return can.get(chat.HEADER, key, cb) },
setHeader: function(key, value) { return can.set(chat.HEADER, key, value) },
setAction: function(key, value) { return can.set(chat.ACTION, key, value) },
getAction: function(key, cb) { return can.get(chat.ACTION, key, cb) },
getActionSize: function(cb) { return can.get(chat.ACTION, nfs.SIZE, cb) },
getRiverWidth: function() { return can._root.River? can._root.River._target.offsetWidth: 0},
isPanelType: function() { return can.page.ClassList.has(can, can._fields||can._target, chat.PANEL) },
isPluginType: function() { return can.page.ClassList.has(can, can._fields||can._target, chat.PLUGIN) },
isStoryType: function() { return can.page.ClassList.has(can, can._fields||can._target, chat.STORY) },
isOutputStyle: function() { return can.page.ClassList.has(can, can._fields||can._target, chat.OUTPUT) },
isSimpleMode: function() { return can.Mode() == chat.SIMPLE },
isFloatMode: function() { return can.Mode() == chat.FLOAT },
isFullMode: function() { return can.Mode() == chat.FULL },
isZoneMode: function() { return can.Mode() == "zone" },
isCmdMode: function() { return can.Mode() == chat.CMD },
isAutoMode: function() { return can.Mode() == "" },
Mode: function(value) { return can.Conf(ice.MODE, value) },
ConfDefault: function(value) { can.core.Item(value, function(k, v) { can.Conf(k) || can.Conf(k, v) }) },
ConfSpace: function(space) { if (space) { can.Conf(web.SPACE, space) } return can.Conf("_space")||can.Conf(web.SPACE)||can.Conf("pod")||"" },
ConfIndex: function(index) { if (index) { can.Conf(ctx.INDEX, index) } return can.Conf("_command")||can.Conf(ctx.INDEX)||can.Conf("_index")||"can" },
ConfIcons: function() { return can.Conf(mdb.ICONS) },
ConfHeight: function(value) { return can.Conf(html.HEIGHT, value) }, ConfHeight: function(value) { return can.Conf(html.HEIGHT, value) },
ConfWidth: function(value) { return can.Conf(html.WIDTH, value)||can._output.offsetWidth }, ConfWidth: function(value) { return can.Conf(html.WIDTH, value) },
ConfHelp: function() { return can.Conf("help") },
Conf: function(key, value) { var res = can._conf Conf: function(key, value) { var res = can._conf
for (var i = 0; i < arguments.length; i += 2) { for (var i = 0; i < arguments.length; i += 2) {
if (typeof key == code.OBJECT) { res = can.core.Value(can._conf, arguments[i]), i--; continue } if (typeof key == lang.OBJECT) {
res = can.core.Value(can._conf, arguments[i]), i--
continue
}
res = can.core.Value(can._conf, arguments[i], arguments[i+1]) res = can.core.Value(can._conf, arguments[i], arguments[i+1])
} return can.base.isUndefined(res) && key.indexOf(ctx.FEATURE+nfs.PT) == -1? can.Conf(can.core.Keys(ctx.FEATURE, key)): res }
return res
}, _conf: {}, }, _conf: {},
}, meta)); if (_can_name) { meta.cache[_can_name] = meta.cache[_can_name]||[], meta.cache[_can_name].push(can) } else { list.push(can) }
setTimeout(function() { can.require(can._follow? libs.concat(meta.libs, meta.frame): libs, cb) }, 1)
return can
})
try { if (typeof(window) == code.OBJECT) { var meta = Volcanos.meta
try { var debug = location.search.indexOf("debug=true") > -1
meta.version = window._version||"", window.parent.outerWidth-window.parent.innerWidth > 100 && (meta.version = "", debug = false)
} catch (e) {
meta.version = window._version, window.outerWidth-window.innerWidth > 100 && (meta.version = "", debug = false)
} }
meta._load = function(url, cb) {
if (meta.version && url.indexOf("/p/usr/icons/") == -1) { url += (url.indexOf(web.QS) == -1? web.QS: "&")+meta.version.slice(1) } can = can||{}; if (navigator.userAgent.indexOf("MSIE") > -1) {
if (meta._cache[url]) { return meta._cache[url].push(cb) } else { meta._cache[url] = [cb] } for (var k in proto) { can[k] = proto[k] }
function _cb() { meta._cache[url].forEach(function(cb) { cb() }), delete(meta._cache[url]) } } else {
switch (url.split(web.QS)[0].split(nfs.PT).pop().toLowerCase()) { can.__proto__ = proto
case nfs.CSS: var item = document.createElement(web.LINK); item.href = url, item.rel = "stylesheet", item.onload = _cb, document.head.appendChild(item); break }
default: var item = document.createElement(nfs.SCRIPT); item.src = url, item.onerror = _cb, item.onload = _cb, document.body.appendChild(item)
if (_can_name) { // 加入缓存
meta.cache[_can_name] = meta.cache[_can_name]||[], meta.cache[_can_name].push(can)
} else { // 加入队列
list.push(can)
}
if (can._follow) { libs = libs.concat(meta.libs, meta.volcano) }
if (libs && libs.length > 0) {
for (var i = 0; i < libs.length; i++) {
if (libs[i] == undefined) {
} else if (libs[i] == "") {
libs[i] = _can_path.replace(".js", ".css")
} else if (libs[i][0] != ice.PS && libs[i].indexOf(ice.HTTP) != 0) {
libs[i] = _can_path.slice(0, _can_path.lastIndexOf(ice.PS)+1)+libs[i]
}
} }
} }
document.ondrop = function(event) { return can.require(libs, cb), can
debugger })
Volcanos.meta._load = function(url, cb) {
switch (url.split("?")[0].split(ice.PT).pop().toLowerCase()) {
case nfs.CSS:
var item = document.createElement(mdb.LINK)
item.rel = "stylesheet", item.type = "text/css"
item.href = url, item.onload = cb
return (document.head||document.body).appendChild(item), item
case nfs.JS:
var item = document.createElement(ssh.SCRIPT)
item.src = url, item.onload = cb, item.onerror = cb
return document.body.appendChild(item), item
} }
meta.target = document.body, meta._height = window.innerHeight, meta._width = window.innerWidth }
meta._init = function(can) { var last = can.page.width() < can.page.height() function can(tool) {
window.onresize = function(event) { can.misc.Event(event, can, function(msg) { Volcanos({name: "chat", panels: [
if (can.user.isMobile && last === can.page.width() < can.page.height()) { return } last = can.page.width() < can.page.height() {name: "Header", help: "标题栏", pos: chat.HIDE, state: ["time", "usernick", "avatar"]},
can.onmotion.delayOnce(can, function() { can.onengine.signal(can, chat.ONRESIZE, can.request(event, kit.Dict(html.HEIGHT, window.innerHeight, html.WIDTH, window.innerWidth))) }, 100, can._delay_resize = can._delay_resize||[]) {name: "Action", help: "工作台", pos: chat.MAIN, tool: tool},
}) } {name: "Search", help: "搜索框", pos: chat.AUTO},
window.onerror = function(message, source, lineno, colno, error) { debug? alert([message].concat(can.misc._stacks(0, error)).join(lex.NL)): can.misc.Error(message, lex.NL+[source, lineno, colno].join(ice.DF), error) } ]})
window.onmousemove = function(event) { window._mousemove && (window._mousemove.onmousemove(event)) } }
window.onmouseup = function(event) { window._mousemove && (window._mousemove.onmouseup(event)) }
window.onbeforeunload = function() { can.onengine.signal(can, chat.ONUNLOAD) }
}
} else { // nodejs
global.document = {}, global.location = {}, global.window = {}, global.navigator = {userAgent: "nodejs"}
global.kit = kit, global.ice = ice
global.ctx = ctx, global.mdb = mdb, global.web = web, global.aaa = aaa
global.lex = lex, global.yac = yac, global.ssh = ssh, global.gdb = gdb
global.tcp = tcp, global.nfs = nfs, global.cli = cli, global.log = log
global.code = code, global.wiki = wiki, global.chat = chat, global.team = team, global.mall = mall
global.http = http, global.html = html, global.icon = icon, global.svg = svg
global.shy = shy, global.Volcanos = Volcanos
} } catch (e) { console.log(e) }

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body>
<script src="/page/can.js"></script>
<script src="/publish/chrome/chrome.js"></script>
</body>
</html>

64
publish/chrome/chrome.js Normal file
View File

@ -0,0 +1,64 @@
Volcanos({
chrome: function(can, msg, arg, cb) {
if (arg.length == 0 || arg[0] == "") { // 窗口列表
chrome.windows.getAll(function(wins) {
can.core.List(wins, function(win) { win.wid = win.id
msg.Push(win, ["wid", "state", html.LEFT, html.TOP, html.WIDTH, html.HEIGHT])
}), can.base.isFunc(cb) && cb(msg)
})
} else if (arg.length == 1 || arg[1] == "") { // 标签列表
chrome.tabs.getAllInWindow(parseInt(arg[0]), function(tabs) {
can.core.List(tabs, function(tab) { tab.tid = tab.id
msg.Push(tab, ["tid", "active", html.WIDTH, html.HEIGHT, "index", "title", "url"])
}), can.base.isFunc(cb) && cb(msg)
})
} else if (arg[1] == "current") { // 当前标签
chrome.tabs.query({currentWindow: true, active: true}, function(tabs) { arg[1] = tabs[0].id
chrome.tabs.sendMessage(parseInt(arg[1]), msg, function(res) {
can.base.isFunc(cb) && cb(msg.Copy(res))
})
})
} else { // 下发命令
chrome.tabs.sendMessage(parseInt(arg[1]), msg, function(res) {
can.base.isFunc(cb) && cb(msg.Copy(res))
})
}
},
_daemon: function(can) {
can.misc.WSS(can, {type: html.CHROME, name: html.CHROME}, function(event, msg, cmd, arg) {
if (msg.Option(ice.MSG_TARGET)) { msg.detail = ["", "", ""].concat(msg.detail)
chrome.tabs.sendMessage(parseInt(msg.Option(ice.MSG_TARGET)), msg, function(res) {
msg.Copy(res), msg.Reply()
})
return
}
can.core.CallFunc([can, cmd], {can: can, msg: msg, arg: arg, cb: function() { msg.Reply() }})
})
chrome.runtime.onMessage.addListener(function(req, sender, cb) {
var msg = can.request({}, {tid: sender.tab.id, url: sender.url})
can.core.List(req.option, function(key) { msg.Option(key, req[key][0]) })
msg.__daemon = can.core.Keys(html.CHROME, sender.tab.id)
can.run(msg._event, req.detail||[], cb)
return true
})
chrome.history.onVisited.addListener(function(item) {
can.run({}, ["sync", mdb.TYPE, "link", mdb.NAME, item.title, mdb.LINK, item.url, "tid", item.id])
})
},
_motion: function(can) {
can.user.toast = function(can, message, title) { chrome.notifications.create(null, {
message: message, title: title||can._name, iconUrl: "/favicon.ico", type: "basic",
})},
chrome.contextMenus.create({title: "volcanos", onclick: function(event) {
chrome.tabs.query({currentWindow: true, active: true}, function(tabs) {
var msg = can.request(event); msg.detail = [html.CHROME, "", "", "order"]
chrome.tabs.sendMessage(tabs[0].id, msg)
})
}})
},
}, function(can) {
can.run = function(event, cmds, cb) { var msg = can.request(event)
can.misc.Run(event, can, {names: "http://localhost:9020/code/chrome/"+cmds[0]}, cmds.slice(1), cb)
}, can._daemon(can), can._motion(can)
})

Some files were not shown because too many files have changed in this diff Show More