From 74f4cd22d49368f9ccef8fdf7084ad679829a88c Mon Sep 17 00:00:00 2001 From: yutent Date: Fri, 1 Sep 2023 18:39:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=80=E5=A4=A7=E6=B3=A2=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/css/app.css | 219 ++++++++- usr/lib/hosts-switch/webapp/app.js | 4 +- .../hosts-switch/webapp/components/home.js | 448 +++++++++++++++++- .../webapp/components/permission.js | 106 +++++ usr/lib/hosts-switch/webapp/css/reset.css | 2 +- usr/lib/hosts-switch/webapp/index.html | 2 +- .../hosts-switch/webapp/lib/ui/form/button.js | 64 +-- .../hosts-switch/webapp/lib/ui/form/input.js | 154 +----- .../hosts-switch/webapp/lib/ui/form/link.js | 5 + .../hosts-switch/webapp/lib/ui/form/switch.js | 60 +-- .../hosts-switch/webapp/lib/ui/layer/index.js | 320 +------------ .../webapp/lib/ui/scroll/index.js | 13 + usr/lib/hosts-switch/webapp/lib/wkit.js | 4 +- usr/lib/hosts-switch/webapp/utils/index.js | 85 ++++ usr/lib/hosts-switch/window.py | 2 +- 15 files changed, 888 insertions(+), 600 deletions(-) create mode 100644 usr/lib/hosts-switch/webapp/components/permission.js create mode 100644 usr/lib/hosts-switch/webapp/lib/ui/form/link.js create mode 100644 usr/lib/hosts-switch/webapp/lib/ui/scroll/index.js create mode 100644 usr/lib/hosts-switch/webapp/utils/index.js diff --git a/src/css/app.css b/src/css/app.css index b3ff818..2c2391b 100644 --- a/src/css/app.css +++ b/src/css/app.css @@ -1 +1,218 @@ -html{width:100%;height:100vh}body{position:fixed;left:0;top:0;display:flex;width:100%;height:100%;line-height:1.5;font-size:14px;color:var(--color-dark-1)}.layout-left{display:flex;flex-direction:column;width:180px;height:100vh;background:var(--color-dark-2)}.layout-left wc-scroll{overflow:hidden;flex:1}.layout-left .domain-list{width:100%}.layout-left .domain-list .item{display:flex;justify-content:flex-end;align-items:center;height:40px;padding:0 20px 0 10px;color:var(--color-plain-1);cursor:pointer;transition:background .1s ease-in-out}.layout-left .domain-list .item wc-icon{--size: 12px;margin:auto -15px auto 5px;color:var(--color-grey-3)}.layout-left .domain-list .item:hover,.layout-left .domain-list .item.active{background:var(--color-dark-1)}.layout-left .domain-list .item.active{border-left:.3px solid var(--color-orange-1);color:var(--color-orange-1);font-weight:bold}.layout-left .domain-list .item.blank{justify-content:center;cursor:default}.layout-left .domain-list .item.blank:hover{background:none}.layout-left .action{display:flex;align-items:center;height:50px;padding:0 10px}.layout-right{flex:1;display:flex;flex-direction:column;background:#f7f8fb}.layout-right .toolbar{display:flex;align-items:center;justify-content:space-between;height:40px;padding:0 15px;background:var(--color-plain-2);box-shadow:0 2px 5px rgba(0,0,0,.1)}.layout-right .toolbar wc-input{width:200px}.layout-right .main{overflow:hidden;flex:1;display:flex;flex-direction:column;margin:20px 10px;padding:0 5px;background:#fff}.layout-right .thead{display:flex;align-items:center;justify-content:center;height:40px;margin-bottom:8px;border-bottom:1px solid var(--color-plain-2);text-align:center}.layout-right .thead span{flex:1}.layout-right .thead .long{flex:1.5}.layout-right wc-scroll{flex:1}.layout-right .record-list{width:100%;line-height:40px}.layout-right .record-list .item{display:flex;justify-content:center;align-items:center;height:40px;padding:0 10px;border-bottom:1px solid var(--color-plain-2);text-align:center}.layout-right .record-list .item wc-input,.layout-right .record-list .item span,.layout-right .record-list .item section{flex:1}.layout-right .record-list .item .long{flex:1.5}.layout-right .record-list .item section{display:flex;align-items:center;justify-content:center}.layout-right .record-list .item wc-button{margin-left:5px}.layout-right .record-list .item:last-child{border-bottom:none}.permission-error{position:fixed;left:0;top:0;z-index:102401;display:flex;flex-direction:column;align-items:center;width:100%;height:100%;padding:50px;background:rgba(255,233,233,.95);-webkit-backdrop-filter:blur(0.5rem);backdrop-filter:blur(0.5rem)}.permission-error pre{font-family:"Courier New",Courier,monospace;font-size:16px;color:var(--color-red-1)}.permission-error fieldset{width:600px;padding:0 30px 30px;border:1px solid var(--color-orange-1);border-radius:8px}.permission-error fieldset legend{padding:0 10px;font-size:16px}.permission-error fieldset dt{margin-top:20px;font-weight:bold}.permission-error fieldset code{display:block;padding:8px 10px;margin-top:8px;border-left:3px solid var(--color-plain-3);background:rgba(255,255,255,.3);font-family:"Courier New",Courier,monospace}.permission-error.show{display:flex}.context-menu{display:flex;flex-direction:column;width:100px;padding:5px 0;background:#fff}.context-menu .item{height:30px;line-height:30px;padding:0 15px;cursor:pointer}.context-menu .item:hover{background:#f2f5fc} \ No newline at end of file +html { + width: 100%; + height: 100vh; +} +body { + position: fixed; + left: 0; + top: 0; + display: flex; + width: 100%; + height: 100%; + line-height: 1.5; + font-size: 14px; + color: var(--color-dark-1); +} +.layout-left { + display: flex; + flex-direction: column; + width: 180px; + height: 100vh; + background: var(--color-dark-2); +} +.layout-left wc-scroll { + overflow: hidden; + flex: 1; +} +.layout-left .domain-list { + width: 100%; +} +.layout-left .domain-list .item { + display: flex; + justify-content: flex-end; + align-items: center; + height: 40px; + padding: 0 20px 0 10px; + color: var(--color-plain-1); + cursor: pointer; + transition: background 0.1s ease-in-out; +} +.layout-left .domain-list .item wc-icon { + --size: 12px; + margin: auto -15px auto 5px; + color: var(--color-grey-3); +} +.layout-left .domain-list .item:hover, +.layout-left .domain-list .item.active { + background: var(--color-dark-1); +} +.layout-left .domain-list .item.active { + border-left: 0.3px solid var(--color-orange-1); + color: var(--color-orange-1); + font-weight: bold; +} +.layout-left .domain-list .item.blank { + justify-content: center; + cursor: default; +} +.layout-left .domain-list .item.blank:hover { + background: none; +} +.layout-left .action { + display: flex; + align-items: center; + height: 50px; + padding: 0 10px; +} + + + + +.layout-right { + flex: 1; + display: flex; + flex-direction: column; + background: #f7f8fb; +} +.layout-right .toolbar { + display: flex; + align-items: center; + justify-content: space-between; + height: 40px; + padding: 0 15px; + background: var(--color-plain-2); + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); +} +.layout-right .toolbar wc-input { + width: 200px; +} +.layout-right .main { + overflow: hidden; + flex: 1; + display: flex; + flex-direction: column; + margin: 20px 10px; + padding: 0 5px; + background: #fff; +} +.layout-right .thead { + display: flex; + align-items: center; + justify-content: center; + height: 40px; + margin-bottom: 8px; + border-bottom: 1px solid var(--color-plain-2); + text-align: center; +} +.layout-right .thead span { + flex: 1; +} +.layout-right .thead .long { + flex: 1.5; +} +.layout-right wc-scroll { + flex: 1; +} +.layout-right .record-list { + width: 100%; + line-height: 40px; +} +.layout-right .record-list .item { + display: flex; + justify-content: center; + align-items: center; + height: 40px; + padding: 0 10px; + border-bottom: 1px solid var(--color-plain-2); + text-align: center; +} +.layout-right .record-list .item wc-input, +.layout-right .record-list .item span, +.layout-right .record-list .item section { + flex: 1; +} +.layout-right .record-list .item .long { + flex: 1.5; +} +.layout-right .record-list .item section { + display: flex; + align-items: center; + justify-content: center; +} +.layout-right .record-list .item wc-button { + margin-left: 5px; +} +.layout-right .record-list .item:last-child { + border-bottom: none; +} + + + + + + + + + + +.permission-error { + position: fixed; + left: 0; + top: 0; + z-index: 102401; + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + height: 100%; + padding: 50px; + background: rgba(255, 233, 233, 0.95); + -webkit-backdrop-filter: blur(0.5rem); + backdrop-filter: blur(0.5rem); +} +.permission-error pre { + font-family: 'Courier New', Courier, monospace; + font-size: 16px; + color: var(--color-red-1); +} +.permission-error fieldset { + width: 600px; + padding: 0 30px 30px; + border: 1px solid var(--color-orange-1); + border-radius: 8px; +} +.permission-error fieldset legend { + padding: 0 10px; + font-size: 16px; +} +.permission-error fieldset dt { + margin-top: 20px; + font-weight: bold; +} +.permission-error fieldset code { + display: block; + padding: 8px 10px; + margin-top: 8px; + border-left: 3px solid var(--color-plain-3); + background: rgba(255, 255, 255, 0.3); + font-family: 'Courier New', Courier, monospace; +} +.permission-error.show { + display: flex; +} +.context-menu { + display: flex; + flex-direction: column; + width: 100px; + padding: 5px 0; + background: #fff; +} +.context-menu .item { + height: 30px; + line-height: 30px; + padding: 0 15px; + cursor: pointer; +} +.context-menu .item:hover { + background: #f2f5fc; +} diff --git a/usr/lib/hosts-switch/webapp/app.js b/usr/lib/hosts-switch/webapp/app.js index 8c2ae9c..198b01f 100644 --- a/usr/lib/hosts-switch/webapp/app.js +++ b/usr/lib/hosts-switch/webapp/app.js @@ -40,6 +40,4 @@ createApp({ render() { return html` ` } -}) - .use(router) - .mount() +}).mount() diff --git a/usr/lib/hosts-switch/webapp/components/home.js b/usr/lib/hosts-switch/webapp/components/home.js index 4926d33..3837ad2 100644 --- a/usr/lib/hosts-switch/webapp/components/home.js +++ b/usr/lib/hosts-switch/webapp/components/home.js @@ -3,64 +3,468 @@ * @author yutent * @date 2023/08/08 18:19:17 */ -import { html, css, Component } from 'wkit' +import { html, css, Component, classMap, nextTick } from 'wkit' import 'ui/icon/index.js' +import 'ui/scroll/index.js' +import 'ui/layer/index.js' import 'ui/space/index.js' import 'ui/form/input.js' import 'ui/form/switch.js' import 'ui/form/button.js' +import 'ui/form/link.js' + +import './permission.js' + +import { getHistory, saveHosts } from '../utils/index.js' + +const HOST_DATA = await getHistory() + +let tmp_records = Object.create(null) + +function noop() {} class Home extends Component { static props = { - foo: '' + filter: '', + activeDomain: localStorage.getItem('last_domain') || '', //当前选中的域名 + editDomain: '', // 当前临时要编辑的域名, 即右键菜单选择到的 + domains: Object.keys(HOST_DATA), + records: [], + permissionShow: false } static styles = [ css` :host { flex: 1; - } - .main { + display: flex; width: 100%; height: 100%; padding: 32px; color: var(--color-dark-1); background: #f0f0f0; } + .visible { + display: block; + } - wc-input { + ul li { + list-style: none; + } + + .noselect { + -webkit-touch-callout: none; + -webkit-user-select: none; + user-select: none; + } + `, + css` + .layout-left { + flex-shrink: 0; + display: flex; + flex-direction: column; + width: 180px; + height: 100vh; + background: var(--color-plain-2); + } + + wc-scroll { flex: 1; } - wc-button { + .layout-left .domain-list { width: 100%; } - .card { - width: 100%; - padding: 12px; - margin: 0 auto 24px; - border: 0; - box-shadow: 0 0 8px rgba(0, 0, 0, 0.075); + .layout-left .domain-list .item { + display: flex; + justify-content: flex-end; + align-items: center; + height: 40px; + padding: 0 12px; + cursor: pointer; + transition: background 0.15s ease-in-out; + } + + .layout-left .item wc-icon { + --wc-icon-size: 12px; + margin-left: 8px; + color: var(--color-grey-2); + } + + .layout-left .item:hover, + .layout-left .item.active { background: #fff; } - legend { - -webkit-touch-callout: none; - user-select: none; - color: var(--color-dark-1); - font-weight: bold; + .layout-left .item.active { + border-right: 2px solid var(--color-orange-1); + color: var(--color-orange-1); + } + .layout-left .item.active wc-icon { + color: var(--color-orange-1); + } + .layout-left .item.blank { + justify-content: center; + cursor: default; + } + + .layout-left .item.blank:hover { + background: none; + } + + .action { + display: flex; + align-items: center; + height: 50px; + padding: 0 10px; + } + `, + css` + .layout-right { + flex: 1; + display: flex; + flex-direction: column; + } + .layout-right .toolbar { + display: flex; + align-items: center; + justify-content: space-between; + height: 40px; + padding: 0 15px; + border-bottom: 1px solid var(--color-plain-3); + background: var(--color-plain-1); + } + `, + css` + .layout-right .main { + overflow: hidden; + flex: 1; + display: flex; + flex-direction: column; + padding: 8px; + background: #fff; + } + .layout-right .item { + display: flex; + align-items: center; + justify-content: center; + height: 40px; + padding: 0 4px; + border-bottom: 1px solid var(--color-plain-2); + text-align: center; + } + .layout-right .thead { + line-height: 40px; + } + .layout-right .item span { + flex: 1; + } + .layout-right .item .long { + flex: 1.5; + } + .layout-right wc-scroll { + overflow: hidden; + } + .layout-right .records { + flex: 1; + } + + .layout-right .item wc-input { + flex: 1; + min-width: 0; + --wc-input-border-color: transparent; + } + .layout-right .record-list .item .long { + flex: 1.5; + } + .layout-right .record-list .item wc-button { + margin-left: 5px; + } + .layout-right .record-list .item:last-child { + border-bottom: none; + } + `, + + css` + .context-menu { + display: flex; + flex-direction: column; + width: 100px; + padding: 5px 0; + background: #fff; + } + + .context-menu .item { + height: 30px; + line-height: 30px; + padding: 0 15px; + cursor: pointer; + } + + .context-menu .item :hover { + background: #f2f5fc; } ` ] + mounted() { + window.foo = this + // let hosts = getHistory() + // console.log(hosts) + // this.domains = Object.keys(hosts) + this.toggleDomain(null, this.activeDomain) + } + + addDomain() { + layer + .prompt('请输入根域名', function (val, done) { + if ( + val === 'localhost' || + val === 'local' || + /^[\w.\-]+\.[a-z]+$/.test(val) + ) { + done() + } else { + layer.toast('域名格式错误', 'error') + } + }) + .then(val => { + this.domains.push(val) + HOST_DATA[val] = [] + if (!this.activeDomain) { + this.toggleDomain(null, val) + } + this.save() + }) + .catch(noop) + } + + toggleDomain(ev, name) { + name = name || ev.currentTarget.dataset.name + this.activeDomain = name + + this.records = (HOST_DATA[name] || []).sort((a, b) => + a.record.localeCompare(b.record) + ) + + tmp_records = Object.create(null) + for (let it of this.records) { + if (tmp_records[it.record]) { + tmp_records[it.record].push(it) + } else { + tmp_records[it.record] = [it] + } + } + document.title = `伪域名解析 ${name} ` + localStorage.setItem('last_domain', name) + nextTick(() => { + this.$refs.records.scrollTop = 0 + }) + } + + showMenu(ev) { + this.$refs.context.close() + var { pageX, pageY } = ev + if (pageY + 70 > 600) { + pageY -= 70 + } + + var elem = ev.target + + if (elem.tagName !== 'LI') { + elem = elem.parentNode + } + this.editDomain = elem.dataset.name + nextTick(_ => { + this.$refs.context.moveTo({ left: pageX + 'px', top: pageY + 'px' }) + this.$refs.context.show() + }) + } + + confirmAction(ev) { + this.$refs.context.close() + if (ev.target.tagName === 'LI') { + var act = ev.target.dataset.act + + if (act === 'del') { + layer + .confirm(`是否要删除域名「${this.editDomain}」?`) + .then(res => { + if (this.editDomain === this.activeDomain) { + if (this.records.length) { + return layer.toast( + '该域名下有主机记录, 请先删除主机记录后再删除域名', + 'error' + ) + } + } else { + if (HOST_DATA[this.editDomain].length > 0) { + return layer.toast( + '该域名下有主机记录, 请先删除主机记录后再删除域名', + 'error' + ) + } + } + delete HOST_DATA[this.editDomain] + this.domains.remove(this.editDomain) + this.activeDomain = '' + this.editDomain = '' + this.records.clear() + this.save() + this.toggleDomain(this.domains[0]) + }) + .catch(noop) + } else if (act === 'edit') { + layer + .prompt(`请输入新的名字「${this.editDomain}」`, (val, done) => { + if (val === this.editDomain || HOST_DATA[val]) { + return + } + + if ( + val === 'localhost' || + val === 'local' || + /^[\w.]+\.[a-z]+$/.test(val) + ) { + done() + } else { + layer.toast('域名格式错误', 'error') + } + }) + .then(val => { + var idx = this.domains.indexOf(this.editDomain) + this.domains.set(idx, val) + HOST_DATA[val] = HOST_DATA[this.editDomain] + delete HOST_DATA[this.editDomain] + this.activeDomain = '' + this.editDomain = '' + this.save() + this.toggleDomain(val) + }) + .catch(noop) + } + } + } + + // 同一个记录, 允许一条被激活 + recordChanges(item) { + if (item.enabled) { + if (tmp_records[item.record].length > 1) { + for (let it of tmp_records[item.record]) { + if (it.value !== item.value) { + it.enabled = false + } + } + } + } + } + + save() { + if (this.activeDomain) { + HOST_DATA[this.activeDomain] = this.records + } + // electron.saveHosts(HOST_DATA) + layer.toast('保存成功', 'success') + } + render() { return html` -
-
- 镜像地址 -
-
+
+ +
    + ${this.domains.map( + it => html` +
  • + ${it} + +
  • + ` + )} + ${this.domains.length < 1 + ? html`
  • 没有域名
  • ` + : ''} +
+
+
+ +
+
+ +
+
+ 新增记录 + 保存 +
+ +
+
+ 主机记录 + 类型 + 记录值 + 操作 + 备注 +
+ + ${this.records.map( + it => html` +
+ + A + + + 删除 + 克隆 + + + +
+ ` + )} +
+
+
+ + + + +
    +
  • 删除域名
  • +
  • 修改域名
  • +
+
` } } diff --git a/usr/lib/hosts-switch/webapp/components/permission.js b/usr/lib/hosts-switch/webapp/components/permission.js new file mode 100644 index 0000000..ecaefba --- /dev/null +++ b/usr/lib/hosts-switch/webapp/components/permission.js @@ -0,0 +1,106 @@ +/** + * {} + * @author yutent + * @date 2023/08/08 18:19:17 + */ +import { html, css, Component } from 'wkit' + +const tips_header = `/************************************************************/ + * hosts文件没有写权限 * +/************************************************************/ +` + +class Permission extends Component { + static props = { + foo: '' + } + + static styles = css` + :host { + display: none; + } + .noselect { + -webkit-touch-callout: none; + -webkit-user-select: none; + user-select: none; + } + .permission-error { + position: fixed; + left: 0; + top: 0; + z-index: 1024; + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + height: 100%; + padding: 24px 52px; + line-height: 1.5; + background: rgba(255, 233, 233, 0.95); + -webkit-backdrop-filter: blur(5px); + } + + pre { + font-family: 'Courier New', Courier, monospace; + font-size: 14px; + color: var(--color-red-1); + } + + fieldset { + width: 600px; + padding: 0 30px 30px; + border: 1px solid var(--color-orange-1); + border-radius: 8px; + } + + legend { + padding: 0 10px; + font-size: 16px; + } + + dt { + margin-top: 20px; + font-weight: bold; + } + code { + display: block; + padding: 8px 10px; + margin-top: 8px; + border-left: 3px solid var(--color-plain-3); + background: rgba(255, 255, 255, 0.8); + font-family: 'Courier New', Courier, monospace; + } + ` + + check() { + // + } + + render() { + return html` +
+
${tips_header}
+
+ 操作指引 +
+
MacOS用户
+
打开终端, 执行以下命令
+
sudo chown $USER:admin /etc/hosts
+ +
Linux用户
+
打开终端, 执行以下命令
+
sudo chown $USER: /etc/hosts
+ +
完成之后
+
点击下面的按钮重新检测.
+
+ 权限检测 +
+
+
+
+ ` + } +} + +Permission.reg('permission') diff --git a/usr/lib/hosts-switch/webapp/css/reset.css b/usr/lib/hosts-switch/webapp/css/reset.css index 67179c8..6e3c7e6 100644 --- a/usr/lib/hosts-switch/webapp/css/reset.css +++ b/usr/lib/hosts-switch/webapp/css/reset.css @@ -33,7 +33,7 @@ body {font-family: 'Helvetica Neue', Arial, 'WenQuanYi Micro Hei', 'PingFang SC' code, pre, samp {font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;white-space:pre-wrap;} [anot],[\:repeat],[\:if] {visibility: hidden;} -.noselect {-webkit-touch-callout: none;-webkit-user-select: none;-moz-user-select: none;user-select: none;} +.noselect {-webkit-touch-callout: none;-webkit-user-select: none;user-select: none;} .noselect img, .noselect a {-webkit-user-drag: none;} .text-ell {overflow: hidden;white-space: nowrap;text-overflow: ellipsis;} .text-thin {-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;} diff --git a/usr/lib/hosts-switch/webapp/index.html b/usr/lib/hosts-switch/webapp/index.html index f23ff3e..7891349 100644 --- a/usr/lib/hosts-switch/webapp/index.html +++ b/usr/lib/hosts-switch/webapp/index.html @@ -29,7 +29,7 @@ - + \ No newline at end of file diff --git a/usr/lib/hosts-switch/webapp/lib/ui/form/button.js b/usr/lib/hosts-switch/webapp/lib/ui/form/button.js index 9a355b8..2e25ed1 100644 --- a/usr/lib/hosts-switch/webapp/lib/ui/form/button.js +++ b/usr/lib/hosts-switch/webapp/lib/ui/form/button.js @@ -1,64 +1,6 @@ -import { css, html, Component, nextTick, styleMap } from "wkit"; -import "../icon/index.js"; -class Button extends Component { - static props = { - icon: "", - autofocus: false, - loading: { - type: Boolean, - observer(val) { - if (val) { - this.cacheIcon = this.icon; - this.icon = "loading"; - } else { - this.icon = this.cacheIcon === void 0 ? this.icon : this.cacheIcon; - } - } - }, - disabled: false, - lazy: "num!0" - // 并发拦截时间, 单位毫秒 - }; - static styles = [ - // 基础样式 - css`:host{overflow:hidden;display:inline-flex;min-width:108px;height:32px;border:0;border-radius:3px;user-select:none;-moz-user-select:none;color:var(--color-dark-1);font-size:14px;cursor:pointer;transition:box-shadow .15s linear}:host button{display:flex;justify-content:center;align-items:center;width:100%;min-width:1px;height:inherit;padding:var(--wc-button-padding, 0 4px);line-height:1;border:1px solid var(--wc-button-border-color, var(--color-grey-2));border-radius:inherit;white-space:nowrap;background:var(--wc-button-background, #fff);font-size:inherit;font-family:inherit;outline:none;color:var(--wc-button-color, var(--color-dark-1));cursor:inherit;transition:background .15s linear,color .15s linear}:host button::-moz-focus-inner{border:none}:host button:hover{color:var(--wc-button-color-hover, var(--color-grey-3));border-color:var(--wc-button-border-color-hover, var(--color-grey-3));background:var(--wc-button-background-hover, var(--wc-button-background, #fff))}:host button:active{color:var(--wc-button-color-active, var(--color-dark-2));background:var(--wc-button-background-active, var(--wc-button-background, #fff))}:host button:disabled{color:var(--wc-button-color-disabled, var(--color-dark-1));background:var(--wc-button-background-disabled, var(--wc-button-background, #fff))}:host .icon{margin-right:4px;--wc-icon-size: var(--wc-button-icon-size, 14px)}:host([solid]) button{border:0;color:#fff;background:var(--color-dark-1)}:host([solid]) button:hover{background:var(--color-grey-3)}:host([solid]) button:active{background:var(--color-dark-2)}:host([solid]) button:disabled{background:var(--color-dark-1)}:host(:focus-within){box-shadow:0 0 0 2px var(--color-plain-a)}:host(:empty) button .icon{margin-right:0}`, - // 尺寸 - css`:host([size=s]){min-width:52px;height:20px;font-size:12px}:host([size=s]) .icon{--wc-icon-size: var(--wc-button-icon-size, 12px)}:host([size=s][circle]){width:20px;height:20px}:host([size=m]){min-width:72px;height:24px;font-size:12px}:host([size=m]) .icon{--wc-icon-size: var(--wc-button-icon-size, 12px)}:host([size=m][circle]){width:24px;height:24px}:host([size=xl]){min-width:132px;height:36px;font-size:14px}:host([size=xl]) .icon{--wc-icon-size: var(--wc-button-icon-size, 14px)}:host([size=xl][circle]){width:36px;height:36px}:host([size=xxl]){min-width:160px;height:44px;font-size:14px}:host([size=xxl]) .icon{--wc-icon-size: var(--wc-button-icon-size, 14px)}:host([size=xxl][circle]){width:44px;height:44px}:host([dashed]) button{border-style:dashed}:host([round]){border-radius:32px}:host([circle]){min-width:0;width:32px;height:32px;border-radius:50%}:host([circle]) button{padding:0}:host([circle]) .icon{margin-right:0}:host([circle]) slot{display:none}`, - // 配色 - css`:host([type=primary]) button{color:var(--color-teal-2);border-color:var(--color-teal-1)}:host([type=primary]) button:hover{color:var(--color-teal-1);border-color:var(--color-teal-2);background:var(--wc-button-background, #fff)}:host([type=primary]) button:active{color:var(--color-teal-3);background:var(--wc-button-background, #fff)}:host([type=primary]) button:disabled{color:var(--color-teal-2);background:var(--wc-button-background, #fff)}:host([type=primary]):host([solid]) button{border:0;color:#fff;background:var(--color-teal-2)}:host([type=primary]):host([solid]) button:hover{background:var(--color-teal-1)}:host([type=primary]):host([solid]) button:active{background:var(--color-teal-3)}:host([type=primary]):host([solid]) button:disabled{background:var(--color-teal-2)}:host([type=primary]):host(:focus-within){box-shadow:0 0 0 2px var(--color-teal-a)}:host([type=info]) button{color:var(--color-blue-2);border-color:var(--color-blue-1)}:host([type=info]) button:hover{color:var(--color-blue-1);border-color:var(--color-blue-2);background:var(--wc-button-background, #fff)}:host([type=info]) button:active{color:var(--color-blue-3);background:var(--wc-button-background, #fff)}:host([type=info]) button:disabled{color:var(--color-blue-2);background:var(--wc-button-background, #fff)}:host([type=info]):host([solid]) button{border:0;color:#fff;background:var(--color-blue-2)}:host([type=info]):host([solid]) button:hover{background:var(--color-blue-1)}:host([type=info]):host([solid]) button:active{background:var(--color-blue-3)}:host([type=info]):host([solid]) button:disabled{background:var(--color-blue-2)}:host([type=info]):host(:focus-within){box-shadow:0 0 0 2px var(--color-blue-a)}:host([type=success]) button{color:var(--color-green-2);border-color:var(--color-green-1)}:host([type=success]) button:hover{color:var(--color-green-1);border-color:var(--color-green-2);background:var(--wc-button-background, #fff)}:host([type=success]) button:active{color:var(--color-green-3);background:var(--wc-button-background, #fff)}:host([type=success]) button:disabled{color:var(--color-green-2);background:var(--wc-button-background, #fff)}:host([type=success]):host([solid]) button{border:0;color:#fff;background:var(--color-green-2)}:host([type=success]):host([solid]) button:hover{background:var(--color-green-1)}:host([type=success]):host([solid]) button:active{background:var(--color-green-3)}:host([type=success]):host([solid]) button:disabled{background:var(--color-green-2)}:host([type=success]):host(:focus-within){box-shadow:0 0 0 2px var(--color-green-a)}:host([type=warning]) button{color:var(--color-orange-2);border-color:var(--color-orange-1)}:host([type=warning]) button:hover{color:var(--color-orange-1);border-color:var(--color-orange-2);background:var(--wc-button-background, #fff)}:host([type=warning]) button:active{color:var(--color-orange-3);background:var(--wc-button-background, #fff)}:host([type=warning]) button:disabled{color:var(--color-orange-2);background:var(--wc-button-background, #fff)}:host([type=warning]):host([solid]) button{border:0;color:#fff;background:var(--color-orange-2)}:host([type=warning]):host([solid]) button:hover{background:var(--color-orange-1)}:host([type=warning]):host([solid]) button:active{background:var(--color-orange-3)}:host([type=warning]):host([solid]) button:disabled{background:var(--color-orange-2)}:host([type=warning]):host(:focus-within){box-shadow:0 0 0 2px var(--color-orange-a)}:host([type=danger]) button{color:var(--color-red-2);border-color:var(--color-red-1)}:host([type=danger]) button:hover{color:var(--color-red-1);border-color:var(--color-red-2);background:var(--wc-button-background, #fff)}:host([type=danger]) button:active{color:var(--color-red-3);background:var(--wc-button-background, #fff)}:host([type=danger]) button:disabled{color:var(--color-red-2);background:var(--wc-button-background, #fff)}:host([type=danger]):host([solid]) button{border:0;color:#fff;background:var(--color-red-2)}:host([type=danger]):host([solid]) button:hover{background:var(--color-red-1)}:host([type=danger]):host([solid]) button:active{background:var(--color-red-3)}:host([type=danger]):host([solid]) button:disabled{background:var(--color-red-2)}:host([type=danger]):host(:focus-within){box-shadow:0 0 0 2px var(--color-red-a)}`, - // 状态 - css`:host([loading]),:host([disabled]){cursor:not-allowed;opacity:.6}` - ]; - created() { - this.stamp = 0; - this._clickFn = this.$on( - "click", - (ev) => { - let { loading, disabled, lazy } = this; - let now = Date.now(); - if (loading || disabled) { - return ev.stopPropagation(); - } - if (lazy > 0 && now - this.stamp < lazy) { - return ev.stopPropagation(); - } - this.stamp = now; - }, - true - ); - } - mounted() { - if (this.autofocus) { - nextTick((_) => this.$refs.btn.focus()); - } - } - render() { - return html` - - `; - } -} -Button.reg("button"); + `}}l.reg("button"); diff --git a/usr/lib/hosts-switch/webapp/lib/ui/form/input.js b/usr/lib/hosts-switch/webapp/lib/ui/form/input.js index 34bbdf2..aae8b33 100644 --- a/usr/lib/hosts-switch/webapp/lib/ui/form/input.js +++ b/usr/lib/hosts-switch/webapp/lib/ui/form/input.js @@ -1,44 +1,4 @@ -import { nextTick, css, html, Component, classMap, outsideClick } from "wkit"; -import "../icon/index.js"; -const ANIMATION = { - duration: 100, - custom: [ - { transform: "scaleY(0)", opacity: 0 }, - { transform: "scaleY(1)", opacity: 1 } - ] -}; -class Input extends Component { - static props = { - readOnly: false, - autofocus: false, - disabled: false, - clearable: false, - icon: "", - placeholder: "", - maxlength: { type: Number, default: null }, - minlength: { type: Number, default: null }, - value: "str!", - lazy: "num!0" - // 并发拦截时间, 单位毫秒 - }; - #list = []; - #selectIndex = -1; - #listShowing = false; - #stamp = 0; - static styles = [ - css`:host{position:relative;display:inline-flex;min-width:188px;height:32px;user-select:none;-moz-user-select:none;color:var(--color-dark-1);border-radius:3px;cursor:text;transition:box-shadow .15s linear}.label{flex:1;display:flex;justify-content:center;align-items:center;height:100%;font-size:14px;border:1px solid var(--wc-input-border-color, var(--color-grey-2));border-radius:inherit;background:var(--bg-color, #fff);color:inherit;cursor:inherit}.label input{flex:1;min-width:36px;width:0;height:100%;padding:0 8px;border:0;border-radius:inherit;font:inherit;color:inherit;background:none;outline:none;box-shadow:none;cursor:inherit}.label input::placeholder{color:var(--color-grey-1)}.label .close{--wc-icon-size: 18px;margin:0 8px 0 4px;padding:4px;border-radius:50%;color:var(--color-grey-2);cursor:pointer;transition:background .15s linear}.label .close:hover{background:var(--color-plain-1)}.label .icon{--wc-icon-size: 16px;margin:0 8px 0 4px;color:var(--color-grey-2)}.suggestion{overflow:hidden;position:absolute;z-index:1;left:0;top:calc(100% + 4px);width:100%;padding:4px 0;border-radius:4px;box-shadow:0 2px 5px rgba(0,0,0,.15);transform-origin:top}.suggestion .list{width:100%;background:#fff}.suggestion.hide{display:none}.suggestion li{overflow:hidden;width:100%;height:30px;line-height:30px;padding:0 8px;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.suggestion li:hover,.suggestion li[focus]{background:var(--color-plain-2)}:host([round]){border-radius:26px}:host([round]) .label input{padding:0 10px}:host(:focus-within){box-shadow:0 0 0 2px var(--color-plain-a)}:host([disabled]){pointer-events:none;cursor:not-allowed}:host([disabled]) .label{border-color:var(--color-grey-1);background:var(--color-plain-1);opacity:.6}:host([readonly]){cursor:default}`, - //尺寸 - css`:host([size=m]){min-width:128px;height:24px;font-size:12px}:host([size=m]) .label{height:24px;font-size:12px}:host([size=m]) .icon{--wc-icon-size: 12px}:host([size=m][circle]){width:24px;height:24px}:host([size=xl]){min-width:224px;height:36px;font-size:14px}:host([size=xl]) .label{height:36px;font-size:14px}:host([size=xl]) .icon{--wc-icon-size: 14px}:host([size=xl][circle]){width:36px;height:36px}:host([size=xxl]){min-width:288px;height:44px;font-size:14px}:host([size=xxl]) .label{height:44px;font-size:14px}:host([size=xxl]) .icon{--wc-icon-size: 14px}:host([size=xxl][circle]){width:44px;height:44px}` - ]; - renderClear() { - return html``; - } - render() { - let classes = classMap({ - suggestion: true, - hide: !this.#list.length - }); - return html` +import{nextTick as r,css as l,html as s,Component as a,classMap as h,outsideClick as c}from"wkit";import"../icon/index.js";const d={duration:100,custom:[{transform:"scaleY(0)",opacity:0},{transform:"scaleY(1)",opacity:1}]};class u extends a{static props={readOnly:!1,autofocus:!1,disabled:!1,clearable:!1,icon:"",placeholder:"",maxlength:{type:Number,default:null},minlength:{type:Number,default:null},value:"str!",lazy:"num!0"};#t=[];#e=-1;#i=!1;#s=0;static styles=[l`:host{position:relative;display:inline-flex;min-width:188px;height:32px;user-select:none;-moz-user-select:none;color:var(--color-dark-1);border-radius:3px;cursor:text;transition:box-shadow .15s linear}.label{flex:1;display:flex;justify-content:center;align-items:center;height:100%;font-size:14px;border:1px solid var(--wc-input-border-color, var(--color-grey-2));border-radius:inherit;background:var(--bg-color, #fff);color:inherit;cursor:inherit}.label input{flex:1;min-width:36px;width:0;height:100%;padding:0 8px;line-height:1;border:0;border-radius:inherit;font:inherit;color:inherit;background:none;outline:none;box-shadow:none;cursor:inherit}.label input::placeholder{color:var(--color-grey-1)}.label .close{--wc-icon-size: 18px;margin:0 8px 0 4px;padding:4px;border-radius:50%;color:var(--color-grey-2);cursor:pointer;transition:background .15s linear}.label .close:hover{background:var(--color-plain-1)}.label .icon{--wc-icon-size: 16px;margin:0 8px 0 4px;color:var(--color-grey-2)}.suggestion{overflow:hidden;position:absolute;z-index:1;left:0;top:calc(100% + 4px);width:100%;padding:4px 0;border-radius:4px;box-shadow:0 2px 5px rgba(0,0,0,.15);transform-origin:top}.suggestion .list{width:100%;background:#fff}.suggestion.hide{display:none}.suggestion li{overflow:hidden;width:100%;height:30px;line-height:30px;padding:0 8px;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.suggestion li:hover,.suggestion li[focus]{background:var(--color-plain-2)}:host([round]){border-radius:26px}:host([round]) .label input{padding:0 10px}:host(:focus-within){box-shadow:0 0 0 2px var(--color-plain-a)}:host([disabled]){pointer-events:none;cursor:not-allowed}:host([disabled]) .label{border-color:var(--color-grey-1);background:var(--color-plain-1);opacity:.6}:host([readonly]){cursor:default}`,l`:host([size=m]){min-width:128px;height:24px;font-size:12px}:host([size=m]) .label{height:24px;font-size:12px}:host([size=m]) .icon{--wc-icon-size: 12px}:host([size=m][circle]){width:24px;height:24px}:host([size=xl]){min-width:224px;height:36px;font-size:14px}:host([size=xl]) .label{height:36px;font-size:14px}:host([size=xl]) .icon{--wc-icon-size: 14px}:host([size=xl][circle]){width:36px;height:36px}:host([size=xxl]){min-width:288px;height:44px;font-size:14px}:host([size=xxl]) .label{height:44px;font-size:14px}:host([size=xxl]) .icon{--wc-icon-size: 14px}:host([size=xxl][circle]){width:44px;height:44px}`];renderClear(){return s``}render(){let e=h({suggestion:!0,hide:!this.#t.length});return s`
@@ -57,115 +17,19 @@ class Input extends Component { autofocus=${this.autofocus} :value=${this.value} /> - ${this.clearable && this.value ? this.renderClear() : ""} + ${this.clearable&&this.value?this.renderClear():""} -
+
    - ${this.#list.map( - (li, idx) => html`
  • s`
  • - ${li.value} -
  • ` - )} + ${t.value} + `)}
- `; - } - handleInput(e) { - let { lazy } = this; - this.value = e.currentTarget.value; - if (lazy && Date.now() - this.#stamp < lazy) { - return; - } - this.#stamp = Date.now(); - this.emitFetchSuggest(); - } - handleClickItem(e) { - let index = e.target.getAttribute("index"); - this.#selectIndex = index; - this.emitSelect(); - } - clear() { - this.$refs.input.value = ""; - this.value = ""; - this.$emit("change"); - this.$emit("input"); - } - handleChange() { - this.$emit("change"); - } - handleKeyDown(e) { - let { lazy, minlength, value } = this; - if (e.keyCode === 13) { - e.preventDefault(); - if (this.#selectIndex > -1 && this.#listShowing) { - return this.emitSelect(); - } - if (lazy && Date.now() - this.#stamp < lazy) { - return; - } - this.#stamp = Date.now(); - if (minlength && value.length < minlength) { - return; - } - return this.$emit("submit"); - } - if (e.keyCode === 38 || e.keyCode === 40) { - e.preventDefault(); - let step = e.keyCode === 38 ? -1 : 1; - this.#selectIndex += step; - if (this.#selectIndex < 0) { - this.#selectIndex = 0; - } - if (this.#selectIndex > this.#list.length - 1) { - this.#selectIndex = this.#list.length - 1; - } - this.$requestUpdate(); - } - } - // 触发列表选择 - emitSelect() { - let item = this.#list[this.#selectIndex]; - this.value = item.value; - this.$refs.suggestion.$animate(true); - this.#listShowing = false; - this.$requestUpdate(); - this.$emit("change"); - this.$emit("input"); - this.$emit("select", { - index: this.#selectIndex, - value: item - }); - } - emitFetchSuggest() { - this.$emit("fetch-suggest", { - value: this.value, - send: (list) => { - this.#list = list.slice(0, 10); - this.#selectIndex = -1; - this.$requestUpdate(); - } - }); - } - handleFocus() { - if (!this.#listShowing) { - this.#listShowing = true; - this.$refs.suggestion.$animate(); - } - } - mounted() { - if (this.autofocus) { - nextTick((_) => this.$refs.input.focus()); - } - outsideClick(this, () => { - this.#listShowing = false; - this.$refs.suggestion.$animate(true); - }); - } -} -Input.reg("input"); + `}handleInput(e){let{lazy:t}=this;this.value=e.currentTarget.value,!(t&&Date.now()-this.#s-1&&this.#i?this.emitSelect():t&&Date.now()-this.#sthis.#t.length-1&&(this.#e=this.#t.length-1),this.$requestUpdate()}}emitSelect(){let e=this.#t[this.#e];this.value=e.value,this.$refs.suggestion.$animate(!0),this.#i=!1,this.$requestUpdate(),this.$emit("change"),this.$emit("input"),this.$emit("select",{index:this.#e,value:e})}emitFetchSuggest(){this.$emit("fetch-suggest",{value:this.value,send:e=>{this.#t=e.slice(0,10),this.#e=-1,this.$requestUpdate()}})}handleFocus(){this.#i||(this.#i=!0,this.$refs.suggestion.$animate())}mounted(){this.autofocus&&r(e=>this.$refs.input.focus()),c(this,()=>{this.#i=!1,this.$refs.suggestion.$animate(!0)})}}u.reg("input"); diff --git a/usr/lib/hosts-switch/webapp/lib/ui/form/link.js b/usr/lib/hosts-switch/webapp/lib/ui/form/link.js new file mode 100644 index 0000000..5a515fb --- /dev/null +++ b/usr/lib/hosts-switch/webapp/lib/ui/form/link.js @@ -0,0 +1,5 @@ +import{css as r,html as s,Component as l,bind as i,nextTick as n}from"wkit";class c extends l{static props={type:"primary",to:"",autofocus:!1,disabled:!1,lazy:0};static styles=[r`:host{position:relative;display:inline-flex;border-radius:2px;user-select:none;-moz-user-select:none;font-size:inherit;cursor:pointer;transition:box-shadow .15s linear}:host .link{display:flex;justify-content:center;align-items:center;width:100%;padding:var(--padding, 0 2px);line-height:1;font-size:inherit;font-family:inherit;outline:none;color:inherit;cursor:inherit;text-decoration:none;transition:color .15s linear}:host .link::-moz-focus-inner{border:none}:host::after{position:absolute;bottom:-2px;left:0;width:100%;height:1px;border-bottom:1px dashed rgba(0,0,0,0);content:"";opacity:0;transition:opacity .15s linear}`,r`:host([type=primary]){color:var(--color-teal-2)}:host([type=primary])::after{border-color:var(--color-teal-1)}:host([type=primary]:not([disabled]):hover){color:var(--color-teal-1)}:host([type=primary]:not([disabled]):active){color:var(--color-teal-3)}:host([type=primary]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-teal-a)}:host([type=info]){color:var(--color-blue-2)}:host([type=info])::after{border-color:var(--color-blue-1)}:host([type=info]:not([disabled]):hover){color:var(--color-blue-1)}:host([type=info]:not([disabled]):active){color:var(--color-blue-3)}:host([type=info]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-blue-a)}:host([type=success]){color:var(--color-green-2)}:host([type=success])::after{border-color:var(--color-green-1)}:host([type=success]:not([disabled]):hover){color:var(--color-green-1)}:host([type=success]:not([disabled]):active){color:var(--color-green-3)}:host([type=success]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-green-a)}:host([type=warning]){color:var(--color-orange-2)}:host([type=warning])::after{border-color:var(--color-orange-1)}:host([type=warning]:not([disabled]):hover){color:var(--color-orange-1)}:host([type=warning]:not([disabled]):active){color:var(--color-orange-3)}:host([type=warning]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-orange-a)}:host([type=danger]){color:var(--color-red-2)}:host([type=danger])::after{border-color:var(--color-red-1)}:host([type=danger]:not([disabled]):hover){color:var(--color-red-1)}:host([type=danger]:not([disabled]):active){color:var(--color-red-3)}:host([type=danger]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-red-a)}:host([type=secondary]){color:var(--color-dark-2)}:host([type=secondary])::after{border-color:var(--color-dark-1)}:host([type=secondary]:not([disabled]):hover){color:var(--color-dark-1)}:host([type=secondary]:not([disabled]):active){color:var(--color-dark-3)}:host([type=secondary]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-dark-a)}:host([type=help]){color:var(--color-grey-2)}:host([type=help])::after{border-color:var(--color-grey-1)}:host([type=help]:not([disabled]):hover){color:var(--color-grey-1)}:host([type=help]:not([disabled]):active){color:var(--color-grey-3)}:host([type=help]:not([disabled]):focus-within){box-shadow:0 0 0 2px var(--color-grey-a)}`,r`:host(:not([disabled]):hover)::after,:host([underline])::after{opacity:1}:host([disabled]){cursor:not-allowed;opacity:.6}`];mounted(){this.stamp=0,this.autofocus&&n(o=>this.$refs.a.focus()),this._clickFn=i(this.$refs.a,"click",o=>{let{disabled:a,lazy:e}=this,t=Date.now();if(a){o.preventDefault(),o.stopPropagation();return}if(e>0&&t-this.stamp + + + `}}c.reg("link"); diff --git a/usr/lib/hosts-switch/webapp/lib/ui/form/switch.js b/usr/lib/hosts-switch/webapp/lib/ui/form/switch.js index 3f71fc7..96f8ea6 100644 --- a/usr/lib/hosts-switch/webapp/lib/ui/form/switch.js +++ b/usr/lib/hosts-switch/webapp/lib/ui/form/switch.js @@ -1,61 +1,13 @@ -import { nextTick, css, html, Component, classMap } from "wkit"; -class Switch extends Component { - static props = { - value: { - type: Boolean, - default: false - }, - inactiveText: "", - activeText: "", - inlineText: false, - disabled: false, - readonly: false - }; - static styles = [ - css`:host{display:inline-flex;align-items:center;font-size:14px;cursor:pointer}:host label{display:flex;justify-content:center;align-items:center;min-width:32px;padding-right:16px;line-height:1;-moz-user-select:none;user-select:none;white-space:nowrap;cursor:inherit;outline:none;color:var(--color-dark-1)}:host .dot{display:flex;align-items:center;justify-content:space-between;min-width:36px;height:18px;padding:0 4px;margin-right:5px;line-height:14px;border-radius:16px;background:var(--color-plain-3);transition:box-shadow .2s ease,background .2s ease}:host .dot::before{display:block;width:14px;height:14px;border-radius:50%;background:#fff;content:""}:host .dot::after{display:flex;padding:0 2px;font-size:12px;content:attr(st);color:#fff}:host .dot.open{flex-direction:row-reverse;background:var(--color-teal-1)}`, - css`:host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-plain-a)}`, - // 尺寸 - css`:host([size=m]){height:24px;font-size:12px}:host([size=m]) .dot{min-width:30px;height:16px;line-height:12px}:host([size=m]) .dot::before{width:12px;height:12px}:host([size=xl]){height:36px;font-size:14px}:host([size=xl]) .dot{min-width:35px;height:18px;line-height:14px}:host([size=xl]) .dot::before{width:14px;height:14px}:host([size=xxl]){height:44px;font-size:14px}:host([size=xxl]) .dot{min-width:35px;height:18px;line-height:14px}:host([size=xxl]) .dot::before{width:14px;height:14px}`, - // 配色 - css`:host([type=primary]) .dot.open{background:var(--color-teal-1)}:host([type=primary]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-teal-a)}:host([type=info]) .dot.open{background:var(--color-blue-1)}:host([type=info]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-blue-a)}:host([type=success]) .dot.open{background:var(--color-green-1)}:host([type=success]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-green-a)}:host([type=warning]) .dot.open{background:var(--color-orange-1)}:host([type=warning]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-orange-a)}:host([type=danger]) .dot.open{background:var(--color-red-1)}:host([type=danger]):host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-red-a)}`, - // 状态 - css`:host([readonly]),:host([disabled]){cursor:not-allowed;opacity:.6}:host([readonly]){cursor:default}` - ]; - toggleCheck(ev) { - if (this.disabled || this.readOnly) { - return; - } - ev.stopPropagation(); - this.value = !this.value; - let data = { - value: this.value - }; - this.$emit("input"); - this.$emit("change", data); - } - handleClick(ev) { - if (ev.type === "click" || ev.keyCode === 32) { - ev.preventDefault(); - this.toggleCheck(ev); - } - } - mounted() { - } - render() { - let classes = classMap({ dot: true, open: this.value }); - return html` - `; - } -} -Switch.reg("switch"); + `}}n.reg("switch"); diff --git a/usr/lib/hosts-switch/webapp/lib/ui/layer/index.js b/usr/lib/hosts-switch/webapp/lib/ui/layer/index.js index 7e658c7..707b92c 100644 --- a/usr/lib/hosts-switch/webapp/lib/ui/layer/index.js +++ b/usr/lib/hosts-switch/webapp/lib/ui/layer/index.js @@ -1,201 +1,13 @@ -import { css, html, Component, bind, styleMap } from "wkit"; -import "../form/input.js"; -let uniqueInstance = null; -let toastInstance = null; -const LANG_TITLE = "\u63D0\u793A"; -const LANG_BTNS = ["\u53D6\u6D88", "\u786E\u5B9A"]; -const UNIQUE_TYPES = ["alert", "confirm", "prompt"]; -const BUILDIN_TYPES = UNIQUE_TYPES.concat(["toast"]); -class Layer extends Component { - static animation = {}; - static props = { - type: { - type: String, - default: null, - observer(v) { - this.#wrapped = !BUILDIN_TYPES.includes(v); - } - }, - left: { type: String, attribute: false }, - right: { type: String, attribute: false }, - top: { type: String, attribute: false }, - bottom: { type: String, attribute: false }, - background: { type: String, attribute: false }, - maskColor: { type: String, attribute: false }, - mask: false, - maskClose: false, - title: { type: String, default: "", attribute: false }, - content: { type: String, default: "", attribute: false }, - btns: [] - }; - static styles = [ - css`:host{display:none;justify-content:center;align-items:center;position:fixed;z-index:65534;left:0;top:0;width:100%;height:0}:host([type]){display:flex}:host([type=toast]) .layer,:host([type=common]) .layer{position:absolute}.noselect{-webkit-touch-callout:none;user-select:none}.noselect img,.noselect a{-webkit-user-drag:none}`, - css`.layer{flex:0 auto;position:relative;z-index:65535;border-radius:3px;color:#666;font-size:14px;background:rgba(255,255,255,.8);box-shadow:0 5px 20px rgba(0,0,0,.3);transition:opacity .2s ease-in-out,left .2s ease-in-out,right .2s ease-in-out,top .2s ease-in-out,bottom .2s ease-in-out}.layer:active{z-index:65536}`, - /* 弹层样式 */ - css`.layer__title{display:flex;justify-content:space-between;align-items:center;width:100%;height:60px;padding:15px;font-size:16px;color:var(--color-dark-2)}.layer__title wc-icon{--wc-icon-size: 14px}.layer__title wc-icon:hover{color:var(--color-red-1)}.layer__content{display:flex;position:relative;width:100%;height:auto;min-height:50px;word-break:break-all;word-wrap:break-word}::slotted(.layer__content__input){flex:1}::slotted(.layer__content__toast){flex-shrink:0;flex:1;display:flex;align-items:center;width:300px;min-height:40px;margin-bottom:15px !important;padding:0 10px !important;border-radius:3px;font-weight:normal;text-indent:8px;--wc-icon-size: 16px;color:var(--color-dark-1);box-shadow:0 2px 12px rgba(0,0,0,.1)}::slotted(.layer__content__toast+.layer__content__toast){margin-top:30px}::slotted(.layer__content__toast.style-info){border:1px solid #ebeef5;background:#edf2fc;color:var(--color-grey-3)}::slotted(.layer__content__toast.style-success){border:1px solid #e1f3d8;background:#f0f9eb;color:var(--color-green-3)}::slotted(.layer__content__toast.style-warning){border:1px solid #faebb4;background:#faecd8;color:var(--color-red-1)}::slotted(.layer__content__toast.style-error){border:1px solid #f5c4c4;background:#fde2e2;color:var(--color-red-1)}.layer__ctrl{display:flex;justify-content:flex-end;width:100%;height:60px;padding:15px;line-height:30px;font-size:14px;color:#454545;text-align:right}.layer__ctrl button{min-width:64px;height:30px;padding:0 10px;margin:0 5px;border:1px solid var(--color-plain-3);border-radius:3px;white-space:nowrap;background:#fff;font-size:inherit;font-family:inherit;outline:none;color:inherit}.layer__ctrl button:hover{background:var(--color-plain-1)}.layer__ctrl button:active{border-color:var(--color-grey-1)}.layer__ctrl button:focus{box-shadow:0 0 0 2px var(--color-plain-a)}.layer__ctrl button:last-child{color:#fff;background:var(--color-teal-2);border-color:rgba(0,0,0,0)}.layer__ctrl button:last-child:hover{background:var(--color-teal-1)}.layer__ctrl button:last-child:active{background:var(--color-teal-3)}.layer__ctrl button:last-child:focus{box-shadow:0 0 0 2px var(--color-teal-a)}.layer__ctrl button::-moz-focus-inner{border:none}`, - css`:host([mask]){height:100%;background:rgba(0,0,0,.2)}:host([type=alert]) .layer,:host([type=confirm]) .layer,:host([type=prompt]) .layer{max-width:600px;min-width:300px;background:#fff}:host([type=alert]) .layer__content,:host([type=confirm]) .layer__content,:host([type=prompt]) .layer__content{padding:0 15px}:host([type=toast]) .layer{box-shadow:none;background:none}:host([type=toast]) .layer__content{flex-direction:column;min-height:40px}:host([blurry]) .layer{backdrop-filter:blur(5px)}` - ]; - #wrapped = false; - #resolve = null; - #reject = null; - constructor() { - super(); - this.promise = new Promise((resolve, reject) => { - this.#resolve = resolve; - this.#reject = reject; - }); - this.promise.host = this; - } - #intercept(value) { - if (this.intercept) { - this.intercept(value, (_) => { - delete this.intercept; - this.#resolve(value); - this.$animate(true); - this.$refs.box.$animate(true).then((_2) => this.close()); - }); - } else { - this.#resolve(value); - this.$animate(true); - this.$refs.box.$animate(true).then((_) => this.close()); - } - } - #play() { - switch (this.type) { - case "toast": - let elem = this.lastElementChild; - elem._anim = elem.animate( - [ - { marginTop: "-30px", opacity: 0 }, - { marginTop: "0", opacity: 1 } - ], - { - duration: 200, - fill: "forwards" - } - ); - setTimeout(() => { - elem._anim.reverse(); - elem._anim.onfinish = (_) => { - elem.remove(); - if (this.children.length === 0) { - this.close(); - toastInstance = null; - } - }; - }, 3e3); - break; - default: - this.$animate(); - this.$refs.box.$animate(); - break; - } - } - mounted() { - if (this.type === "prompt") { - this.$refs.input = this.firstElementChild; - bind(this.$refs.input, "submit", (ev) => { - this.#intercept(ev.target.value); - }); - } else if (this.type === "toast") { - this.style.display = ""; - } - if (this.mask) { - this.$on("click", (ev) => { - let path = ev.composedPath(); - if (path[0] === ev.currentTarget) { - if (UNIQUE_TYPES.includes(this.type)) { - return; - } - if (this.maskClose) { - if (this.#wrapped === false) { - this.#reject(); - } - this.$refs.box.$animate(true).then((_) => this.close()); - } - } - }); - if (this.maskColor) { - this.style.backgroundColor = this.maskColor; - } - } - if (this.background) { - this.$refs.box.style.backgroundColor = this.background; - } - this.#play(); - } - updated() { - this.#play(); - } - moveTo(obj = {}) { - var css2 = ""; - for (var k in obj) { - css2 += `${k}:${obj[k]};`; - } - this.$refs.box.style.cssText += css2; - } - show() { - if (this.#wrapped) { - this.type = "common"; - } - } - /** - * 关闭实例 - */ - close() { - if (this.#wrapped) { - this.type = null; - this.$emit("close"); - } else { - if (UNIQUE_TYPES.includes(this.type)) { - uniqueInstance = null; - } - this.$emit("close"); - this.remove(); - } - } - // 按钮的点击事件 - handleBtnClick(ev) { - if (ev.target.tagName === "BUTTON") { - let idx = +ev.target.dataset.idx || 0; - switch (this.type) { - case "alert": - this.#intercept(null); - break; - case "confirm": - case "prompt": - if (idx === 0) { - this.#reject(); - this.$animate(true); - this.$refs.box.$animate(true).then((_) => this.close()); - } else { - let value = this.type === "prompt" ? this.$refs.input.value : null; - this.#intercept(value); - } - break; - default: - this.#intercept(idx); - break; - } - } - } - render() { - let { type, mask, left, right, top, bottom } = this; - let styles = ""; - if (type === "common" && mask === false) { - top = top || 0; - } - styles = styleMap({ left, right, top, bottom }); - return html` +import{css as c,html as y,Component as x,bind as g,styleMap as d}from"wkit";import"../form/input.js";let s=null,p=null;const a="\u63D0\u793A",u=["\u53D6\u6D88","\u786E\u5B9A"],h=["alert","confirm","prompt"],k=h.concat(["toast"]);class w extends x{static animation={};static props={type:{type:String,default:null,observer(t){this.#t=!k.includes(t)}},left:{type:String,attribute:!1},right:{type:String,attribute:!1},top:{type:String,attribute:!1},bottom:{type:String,attribute:!1},background:{type:String,attribute:!1},maskColor:{type:String,attribute:!1},mask:!1,maskClose:!1,title:{type:String,default:"",attribute:!1},content:{type:String,default:"",attribute:!1},btns:[]};static styles=[c`:host{display:none;justify-content:center;align-items:center;position:fixed;z-index:65534;left:0;top:0;width:100%;height:0}:host([type]){display:flex}:host([type=toast]) .layer,:host([type=common]) .layer{position:absolute}.noselect{-webkit-touch-callout:none;user-select:none}.noselect img,.noselect a{-webkit-user-drag:none}`,c`.layer{flex:0 auto;position:relative;z-index:65535;border-radius:3px;color:#666;font-size:14px;background:rgba(255,255,255,.8);box-shadow:0 5px 20px rgba(0,0,0,.3);transition:opacity .2s ease-in-out,left .2s ease-in-out,right .2s ease-in-out,top .2s ease-in-out,bottom .2s ease-in-out}.layer:active{z-index:65536}`,c`.layer__title{display:flex;justify-content:space-between;align-items:center;width:100%;height:60px;padding:15px;font-size:16px;color:var(--color-dark-2)}.layer__title wc-icon{--wc-icon-size: 14px}.layer__title wc-icon:hover{color:var(--color-red-1)}.layer__content{display:flex;position:relative;width:100%;height:auto;min-height:50px;word-break:break-all;word-wrap:break-word}::slotted(.layer__content__input){flex:1}::slotted(.layer__content__toast){flex-shrink:0;flex:1;display:flex;align-items:center;width:300px;min-height:40px;margin-bottom:15px !important;padding:0 10px !important;border-radius:3px;font-weight:normal;text-indent:8px;--wc-icon-size: 16px;color:var(--color-dark-1);box-shadow:0 2px 12px rgba(0,0,0,.1)}::slotted(.layer__content__toast+.layer__content__toast){margin-top:30px}::slotted(.layer__content__toast.style-info){border:1px solid #ebeef5;background:#edf2fc;color:var(--color-grey-3)}::slotted(.layer__content__toast.style-success){border:1px solid #e1f3d8;background:#f0f9eb;color:var(--color-green-3)}::slotted(.layer__content__toast.style-warning){border:1px solid #faebb4;background:#faecd8;color:var(--color-red-1)}::slotted(.layer__content__toast.style-error){border:1px solid #f5c4c4;background:#fde2e2;color:var(--color-red-1)}.layer__ctrl{display:flex;justify-content:flex-end;width:100%;height:60px;padding:15px;line-height:30px;font-size:14px;color:#454545;text-align:right}.layer__ctrl button{min-width:64px;height:30px;padding:0 10px;margin:0 5px;border:1px solid var(--color-plain-3);border-radius:3px;white-space:nowrap;background:#fff;font-size:inherit;font-family:inherit;outline:none;color:inherit}.layer__ctrl button:hover{background:var(--color-plain-1)}.layer__ctrl button:active{border-color:var(--color-grey-1)}.layer__ctrl button:focus{box-shadow:0 0 0 2px var(--color-plain-a)}.layer__ctrl button:last-child{color:#fff;background:var(--color-teal-2);border-color:rgba(0,0,0,0)}.layer__ctrl button:last-child:hover{background:var(--color-teal-1)}.layer__ctrl button:last-child:active{background:var(--color-teal-3)}.layer__ctrl button:last-child:focus{box-shadow:0 0 0 2px var(--color-teal-a)}.layer__ctrl button::-moz-focus-inner{border:none}`,c`:host([mask]){height:100%;background:rgba(0,0,0,.2)}:host([type=alert]) .layer,:host([type=confirm]) .layer,:host([type=prompt]) .layer{max-width:600px;min-width:300px;background:#fff}:host([type=alert]) .layer__content,:host([type=confirm]) .layer__content,:host([type=prompt]) .layer__content{padding:0 15px}:host([type=toast]) .layer{box-shadow:none;background:none}:host([type=toast]) .layer__content{flex-direction:column;min-height:40px}:host([blurry]) .layer{backdrop-filter:blur(5px)}`];#t=!0;#o=null;#i=null;constructor(){super(),this.promise=new Promise((t,e)=>{this.#o=t,this.#i=e}),this.promise.host=this}#e(t){this.intercept?this.intercept(t,e=>{delete this.intercept,this.#o(t),this.$animate(!0),this.$refs.box.$animate(!0).then(o=>this.close())}):(this.#o(t),this.$animate(!0),this.$refs.box.$animate(!0).then(e=>this.close()))}#r(){switch(this.type){case"toast":let t=this.lastElementChild;t._anim=t.animate([{marginTop:"-30px",opacity:0},{marginTop:"0",opacity:1}],{duration:200,fill:"forwards"}),setTimeout(()=>{t._anim.reverse(),t._anim.onfinish=e=>{t.remove(),this.children.length===0&&(this.close(),p=null)}},3e3);break;default:this.$animate(),this.$refs.box.$animate();break}}mounted(){this.type==="prompt"?(this.$refs.input=this.firstElementChild,g(this.$refs.input,"submit",t=>{this.#e(t.target.value)})):this.type==="toast"&&(this.style.display=""),this.mask&&(this.$on("click",t=>{if(t.composedPath()[0]===t.currentTarget){if(h.includes(this.type))return;this.maskClose&&(this.#t===!1&&this.#i(),this.$refs.box.$animate(!0).then(o=>this.close()))}}),this.maskColor&&(this.style.backgroundColor=this.maskColor)),this.background&&(this.$refs.box.style.backgroundColor=this.background),this.#r()}updated(){this.#r()}moveTo(t={}){var e="";for(var o in t)e+=`${o}:${t[o]};`;this.$refs.box.style.cssText+=e}show(){this.#t&&(this.type="common")}close(){this.#t?(this.type=null,this.$emit("close")):(h.includes(this.type)&&(s=null),this.$emit("close"),this.remove())}handleBtnClick(t){if(t.target.tagName==="BUTTON"){let e=+t.target.dataset.idx||0;switch(this.type){case"alert":this.#e(null);break;case"confirm":case"prompt":if(e===0)this.#i(),this.$animate(!0),this.$refs.box.$animate(!0).then(o=>this.close());else{let o=this.type==="prompt"?this.$refs.input.value:null;this.#e(o)}break;default:this.#e(e);break}}}render(){let{type:t,mask:e,left:o,right:n,top:r,bottom:m}=this,f="";return t==="common"&&e===!1&&(r=r||0),f=d({left:o,right:n,top:r,bottom:m}),y`
${this.title}
@@ -204,124 +16,14 @@ class Layer extends Component {
- ${this.btns.map((s, i) => html``)} + ${this.btns.map((b,_)=>y``)}
- `; - } -} -function layer(opt = {}) { - let { type = "common", content = "" } = opt; - let layDom = type === "toast" ? toastInstance || document.createElement("wc-layer") : document.createElement("wc-layer"); - let alreadyInTree = type === "toast" && !!toastInstance; - layDom.type = opt.type; - if (type === "toast") { - toastInstance = layDom; - layDom.top = "20px"; - } else { - if (opt.btns && opt.btns.length) { - layDom.btns = opt.btns; - } - if (opt.intercept && typeof opt.intercept === "function") { - layDom.intercept = opt.intercept; - } - layDom.mask = opt.mask; - layDom.title = opt.title; - if (UNIQUE_TYPES.includes(type)) { - if (uniqueInstance) { - uniqueInstance.$animate(true).then((_) => { - uniqueInstance.close(); - uniqueInstance = layDom; - }); - } else { - uniqueInstance = layDom; - } - } - } - if (alreadyInTree) { - let tmp = document.createElement("template"); - tmp.innerHTML = content; - layDom.appendChild(tmp.content.cloneNode(true)); - layDom.updated(); - } else { - layDom.innerHTML = content; - document.body.appendChild(layDom); - } - return layDom.promise; -} -layer.alert = function(content, title = LANG_TITLE, btns = LANG_BTNS.slice(1)) { - if (typeof title === "object") { - btns = title; - title = LANG_TITLE; - } - return this({ - type: "alert", - title, - content, - mask: true, - btns - }); -}; -layer.confirm = function(content, title = LANG_TITLE, btns = LANG_BTNS.concat()) { - if (typeof title === "object") { - btns = title; - title = LANG_TITLE; - } - return this({ - type: "confirm", - title, - content, - mask: true, - btns - }); -}; -layer.prompt = function(title = LANG_TITLE, defaultValue = "", intercept) { - if (typeof defaultValue === "function") { - intercept = defaultValue; - defaultValue = ""; - } - if (!intercept) { - intercept = function(val, done) { - if (val) { - done(); - } - }; - } - return this({ - type: "prompt", - title, - content: ``, - mask: true, - intercept, - btns: LANG_BTNS.concat() - }); -}; -layer.toast = function(txt, type = "info") { - var ico = type; - switch (type) { - case "info": - case "warning": - break; - case "error": - ico = "deny"; - break; - case "success": - ico = "get"; - break; - default: - ico = "info"; - } - return this({ - content: ` -
- - ${txt} -
`, - type: "toast" - }); -}; -Layer.reg("layer"); -window.layer = layer; + `}}function l(i={}){let{type:t="common",content:e=""}=i,o=t==="toast"&&p||document.createElement("wc-layer"),n=t==="toast"&&!!p;if(o.type=i.type,t==="toast"?(p=o,o.top="20px"):(i.btns&&i.btns.length&&(o.btns=i.btns),i.intercept&&typeof i.intercept=="function"&&(o.intercept=i.intercept),o.mask=i.mask,o.title=i.title,h.includes(t)&&(s?s.$animate(!0).then(r=>{s.close(),s=o}):s=o)),n){let r=document.createElement("template");r.innerHTML=e,o.appendChild(r.content.cloneNode(!0)),o.updated()}else o.innerHTML=e,document.body.appendChild(o);return o.promise}l.alert=function(i,t=a,e=u.slice(1)){return typeof t=="object"&&(e=t,t=a),this({type:"alert",title:t,content:i,mask:!0,btns:e})},l.confirm=function(i,t=a,e=u.concat()){return typeof t=="object"&&(e=t,t=a),this({type:"confirm",title:t,content:i,mask:!0,btns:e})},l.prompt=function(i=a,t="",e){return typeof t=="function"&&(e=t,t=""),e||(e=function(o,n){o&&n()}),this({type:"prompt",title:i,content:``,mask:!0,intercept:e,btns:u.concat()})},l.toast=function(i,t="info"){var e=t;switch(t){case"info":case"warning":break;case"error":e="deny";break;case"success":e="get";break;default:e="info"}return this({content:` +
+ + ${i} +
`,type:"toast"})},w.reg("layer"),window.layer=l; diff --git a/usr/lib/hosts-switch/webapp/lib/ui/scroll/index.js b/usr/lib/hosts-switch/webapp/lib/ui/scroll/index.js new file mode 100644 index 0000000..ec5d223 --- /dev/null +++ b/usr/lib/hosts-switch/webapp/lib/ui/scroll/index.js @@ -0,0 +1,13 @@ +import{css as p,html as $,bind as a,unbind as x,Component as _}from"wkit";class z extends _{static props={axis:"xy",delay:1e3,distance:1};static styles=[p`:host{position:relative;display:block}:host .container{overflow:hidden;position:relative;width:100%;height:100%;max-height:inherit}:host .wrapper{overflow:auto;scrollbar-width:none;width:100%;height:100%;max-height:inherit;scrollbar-width:0}:host .wrapper::-webkit-scrollbar{display:none}:host .content{min-width:100%;width:fit-content;height:fit-content}`,p`.is-horizontal,.is-vertical{visibility:hidden;position:absolute;display:flex;justify-content:flex-end;opacity:0;user-select:none;transition:opacity .3s linear,visibility .3s linear}.is-horizontal .thumb,.is-vertical .thumb{display:block;border-radius:5px;background:rgba(44,47,53,.25);cursor:default;transition:width .1s linear,height .1s linear}.is-horizontal .thumb:hover,.is-vertical .thumb:hover{background:rgba(44,47,53,.5)}.is-horizontal{flex-direction:column;left:0;bottom:0;width:100%;height:10px}.is-horizontal .thumb{width:0;height:6px}.is-horizontal .thumb:hover{height:10px}.is-vertical{top:0;right:0;width:10px;height:100%}.is-vertical .thumb{width:6px;height:0}.is-vertical .thumb:hover{width:10px}`,p`:host(:hover) .is-horizontal,:host(:hover) .is-vertical{visibility:visible;opacity:1}:host([axis=x]) .wrapper{overflow-y:hidden}:host([axis=x]) .is-vertical{display:none}:host([axis=y]) .wrapper{overflow-x:hidden}:host([axis=y]) .is-horizontal{display:none}:host([disabled]) .wrapper{overflow:hidden}:host([disabled]) .is-vertical,:host([disabled]) .is-horizontal{display:none}`];stamp=0;cache={xBar:0,yBar:0,thumbX:0,thumbY:0};get scrollTop(){return this.$refs.box?.scrollTop||0}set scrollTop(t){t=+t,t===t&&(this.$refs.box.scrollTop=t)}get scrollLeft(){return this.$refs.box?.scrollLeft||0}set scrollLeft(t){t=+t,t===t&&(this.$refs.box.scrollLeft=t)}get scrollHeight(){return this.$refs.box?.scrollHeight}get scrollWidth(){return this.$refs.box?.scrollWidth}__init__(t){let e=this.offsetWidth,r=this.offsetHeight,s=this.scrollWidth,l=this.scrollHeight,h=50,i=50;h=r*(r/l)>>0,i=e*(e/s)>>0,h<50&&(h=50),i<50&&(i=50),i>=e&&(i=0),h>=r&&(h=0),this.cache.yBar=h,this.cache.xBar=i,i>0?(this.$refs.x.parentNode.style.display="flex",this.$refs.x.style.width=i+"px"):this.$refs.x.parentNode.style.display="none",h>0?(this.$refs.y.parentNode.style.display="flex",this.$refs.y.style.height=h+"px"):this.$refs.y.parentNode.style.display="none"}_fetchScrollX(t){let{xBar:e}=this.cache,{scrollWidth:r,offsetWidth:s}=this;return t<0?t=0:t>s-e&&(t=s-e),this.scrollLeft=(r-s)*(t/(s-e)),this.$refs.x.style.transform=`translateX(${t}px)`,t}_fetchScrollY(t){let{yBar:e}=this.cache,{scrollHeight:r,offsetHeight:s}=this;return t<0?t=0:t>s-e&&(t=s-e),this.scrollTop=(r-s)*(t/(s-e)),this.$refs.y.style.transform=`translateY(${t}px)`,t}_fireReachEnd(t="reach-bottom"){let e=this.delay,{scrollHeight:r,offsetHeight:s}=this,l=this.scrollTop,h=Date.now();if(h-this.stamp>e){if(t==="reach-bottom"){if(s+l0)return;this.stamp=h,this.$emit(t)}}mounted(){let t,e,r,s,l=i=>{let{thumbY:c,thumbX:n}=this.cache;t!==void 0&&(r=this._fetchScrollX(n+i.pageX-t)),e!==void 0&&(s=this._fetchScrollY(c+i.pageY-e))},h=i=>{Math.abs(i.pageY-e)>this.distance&&this._fireReachEnd(i.pageY>e?"reach-bottom":"reach-top"),t=void 0,e=void 0,this.cache.thumbX=r||0,this.cache.thumbY=s||0,delete this._active,x(document,"mousemove",l),x(document,"mouseup",h)};a(this.$refs.box,"scroll",i=>{if(i.stopPropagation(),this._active)return;let{xBar:c,yBar:n,thumbX:m,thumbY:f}=this.cache,{axis:d,scrollHeight:y,scrollWidth:g,offsetHeight:u,offsetWidth:b,scrollTop:v,scrollLeft:w}=this;if(!(c===0&&n===0)){if((d==="y"||d==="xy")&&n){let o=~~(v/(y-u)*(u-n));o!==f&&(this.cache.thumbY=o,this.$refs.y.style.transform=`translateY(${o}px)`,Math.abs(o-f)>this.distance&&this._fireReachEnd(o>f?"reach-bottom":"reach-top"))}if((d==="x"||d==="xy")&&c){let o=~~(w/(g-b)*(b-c));o!==m&&(this.cache.thumbX=o,this.$refs.x.style.transform=`translateX(${o}px)`)}this.$emit("scroll")}}),a(this.$refs.y,"mousedown",i=>{e=i.pageY,this._active=!0,a(document,"mousemove",l),a(document,"mouseup",h)}),a(this.$refs.x,"mousedown",i=>{t=i.pageX,this._active=!0,a(document,"mousemove",l),a(document,"mouseup",h)}),this.__observer=new ResizeObserver(this.__init__.bind(this)),this.__observer.observe(this.$refs.cont)}unmounted(){this.__observer?.disconnect()}render(){return $` +
+
+
+
+
+
+ +
+
+ +
+ `}}z.reg("scroll"); diff --git a/usr/lib/hosts-switch/webapp/lib/wkit.js b/usr/lib/hosts-switch/webapp/lib/wkit.js index 3063769..2bfd83b 100644 --- a/usr/lib/hosts-switch/webapp/lib/wkit.js +++ b/usr/lib/hosts-switch/webapp/lib/wkit.js @@ -1,3 +1,3 @@ -var y=Object.create(null);["autofocus","autoplay","async","allowTransparency","checked","controls","declare","disabled","defer","defaultChecked","defaultSelected","contentEditable","isMap","loop","multiple","noHref","noResize","noShade","open","readOnly","selected","loading"].forEach(function(i){y[i.toLowerCase()]=i});var H=Symbol("wc_path"),p=Symbol("wc-nothing"),z=Symbol("finalized"),x=Symbol("props"),N=Symbol("changed_props"),w=Symbol("mounted"),g=Symbol("pending"),V=Symbol("children"),oe="* {box-sizing: border-box;margin: 0;padding: 0;}::before,::after {box-sizing: border-box;}";function re(i){switch(i){case Number:return 0;case Boolean:return!1;case Object:return{};case Array:return[];default:return""}}function Ee(i){switch(typeof i){case"number":return{type:Number,default:i};case"boolean":return{type:Boolean,default:i};case"object":return Array.isArray(i)?{type:Array,default:i}:{type:Object,default:i};default:return{type:String,default:i+""}}}function le(i){if(i&&typeof i=="object"&&i.hasOwnProperty("type"))return Object.assign({attribute:!0,default:re(i.type)},i);switch(i){case Number:i={type:Number};break;case Boolean:i={type:Boolean};break;case Object:i={type:Object};break;case Array:i={type:Array};break;default:i=Ee(i);break}return i.default=i.hasOwnProperty("default")?i.default:re(i.type),i.attribute=!0,i}function B(i,e){switch(e.type){case Number:return i===null?null:+i||0;case Boolean:return i===!1?!1:i!==null;case Object:if(typeof i=="object")return i;try{return JSON.parse(i)}catch{return{}}case Array:if(typeof i=="object")return i;try{return JSON.parse(i)}catch{return[]}default:return i==null?null:i+""}}var ae=CSSStyleSheet;document.adoptedStyleSheets||(ae=class{elem=document.createElement("style");replaceSync(i){this.elem.textContent=i.replace(/\s+/g," ")}});function Se(i,...e){let t="",s=Array.from(i);for(;s.length;)t+=s.shift()+(e.shift()||"");return t}function ce(i,e=""){let t=new ae;typeof e=="string"?e=[e]:e=e.flat(1/0),e=(oe+e.join(" ")).trim(),t.replaceSync(e),i.adoptedStyleSheets?i.adoptedStyleSheets=[t]:i.appendChild(t.elem)}function O(i=200,e=[],t=!1){t===!1&&(this.style.display="");let s=this.animate(e,{duration:i,direction:t?"reverse":"normal",fill:"forwards"});return new Promise(n=>{s.addEventListener("finish",o=>{t&&(this.style.display="none"),s.cancel(),n()},{once:!0})})}var C={fade:[{opacity:0},{opacity:1}],scale:[{transform:"scale(0)"},{transform:"scale(1)"}],"micro-bounce":[{opacity:0,transform:"scale(0.8)"},{transform:"scale(1.05)",opacity:1},{transform:"scale(1)"}],slide:[{opacity:0,transform:"translateY(-50px)"},{opacity:1,transform:"translateY(0)"}],bounce:[{transform:"scale(0)"},{transform:"scale(1.2)"},{transform:"scale(1)"}],rotate:[{transform:"rotate(0)"},{transform:"rotate(360deg)"}]};var Y="$wc$",_=`wc$${String(Math.random()).slice(9)}$`,ye="?"+_,Ce=`<${ye}>`,k=(i="")=>document.createComment(i),R=i=>i===null||typeof i!="object"&&typeof i!="function",ge=Array.isArray,Te=i=>ge(i)||typeof(i==null?!1:i[Symbol.iterator])=="function",D=`[ +var g=Object.create(null);["autofocus","autoplay","async","allowTransparency","checked","controls","declare","disabled","defer","defaultChecked","defaultSelected","contentEditable","isMap","loop","multiple","noHref","noResize","noShade","open","readOnly","selected","loading"].forEach(function(i){g[i.toLowerCase()]=i});var z=Symbol("wc_path"),p=Symbol("wc-nothing"),B=Symbol("finalized"),x=Symbol("props"),_=Symbol("changed_props"),w=Symbol("mounted"),C=Symbol("pending"),O=Symbol("children"),oe="* {box-sizing: border-box;margin: 0;padding: 0;}::before,::after {box-sizing: border-box;}";function ne(i){switch(i){case Number:return 0;case Boolean:return!1;case Object:return{};case Array:return[];default:return""}}function Ee(i){switch(typeof i){case"number":return{type:Number,default:i};case"boolean":return{type:Boolean,default:i};case"object":return Array.isArray(i)?{type:Array,default:i}:{type:Object,default:i};case"string":let e=String,t=!0;if(i.includes("!")){i=i.split("!");let s=i.shift();s==="str"?i=i.join("!"):s==="num"?(e=Number,i=+i.shift()||0):s==="bool"&&(e=Boolean,i=i.shift(),i=i!=="false"&&i!==""),t=!1}return{type:e,default:i,attribute:t};default:return{type:String,default:i+""}}}function le(i){if(i&&typeof i=="object"&&i.hasOwnProperty("type"))return Object.assign({attribute:!0,default:ne(i.type)},i);switch(i){case Number:i={type:Number};break;case Boolean:i={type:Boolean};break;case Object:i={type:Object};break;case Array:i={type:Array};break;default:i=Ee(i);break}return i.default=i.hasOwnProperty("default")?i.default:ne(i.type),i.attribute=i.hasOwnProperty("attribute")?i.attribute:!0,i}function R(i,e){switch(e.type){case Number:return i===null?null:+i||0;case Boolean:return i===!1?!1:i!==null;case Object:if(typeof i=="object")return i;try{return JSON.parse(i)}catch{return{}}case Array:if(typeof i=="object")return i;try{return JSON.parse(i)}catch{return[]}default:return i==null?null:i+""}}var ae=CSSStyleSheet;document.adoptedStyleSheets||(ae=class{elem=document.createElement("style");replaceSync(i){this.elem.textContent=i.replace(/\s+/g," ")}});function Se(i,...e){let t="",s=Array.from(i);for(;s.length;)t+=s.shift()+(e.shift()||"");return t}function ce(i,e=""){let t=new ae;typeof e=="string"?e=[e]:e=e.flat(1/0),e=(oe+e.join(" ")).trim(),t.replaceSync(e),i.adoptedStyleSheets?i.adoptedStyleSheets=[t]:i.appendChild(t.elem)}function M(i=200,e=[],t=!1){t===!1&&(this.style.display="");let s=this.animate(e,{duration:i,direction:t?"reverse":"normal",fill:"forwards"});return new Promise(r=>{s.addEventListener("finish",n=>{t&&(this.style.display="none"),s.cancel(),r()},{once:!0})})}var N={fade:[{opacity:0},{opacity:1}],scale:[{transform:"scale(0)"},{transform:"scale(1)"}],"micro-bounce":[{opacity:0,transform:"scale(0.8)"},{transform:"scale(1.05)",opacity:1},{transform:"scale(1)"}],slide:[{opacity:0,transform:"translateY(-50px)"},{opacity:1,transform:"translateY(0)"}],bounce:[{transform:"scale(0)"},{transform:"scale(1.2)"},{transform:"scale(1)"}],rotate:[{transform:"rotate(0)"},{transform:"rotate(360deg)"}]};var Y="$wc$",b=`wc$${String(Math.random()).slice(9)}$`,ye="?"+b,Ce=`<${ye}>`,k=(i="")=>document.createComment(i),P=i=>i===null||typeof i!="object"&&typeof i!="function",ge=Array.isArray,Te=i=>ge(i)||typeof(i==null?!1:i[Symbol.iterator])=="function",D=`[ \f\r]`,ke=`[^ -\f\r"'\`<>=]`,Ve=`[^\\s"'>=/]`,T=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,he=1,U=2,Oe=3,fe=/-->/g,de=/>/g,$=new RegExp(`>|${D}(?:(${Ve}+)(${D}*=${D}*(?:${ke}|("|')|))|$)`,"g"),Re=0,ue=1,Me=2,pe=3,me=/'/g,_e=/"/g,$e=/^(?:script|style|textarea|title)$/i,ve=1,M=2,X=1,v=2,Pe=5,F=6,Ie=7,be=new WeakMap,b=document.createTreeWalker(document,129,null,!1);function W(){}function Le(i,e){let t=i.length-1,s=[],n=e===M?"":"",o,r=T;for(let a=0;a"?(r=o??T,u=-1):h[ue]===void 0?u=-2:(u=r.lastIndex-h[Me].length,d=h[ue],r=h[pe]===void 0?$:h[pe]==='"'?_e:me):r===_e||r===me?r=$:r===fe||r===de?r=T:(r=$,o=void 0);let L=r===$&&i[a+1].startsWith("/>")?" ":"";n+=r===T?c+Ce:u>=0?(s.push(d),c.slice(0,u)+Y+c.slice(u)+_+L):c+_+(u===-2?(s.push(void 0),a):L)}let l=n+(i[t]||"")+(e===M?"":"");if(!Array.isArray(i)||!i.hasOwnProperty("raw"))throw new Error("invalid html ast");return[l,s]}var A=class{constructor({strings:e,["__dom_type__"]:t},s){this.parts=[];let n,o=0,r=0,l=e.length-1,a=this.parts,[c,u]=Le(e,t);if(this.el=A.createElement(c),b.currentNode=this.el.content,t===M){let d=this.el.content,f=d.firstChild;f.remove(),d.append(...f.childNodes)}for(;(n=b.nextNode())!==null&&a.length0){n.textContent="";for(let h=0;h2||s[0]!==""||s[1]!==""?(this._$committedValue=new Array(s.length-1).fill(new String),this.strings=s):this._$committedValue=p}get tagName(){return this.element.tagName}get _$isConnected(){return this._$parent._$isConnected}_$setValue(e,t){let s=this.strings,n=!1;if(s===void 0)n=!R(e)||e!==this._$committedValue,n&&(this._$committedValue=e);else{let o=e;e=s[0];for(let r=0;rr.stopPropagation();break;case"prevent":this.#t=r=>r.preventDefault();break;case"self":this.#s=r=>r.target===this.element;break;case"capture":case"once":case"passive":s[o]=!0;break}let n=e!==this.#e;if(this.#e&&t.$events[this.name]){for(let o of t.$events[this.name])if(o.el===this.element){n=s.capture!==o.capture||s.once!==o.once||s.passive!==o.passive,n&&this.element.removeEventListener(this.name,o.listener,o.options);break}}e&&n&&(this.element.addEventListener(this.name,this,s),this.#e=e,t.$events[this.name]?t.$events[this.name].push({el:this.element,listener:this,options:s}):t.$events[this.name]=[{el:this.element,listener:this,options:s}])}handleEvent(e){this.#i(e),this.#t(e),this.#s(e)!==!1&&this.#e.call(this.options.host,e)}},J=class{constructor(e,t,s){this.element=e,this.type=F,this._$disconnectableChildren=void 0,this._$parent=t,this.options=s}get _$isConnected(){return this._$parent._$isConnected}_$setValue(e){}};function xe(i,e,t={}){let s=e[H];return s===void 0&&(e[H]=s=new E(e.insertBefore(k(),null),null,void 0,t)),s._$setValue(i),s}function K(i,...e){return{__dom_type__:ve,strings:i,values:e}}function je(i){let e=[i];return e.raw=e,K(e)}function He(i,...e){return{__dom_type__:M,strings:i,values:e}}function P(){}function ee(i,e,t){let s=t?"querySelectorAll":"querySelector";return e?e[s](i):document.body[s](i)}function ze(i,e){return ee(i,e,!0)}var te=function(){let i=[],e=document.createTextNode(""),t=!1;function s(){let n=i.length;for(let o=0;ot.toUpperCase())}function Be(i){try{let e=i.getBoundingClientRect();if(e.width||e.height||i.getClientRects().length){let t=i.ownerDocument,s=t.documentElement,n=t.defaultView;return{top:e.top+n.pageYOffset-s.clientTop,left:e.left+n.pageXOffset-s.clientLeft}}}catch{return{left:0,top:0}}}function ne(i,e,t,s,n=!0){let o=e.split(","),r,l=i.host===i,a=l?i:null;if(typeof t=="function"?(n=s,s=t,t=null):(typeof t!="string"&&(t=null),s=s||P),l===!1){let c=i;for(;c&&c!==document.body&&c!==document;){if(c.ownHost){l=!0,a=c.ownHost;break}c=c.parentNode}}return t?r=function(c){let u=ee(t,i),d=c.target;if(u)for(;d!==i;)if(u.contains(d)){s(c);break}else d=d.parentNode}:r=s,o.forEach(function(c){c=c.trim(),l&&(a.$events[c]?a.$events[c].push({el:i,listener:r,options:n}):a.$events[c]=[{el:i,listener:r,options:n}]),i.addEventListener(c,r,n)}),r}function I(i,e,t=P,s=!1){e.split(",").forEach(function(o){i.removeEventListener(o.trim(),t,s)})}function De(i,e=P){return ne(document,"mousedown",t=>{let s=t.composedPath?t.composedPath():t.path;if(s){for(;s.length>3;)if(s.shift()===i)return}else{let n=t.explicitOriginalTarget||t.target;if(i===n||i.contains(n)||i.root&&i.root.contains(n))return}e(t)})}function Ue(i=P){I(document,"mousedown",i)}function Ne(i,e="click",t={},s){let n=new Event(e,{bubbles:!s,cancelable:!0});Object.assign(n,t),i.dispatchEvent(n)}function nt(i={}){let e="";for(let t in i)i[t]&&(e+=" "+t);return e.slice(1)}function rt(i={}){let e="";for(let t in i)(i[t]||i[t]===0)&&(e+=ie(t)+":"+i[t]+";");return e}var we=class extends HTMLElement{static get observedAttributes(){let e=[];return this.finalize(),this.parseAnim(),this[x].forEach((t,s)=>{e.push(t.attrName)}),e}static createProperty(e,t){let s=Symbol(e),n={get(){return this[s]},set(o){let r=this[s];o=B(o,t),r!==o&&(this[s]=o,this.$requestUpdate(e,r),t.observer&&t.observer.call(this,o,r))},enumerable:!1};this[x].set(e,t),Object.defineProperty(this.prototype,e,n)}static parseAnim(){if(this.hasOwnProperty("animation")){let{type:e="fade",duration:t}=this.animation;Object.defineProperty(this.prototype,"$animate",{value(s){if(this[w])return O.call(this,t,C[e],s)},enumerable:!1}),delete this.animation}}static finalize(){if(this[z])return!1;if(this[z]=!0,this[x]=new Map,this.hasOwnProperty("props"))for(let e in this.props){let t=le(this.props[e]),s=e.toLowerCase();t.attrName=s,y[s]?e=y[s]:(t.attrName=ie(e),e=se(e)),this.createProperty(e,t)}delete this.props}static reg(e=""){e="wc-"+e,customElements.get(e)||customElements.define(e,this)}constructor(){super(),this[g]=!1,this[w]=!1,this[N]=new Map,this.host=this,this.root=this.shadowRoot||this.attachShadow({mode:"open"}),this.root.ownHost=this,Object.defineProperty(this,"$refs",{value:Object.create(null),enumerable:!1}),Object.defineProperty(this,"$events",{value:Object.create(null),enumerable:!1}),this.created()}#e(){this[N]=new Map,this.constructor[x].forEach((e,t)=>{this[t]=this[t]===void 0?e.default:this[t]}),this[g]===!1&&(this[g]=!0,te(e=>this.#n()))}#t(e){return this.constructor[x].get(e)}connectedCallback(){this.$animate&&(this.style.display="none"),this.#e(),ce(this.root,this.constructor.styles),this[V]?.setConnected(!0)}disconnectedCallback(){if(this[V]?.setConnected(!1),!document.body?.contains(this)){let e=this.$events;if(e)for(let t in e)for(let s of e[t])I(s.el,t,s.listener,s.options)}this.unmounted()}attributeChangedCallback(e,t,s){t!==s&&this.#s(e,s,t)}#i(e,t){let s=this.#t(e),n=s.attrName;if(s.attribute===!1){this.removeAttribute(n);return}switch(s.type){case Number:case String:t===null?this.removeAttribute(n):this.setAttribute(n,t);break;case Boolean:t===null||t===!1?this.removeAttribute(n):this.setAttribute(n,"");break}}#s(e,t,s){let n=y[e],o,r;if(n&&(e=n),r=se(e),o=this.#t(r),t=B(t,o),o.attribute===!1){if(t===null)return;if(t===this[r]){this.removeAttribute(e);return}}this[r]=t}$requestUpdate(e,t){e!==void 0&&(this[N].set(e,this[e]),this.#i(e,this[e])),this[g]===!1&&(this[g]=!0,te(s=>this.#n()))}#n(){let e=this[N];this.#l(),this.#r(e),this.#o()}#r(e){this[w]===!1?(this[w]=!0,this.mounted()):this.updated(e)}#o(){this[N]=new Map,this[g]=!1}#l(){let e=this.render();this[V]=xe(e,this.root,{host:this,isConnected:!this[w]&&this.isConnected})}created(){}mounted(){}unmounted(){}updated(){}render(){return K``}$on(e,t,s){return ne(this,e,t,s)}$off(e,t,s){I(this,e,t,s)}$emit(e,t={},s=!1){return Ne(this,e,t,s)}};export{ee as $,ze as $$,we as Component,ne as bind,se as camelize,nt as classMap,Ue as clearOutsideClick,Se as css,Ne as fire,K as html,ie as hyphen,te as nextTick,Be as offset,De as outsideClick,je as raw,rt as styleMap,He as svg,I as unbind}; +\f\r"'\`<>=]`,Ve=`[^\\s"'>=/]`,T=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,he=1,q=2,Oe=3,fe=/-->/g,de=/>/g,$=new RegExp(`>|${D}(?:(${Ve}+)(${D}*=${D}*(?:${ke}|("|')|))|$)`,"g"),Re=0,ue=1,Me=2,pe=3,me=/'/g,_e=/"/g,$e=/^(?:script|style|textarea|title)$/i,Pe=1,j=2,F=1,L=2,je=5,K=6,Le=7,be=new Map,y=document.createTreeWalker(document,129,null,!1);function W(){}function Ie(i,e){let t=i.length-1,s=[],r=e===j?"":"",n,o=T;for(let a=0;a"?(o=n??T,u=-1):h[ue]===void 0?u=-2:(u=o.lastIndex-h[Me].length,d=h[ue],o=h[pe]===void 0?$:h[pe]==='"'?_e:me):o===_e||o===me?o=$:o===fe||o===de?o=T:(o=$,n=void 0);let v=o===$&&i[a+1].startsWith("/>")?" ":"";r+=o===T?c+Ce:u>=0?(s.push(d),c.slice(0,u)+Y+c.slice(u)+b+v):c+b+(u===-2?(s.push(void 0),a):v)}let l=r+(i[t]||"")+(e===j?"":"");if(!Array.isArray(i)||!i.hasOwnProperty("raw"))throw new Error("invalid html ast");return[l,s]}var A=class{constructor({strings:e,["__dom_type__"]:t},s){this.parts=[];let r,n=0,o=0,l=e.length-1,a=this.parts,[c,u]=Ie(e,t);if(this.el=A.createElement(c),y.currentNode=this.el.content,t===j){let d=this.el.content,f=d.firstChild;f.remove(),d.append(...f.childNodes)}for(;(r=y.nextNode())!==null&&a.length0){r.textContent="";for(let h=0;h2||s[0]!==""||s[1]!==""?(this._$committedValue=new Array(s.length-1).fill(new String),this.strings=s):this._$committedValue=p}get tagName(){return this.element.tagName}get _$isConnected(){return this._$parent._$isConnected}_$setValue(e,t){let s=this.strings,r=!1;if(s===void 0)r=!P(e)||e!==this._$committedValue,r&&(this._$committedValue=e);else{let n=e;e=s[0];for(let o=0;oo.stopPropagation();break;case"prevent":this.#t=o=>o.preventDefault();break;case"self":this.#s=o=>o.target===this.element;break;case"capture":case"once":case"passive":s[n]=!0;break}let r=e!==this.#e;if(this.#e&&t.$events[this.name]){for(let n of t.$events[this.name])if(n.el===this.element){r=s.capture!==n.capture||s.once!==n.once||s.passive!==n.passive,r&&this.element.removeEventListener(this.name,n.listener,n.options);break}}e&&r&&(this.element.addEventListener(this.name,this,s),this.#e=e,t.$events[this.name]?t.$events[this.name].push({el:this.element,listener:this,options:s}):t.$events[this.name]=[{el:this.element,listener:this,options:s}])}handleEvent(e){this.#i(e),this.#t(e),this.#s(e)!==!1&&this.#e.call(this.options.host,e)}},X=class{constructor(e,t,s){this.element=e,this.type=K,this._$disconnectableChildren=void 0,this._$parent=t,this.options=s}get _$isConnected(){return this._$parent._$isConnected}_$setValue(e){}};function xe(i,e,t={}){let s=e[z];return s===void 0&&(s=new E(e.insertBefore(k(),null),null,void 0,t),e[z]=s),s._$setValue(i),s}function ee(i,...e){return{__dom_type__:Pe,strings:i,values:e}}function He(i,e=[]){let t=e.length?i.split("%s"):[i];return t.raw=!0,ee(t,...e)}function ve(i,...e){return{__dom_type__:j,strings:i,values:e}}function I(){}function te(i,e,t){let s=t?"querySelectorAll":"querySelector";return e?e[s](i):document.body[s](i)}function Ue(i,e){return te(i,e,!0)}var V=function(){let i=[],e=document.createTextNode(""),t=!1;function s(){let r=i.length;for(let n=0;nt.toUpperCase())}function ze(i){try{let e=i.getBoundingClientRect();if(e.width||e.height||i.getClientRects().length){let t=i.ownerDocument,s=t.documentElement,r=t.defaultView;return{top:e.top+r.pageYOffset-s.clientTop,left:e.left+r.pageXOffset-s.clientLeft}}}catch{return{left:0,top:0}}}function re(i,e,t,s,r=!0){let n=e.split(","),o,l=i.host===i,a=l?i:null;if(typeof t=="function"?(r=s,s=t,t=null):(typeof t!="string"&&(t=null),s=s||I),l===!1){let c=i;for(;c&&c!==document.body&&c!==document;){if(c.ownHost){l=!0,a=c.ownHost;break}c=c.parentNode}}return t?o=function(c){let u=te(t,i),d=c.target;if(u)for(;d!==i;)if(u.contains(d)){s(c);break}else d=d.parentNode}:o=s,n.forEach(function(c){c=c.trim(),l&&(a.$events[c]?a.$events[c].push({el:i,listener:o,options:r}):a.$events[c]=[{el:i,listener:o,options:r}]),i.addEventListener(c,o,r)}),o}function H(i,e,t=I,s=!1){e.split(",").forEach(function(n){i.removeEventListener(n.trim(),t,s)})}function Be(i,e=I){return re(document,"mousedown",t=>{let s=t.composedPath?t.composedPath():t.path;if(s){for(;s.length>3;)if(s.shift()===i)return}else{let r=t.explicitOriginalTarget||t.target;if(i===r||i.contains(r)||i.root&&i.root.contains(r))return}e(t)})}function De(i=I){H(document,"mousedown",i)}function we(i,e="click",t={},s){let r=new Event(e,{bubbles:!s,cancelable:!0});Object.assign(r,t),i.dispatchEvent(r)}function rt(i={}){let e="";for(let t in i)i[t]&&(e+=" "+t);return e.slice(1)}function nt(i={}){let e="";for(let t in i)(i[t]||i[t]===0)&&(e+=ie(t)+":"+i[t]+";");return e}var Ne=class extends HTMLElement{static get observedAttributes(){let e=[];return this.finalize(),this.parseAnim(),this[x].forEach((t,s)=>{e.push(t.attrName)}),e}static parseAnim(){if(this.hasOwnProperty("animation")){let{type:e="fade",duration:t,custom:s,immediate:r=!1}=this.animation,n=N[e]||N.fade;s&&(n=s),Object.defineProperty(this.prototype,"$animate",{value(o){if(this[w])return M.call(this,t,n,o)},enumerable:!1}),this.prototype.$animate.immediate=r,delete this.animation}}static finalize(){if(this[B])return!1;if(this[B]=!0,this[x]=new Map,this.hasOwnProperty("props"))for(let e in this.props){let t=le(this.props[e]),s=e.toLowerCase();t.attrName=s,g[s]?e=g[s]:(t.attrName=ie(e),e=se(e)),this[x].set(e,t)}delete this.props}static reg(e=""){e="wc-"+e,customElements.get(e)||customElements.define(e,this)}constructor(){super(),this[C]=!1,this[w]=!1,this[_]=new Map,this.host=this,this.root=this.shadowRoot||this.attachShadow({mode:"open"}),this.root.ownHost=this,Object.defineProperty(this,"$refs",{value:Object.create(null),enumerable:!1}),Object.defineProperty(this,"$events",{value:Object.create(null),enumerable:!1}),window.wkitd&&this.$store&&window.wkitd.assign(this);for(let[e,t]of this.constructor[x])this.createProperty(e,t),this[_].set(e,this[e]);this.created()}createProperty(e,t){let s=Symbol(e),r;if(t.type===Array||t.type===Object){let n=this.#e(e,t);r={get(){return n},set(o){n=this.#e(e,t,R(o,t)),this.$requestUpdate(e)},enumerable:!1}}else r={get(){return this[s]},set(n){let o=this[s];n=R(n,t),o!==n&&(this[s]=n,this.$requestUpdate(e),t.observer&&t.observer.call(this,n,o))},enumerable:!1},this[s]=t.default;Object.defineProperty(this,e,r)}#e(e,t,s){return new Proxy(s||t.default,{set:(r,n,o)=>{if(n==="length"&&t.type===Array)return!0;let l=r[n];return r[n]=o,this.$requestUpdate(e),t.observer&&t.observer.call(this,o,l),!0}})}#t(){for(let[e,t]of this[_])this.#s(e,t);this[_].clear(),this.$requestUpdate()}#i(e){return this.constructor[x].get(e)}connectedCallback(){this.$animate&&(this.style.display="none"),this.#t(),ce(this.root,this.constructor.styles),this[O]?.setConnected(!0)}disconnectedCallback(){if(this[O]?.setConnected(!1),!document.body?.contains(this)){let e=this.$events;if(e)for(let t in e)for(let s of e[t])H(s.el,t,s.listener,s.options);window.wkitd&&this.$store&&window.wkitd.deassign(this)}this.unmounted()}attributeChangedCallback(e,t,s){t!==s&&this.#r(e,s,t)}#s(e,t){let s=this.#i(e),r=s.attrName;if(s.attribute===!1){this.removeAttribute(r);return}switch(s.type){case Number:case String:t===null?this.removeAttribute(r):this.setAttribute(r,t);break;case Boolean:t===null||t===!1?this.removeAttribute(r):this.setAttribute(r,"");break}}#r(e,t,s){let r=g[e],n,o;if(r&&(e=r),o=se(e),n=this.#i(o),t=R(t,n),n.attribute===!1){if(t===null)return;if(t===this[o]){this.removeAttribute(e);return}}this[o]=t}$requestUpdate(e){e!==void 0&&(this[_].set(e,this[e]),this.#s(e,this[e])),this[C]===!1&&(this[C]=!0,V(t=>this.#n()))}#n(){let e=this[_];this.#a(),this.#o(e),this.#l()}#o(e){this[w]===!1?(this[w]=!0,this.$animate?.immediate&&this.$animate(),this.__keep_alive__&&V(t=>this.activated()),V(t=>this.mounted())):V(t=>this.updated(e))}#l(){this[_].clear(),this[C]=!1}#a(){let e=this.render();this[O]=xe(e,this.root,{host:this,isConnected:!this[w]&&this.isConnected})}created(){}mounted(){}activated(){}deactivated(){}unmounted(){}updated(){}render(){return ee``}$on(e,t,s){return re(this,e,t,s)}$off(e,t,s){H(this,e,t,s)}$emit(e,t={},s=!1){return we(this,e,t,s)}};export{te as $,Ue as $$,Ne as Component,re as bind,se as camelize,rt as classMap,De as clearOutsideClick,Se as css,we as fire,ee as html,ie as hyphen,V as nextTick,ze as offset,Be as outsideClick,He as raw,nt as styleMap,ve as svg,H as unbind}; diff --git a/usr/lib/hosts-switch/webapp/utils/index.js b/usr/lib/hosts-switch/webapp/utils/index.js new file mode 100644 index 0000000..7e2b962 --- /dev/null +++ b/usr/lib/hosts-switch/webapp/utils/index.js @@ -0,0 +1,85 @@ +const CONFIG_DIR = '/home/yutent/.config/hosts-switch' +const HOST_FILE = `${CONFIG_DIR}/host.cache` +const LOCK_FILE = `${CONFIG_DIR}/lock` + +let timer + +export function checkPermission() { + return writable('/etc/hosts') +} + +export async function getHistory() { + if (await native.fs.isfile(LOCK_FILE)) { + var cache = await native.fs.read(HOST_FILE) + return JSON.parse(cache) + } + + var cache = native.fs.read('/etc/hosts').toString() + var records = cache.split(/[\n\r]+/) + var list = [] + var dict = {} + records.forEach(str => { + str = str.trim() + let matches = str.match(/^(#*?)\s*(\d+\.\d+\.\d+\.\d+)\s+(.*)/) + + if (matches) { + let names = matches[3].split(/\s+/).map(it => it.trim()) + let name + while ((name = names.pop())) { + list.push({ ip: matches[2], enabled: !matches[1], name }) + } + } + }) + records = null + + list.forEach(it => { + it.name = it.name.split('.') + let domain = it.name.splice(-2, 2).join('.') + if (domain === 'com.cn' || domain === 'org.cn' || domain === 'net.cn') { + domain = it.name.pop() + '.' + domain + } + + if (dict[domain]) { + dict[domain].push({ + value: it.ip, + enabled: it.enabled, + record: it.name.join('.') || '@', + remark: '' + }) + } else { + dict[domain] = [ + { + value: it.ip, + enabled: it.enabled, + record: it.name.join('.') || '@', + remark: '' + } + ] + } + }) + list = null + native.fs.write(HOST_FILE, JSON.stringify(dict)) + native.fs.write(LOCK_FILE, '') + return dict +} + +export function saveHosts(dict) { + clearTimeout(timer) + timer = setTimeout(() => { + var txt = '' + for (let k in dict) { + for (let it of dict[k]) { + if (it.enabled) { + var name = it.record === '@' ? '' : it.record + if (name) { + name += '.' + } + txt += `${it.value.padEnd(15, ' ')} ${name + k}\n` + } + } + txt += '\n' + } + native.fs.write(HOST_FILE, JSON.stringify(dict)) + native.fs.write('/etc/hosts', txt) + }, 1000) +} diff --git a/usr/lib/hosts-switch/window.py b/usr/lib/hosts-switch/window.py index c226a58..67f135f 100644 --- a/usr/lib/hosts-switch/window.py +++ b/usr/lib/hosts-switch/window.py @@ -7,7 +7,7 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk class Window(Gtk.Window): - def __init__(self, title = 'Untitled window', width = 760, height = 480): + def __init__(self, title = 'Untitled window', width = 840, height = 520): Gtk.Window.__init__(self, title = title) self.set_default_size(width, height) self.resize(width, height)