一大波更新

master
yutent 2023-09-04 19:21:47 +08:00
parent 74f4cd22d4
commit 419a13e4e6
49 changed files with 437 additions and 1822 deletions

2
.gitignore vendored
View File

@ -6,6 +6,6 @@
.Spotlight-V100
.Trashes
we
__pycache__
*.txt

Binary file not shown.

View File

@ -1,21 +0,0 @@
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0"
viewBox="0 0 1000 1000" xml:space="preserve">
<style>
.st1 {
fill: #fff
}
.st2 {
fill: #0195de
}
</style>
<path
d="M895.4 974.5H104.6c-43.6-.1-79-35.5-79.1-79.1V104.6c.1-43.6 35.5-79 79.1-79.1h790.8c43.6.1 79 35.5 79.1 79.1v790.8c-.2 43.6-35.5 79-79.1 79.1z"
fill="#00a0ef" />
<path class="st1"
d="M155 370.5h90.9c19.8 0 35.6 2 47.4 4 14.6 4.1 27.6 12.3 37.6 23.7 10.2 11.7 18.2 25 23.7 39.5 5.9 15.8 7.9 35.6 7.9 59.3 0 19.8-2 37.6-7.9 53.4-5.2 16.2-14 31.1-25.7 43.5-9.9 9.7-22.2 16.5-35.6 19.8-11.9 4-25.7 5.9-43.5 5.9h-94.9V370.5h.1zM406.1 619.6V370.5h49.4l100.7 166.1V370.5h47.5v249.1h-49.5L453.5 457.5v162.1zM643.2 538.6l49.4-4c2 15.8 7.9 27.7 17.8 35.6 10.1 8 22.7 12.2 35.6 11.9 12.6.6 25.1-2.9 35.6-9.9 7.3-5.7 11.7-14.4 11.9-23.7 0-5.9-2-9.9-5.9-15.8-4-4-9.9-7.9-17.8-9.9-5.9-2-19.8-5.9-39.5-9.9-20.5-4.1-39.9-12.1-57.3-23.7-15.1-12-23.8-30.2-23.7-49.4.5-12.5 3.9-24.7 9.9-35.6 7.6-11.6 18.7-20.6 31.6-25.7 15.8-6 32.6-8.7 49.4-7.9 31.6 0 55.4 5.9 71.2 19.8s23.7 31.6 25.7 55.4l-49.4 2c-2-11.9-5.9-21.7-13.8-27.7-7.9-5.9-17.8-7.9-31.6-7.9s-25.7 4-33.6 9.9c-5.9 4-7.9 9.9-7.9 15.8s2 11.9 7.9 15.8c5.9 5.9 21.7 9.9 45.5 15.8 23.7 5.9 41.5 11.9 53.4 17.8s21.7 13.8 27.7 25.7c6.7 12.1 10.2 25.7 9.9 39.5 0 13.8-4 27.7-11.9 39.5-8.3 12.3-20 21.9-33.6 27.7-17 6.9-35.1 10.2-53.4 9.9-31.6 0-57.1-5.9-73.2-21.7-18.1-17.9-25.8-41.7-29.9-69.3z" />
<path class="st2"
d="M273.6 576.1c7.9-2 15.8-5.9 19.8-9.9 5.9-4 9.9-13.8 13.8-23.7 4-11.9 5.9-25.7 5.9-45.5s-2-33.6-5.9-43.5c-3-8.7-7.7-16.8-13.8-23.7-6.5-6.2-14.8-10.4-23.7-11.9-7.9-2-19.8-2-41.5-2h-21.7V578h37.6c13.7.1 23.6.1 29.5-1.9z" />
<path class="st2"
d="M502.1 974.5h393.4c43.6-.1 79-35.5 79.1-79.1V540.6l-156-143.1c11.3 13.5 17.8 30.5 18.5 48.1l-49.4 2c-2-11.9-5.9-21.7-13.8-27.7-7.9-5.9-17.8-7.9-31.6-7.9s-25.7 4-33.6 9.9c-5.9 4-7.9 9.9-7.9 15.8s2 11.9 7.9 15.8c5.9 5.9 21.7 9.9 45.5 15.8s41.5 11.9 53.4 17.8 21.7 13.8 27.7 25.7c6.7 12.1 10.2 25.7 9.9 39.5 0 13.8-4 27.7-11.9 39.5-8.3 12.3-20 21.9-33.6 27.7-17 6.9-35.1 10.2-53.4 9.9-31.6 0-57.1-5.9-73.2-21.7-18-17.8-25.7-41.5-29.7-69.2l49.4-4c2 15.8 7.9 27.7 17.8 35.6 10.1 8 22.7 12.2 35.6 11.9 12.6.6 25.1-2.9 35.6-9.9 7.3-5.7 11.7-14.4 11.9-23.7 0-5.9-2-9.9-5.9-15.8-4-4-9.9-7.9-17.8-9.9-5.9-2-19.8-5.9-39.5-9.9-20.5-4.1-39.9-12.1-57.3-23.7-21.6-17.2-29.5-46.5-19.3-72.2l-49.8-45.6v248.4h-49.4L453.5 457.5v162.1h-47.4V477.8l-51.4-40.1c5.9 15.8 7.9 35.6 7.9 59.3 0 19.8-2 37.6-7.9 53.4-5.2 16.2-14 31.1-25.7 43.5-9.9 9.7-22.2 16.5-35.6 19.8-11.9 4-25.7 5.9-43.5 5.9H155v-6.9l-.4 6.9 347.5 354.9z" />
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1,218 +0,0 @@
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;
}

View File

@ -1,240 +0,0 @@
@charset "UTF-8";
/**
* {sonist app style}
* @authors yutent<yutent.io@gmail.com>
* @date 2018/12/16 17:15:07
*/
@mixin ts($c: all, $t: 0.1s, $m: ease-in-out) {
transition: $c $t $m;
}
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);
wc-scroll {
overflow: hidden;
flex: 1;
}
.domain-list {
width: 100%;
.item {
display: flex;
justify-content: flex-end;
align-items: center;
height: 40px;
padding: 0 20px 0 10px;
color: var(--color-plain-1);
cursor: pointer;
@include ts(background);
wc-icon {
--size: 12px;
margin: auto -15px auto 5px;
color: var(--color-grey-3);
}
&:hover,
&.active {
background: var(--color-dark-1);
}
&.active {
border-left: 0.3px solid var(--color-orange-1);
color: var(--color-orange-1);
font-weight: bold;
}
&.blank {
justify-content: center;
cursor: default;
&:hover {
background: none;
}
}
}
}
.action {
display: flex;
align-items: center;
height: 50px;
padding: 0 10px;
}
}
.layout-right {
flex: 1;
display: flex;
flex-direction: column;
background: #f7f8fb;
.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);
wc-input {
width: 200px;
}
}
.main {
overflow: hidden;
flex: 1;
display: flex;
flex-direction: column;
margin: 20px 10px;
padding: 0 5px;
background: #fff;
}
.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;
span {
flex: 1;
}
.long {
flex: 1.5;
}
}
wc-scroll {
flex: 1;
}
.record-list {
width: 100%;
line-height: 40px;
.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;
wc-input,
span,
section {
flex: 1;
}
.long {
flex: 1.5;
}
section {
display: flex;
align-items: center;
justify-content: center;
}
wc-button {
margin-left: 5px;
}
&: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);
backdrop-filter: blur(0.5rem);
pre {
font-family: 'Courier New', Courier, monospace;
font-size: 16px;
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.3);
font-family: 'Courier New', Courier, monospace;
}
}
&.show {
display: flex;
}
}
.context-menu {
display: flex;
flex-direction: column;
width: 100px;
padding: 5px 0;
background: #fff;
.item {
height: 30px;
line-height: 30px;
padding: 0 15px;
cursor: pointer;
&:hover {
background: #f2f5fc;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@ -1,108 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title></title>
<link href="/lib/css/reset-basic.css" rel="stylesheet">
<link href="/css/app.css" rel="stylesheet">
<script src="/js/app.js" type="module"></script>
</head>
<body anot="app" class="do-fn-noselect">
<div class="layout-left">
<wc-scroll>
<ul class="domain-list" @contextmenu="showMenu">
<li
class="item"
:class="{active: it === activeDomain}"
:for="it in domains"
:data-name="it"
@click="toggleDomain(it)">
<span :text="it"></span>
<wc-icon is="right"></wc-icon>
</li>
<li :if="domains.size() < 1" class="item blank">没有域名</li>
</ul>
</wc-scroll>
<section class="action">
<wc-button
title="新增域名"
type="info"
circle
icon="plus"
@click="addDomain">
</wc-button>
</section>
</div>
<div class="layout-right">
<header class="toolbar">
<wc-button icon="plus" type="primary" @click="addRecord">新增记录</wc-button>
<wc-button icon="fly" type="info" @click="save">保存</wc-button>
</header>
<main class="main">
<header class="thead">
<span class="long">主机记录</span>
<span>类型</span>
<span class="long">记录值</span>
<span class="long">操作</span>
<span>备注</span>
</header>
<wc-scroll ref="records">
<ul class="record-list">
<li class="item" :for="it in records">
<wc-input no-border autofocus class="long" @change="updateCacheDict(it)" :duplex="it.record" label="根域请填 @"></wc-input>
<span>A</span>
<wc-input no-border class="long" :duplex="it.value" label="请填写IP"></wc-input>
<section class="long">
<wc-switch :duplex="it.enabled" @change="recordChanges(it)"></wc-switch>
<wc-link size="mini" type="danger" @click="$remove">删除</wc-link>
<wc-link size="mini" type="info" @click="clone(it)">克隆</wc-link>
</section>
<wc-input no-border :duplex="it.remark"></wc-input>
</li>
</ul>
</wc-scroll>
</main>
</div>
<div class="permission-error" :if="permissionShow">
<pre>
/************************************************************/
* hosts文件没有写权限 *
/************************************************************/
</pre>
<fieldset>
<legend>操作指引</legend>
<dl>
<dt>MacOS用户</dt>
<dd>打开终端, 执行以下命令</dd>
<dd><code>sudo chown $USER:admin /etc/hosts</code></dd>
<dt>Linux用户</dt>
<dd>打开终端, 执行以下命令</dd>
<dd><code>sudo chown $USER: /etc/hosts</code></dd>
<dt>完成之后</dt>
<dd>点击下面的按钮重新检测.</dd>
<dd>
<wc-button color="red" size="mini" @click="check">权限检测</wc-button>
</dd>
</dl>
</fieldset>
</div>
<wc-layer ref="context" left="100px" top="0" radius="0">
<ul class="context-menu" @click="confirmAction">
<li class="item" data-act="del">删除域名</li>
<li class="item" data-act="edit">修改域名</li>
</ul>
</wc-layer>
</body>
</html>

View File

@ -1,234 +0,0 @@
/**
* {sonist app}
* @author yutent<yutent.io@gmail.com>
* @date 2018/12/16 17:15:57
*/
import '/lib/anot.js'
import '/lib/form/button.js'
import '/lib/form/link.js'
import '/lib/form/input.js'
import '/lib/form/switch.js'
import '/lib/layer/index.js'
import Utils from '/lib/utils.js'
const $doc = Anot(document)
let dict = {}
let tmp_records = {}
Anot({
$id: 'app',
state: {
filter: '',
activeDomain: Anot.ls('last_domain') || '', //当前选中的域名
editDomain: '', // 当前临时要编辑的域名, 即右键菜单选择到的
domains: [],
records: [],
permissionShow: false
},
mounted() {
// this.$refs.context.show()
this.check()
Utils.outside(this.$refs.context, ev => {
this.$refs.context.close()
})
},
watch: {},
methods: {
addRecord() {
if (this.activeDomain) {
this.records.unshift({
record: '',
value: '',
enabled: true,
remark: ''
})
this.$refs.records.scrollTop = 0
} else {
layer.toast('请先选择域名', 'warn')
}
},
addDomain() {
layer
.prompt('请输入根域名', function (val, done) {
if (
val === 'localhost' ||
val === 'local' ||
val === electron.hostname ||
/^[\w.\-]+\.[a-z]+$/.test(val)
) {
done()
} else {
layer.toast('域名格式错误', 'error')
}
})
.then(val => {
this.domains.push(val)
dict[val] = []
if (!this.activeDomain) {
this.toggleDomain(val)
}
this.save()
})
.catch(Anot.noop)
},
toggleDomain(name) {
this.activeDomain = name
this.records = (dict[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} `
Anot.ls('last_domain', name)
setTimeout(() => {
this.$refs.records.scrollTop = 0
}, 50)
},
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
Anot.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 (dict[this.editDomain].length > 0) {
return layer.toast('该域名下有主机记录, 请先删除主机记录后再删除域名', 'error')
}
}
delete dict[this.editDomain]
this.domains.remove(this.editDomain)
this.activeDomain = ''
this.editDomain = ''
this.records.clear()
this.save()
this.toggleDomain(this.domains[0])
})
.catch(Anot.noop)
} else if (act === 'edit') {
layer
.prompt(`请输入新的名字「${this.editDomain}`, (val, done) => {
if (val === this.editDomain || dict[val]) {
return
}
if (
val === 'localhost' ||
val === 'local' ||
val === electron.hostname ||
/^[\w.]+\.[a-z]+$/.test(val)
) {
done()
} else {
layer.toast('域名格式错误', 'error')
}
})
.then(val => {
var idx = this.domains.indexOf(this.editDomain)
this.domains.set(idx, val)
dict[val] = dict[this.editDomain]
delete dict[this.editDomain]
this.activeDomain = ''
this.editDomain = ''
this.save()
this.toggleDomain(val)
})
.catch(Anot.noop)
}
}
},
check() {
var check = electron.checkPermission()
if (check) {
dict = electron.getHistory()
var tmp = []
for (var k in dict) {
if (k) {
tmp.push(k)
} else {
delete dict[k]
}
}
this.domains = tmp
this.permissionShow = false
this.toggleDomain(Anot.ls('last_domain') || tmp[0])
} else {
this.permissionShow = true
}
},
updateCacheDict(item) {
clearTimeout(this.timer)
this.timer = setTimeout(_ => {
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]
}
}
}, 1000)
},
clone(item) {
var params = { ...item }
params.enabled = false
this.records.unshift(params)
tmp_records[params.record].push(this.records[0])
this.$refs.records.scrollTop = 0
},
// 同一个记录, 允许一条被激活
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) {
dict[this.activeDomain] = this.records.$model
}
electron.saveHosts(dict)
layer.toast('保存成功', 'success')
}
}
})

File diff suppressed because one or more lines are too long

View File

@ -1,82 +0,0 @@
@charset "UTF-8";
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2014-10-10 00:45:09
*
* CSS
*
* ,
*
*
* 1 display float position overflow z-index /
* 2 width height margin padding border
* 3 line-height font-size vertical-align text-align user-select outline ....
* 4 color background opacity cursor ...
* 5 content list-style quotes ...
*
*/
* {margin: 0;padding: 0;vertical-align: baseline;box-sizing: border-box;}
::before, ::after {box-sizing: border-box;}
/* HTML5 display-role reset for older browsers */
article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section,content {display: block;}
img {border: 0;display: inline-block;}
ol,ul {list-style: none;}
blockquote, q {quotes: none;}
blockquote::before, blockquote::after, q::before, q::after {content: '';content: none;}
table {border-collapse: collapse;border-spacing: 0;}
a:focus,input,textarea,button:focus,input:focus,textarea:focus {outline: none;}
::-moz-focus-inner {border: none;outline: none;}
body {font-family: 'Helvetica Neue', Arial, 'WenQuanYi Micro Hei', 'PingFang SC', 'Hiragino Sans GB', 'Segoe UI', 'Microsoft Yahei', sans-serif;-webkit-font-smoothing: antialiased;text-size-adjust: 100%;-webkit-tap-highlight-color: transparent;}
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 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;}
:root {
/* primary */
--color-teal-a: rgba(72, 201, 176, 0.35);
--color-teal-1: rgb(72, 201, 176);
--color-teal-2: rgb(26, 188, 156);
--color-teal-3: rgb(22, 160, 133);
/* success */
--color-green-a: rgba(70, 221, 126, 0.35);
--color-green-1: rgb(70, 221, 126);
--color-green-2: rgb(47, 208, 105);
--color-green-3: rgb(26, 196, 88);
/* info */
--color-blue-a: rgba(100, 181, 246, 0.35);
--color-blue-1: rgb(100, 181, 246);
--color-blue-2: rgb(66, 165, 245);
--color-blue-3: rgb(33, 150, 243);
/* danger */
--color-red-a: rgba(252, 118, 97, 0.35);
--color-red-1: rgb(252, 118, 97);
--color-red-2: rgb(255, 95, 69);
--color-red-3: rgb(243, 62, 34);
/* warning */
--color-orange-a: rgba(254, 174, 117, 0.35);
--color-orange-1: #feae75;
--color-orange-2: #fd964b;
--color-orange-3: #f97316;
/* default1 */
--color-plain-a: rgba(150, 204, 248, 0.35);
--color-plain-1: rgb(242, 245, 252);
--color-plain-2: rgb(232, 235, 244);
--color-plain-3: rgb(218, 225, 233);
/* default2 */
--color-grey-a: rgba(206, 214, 224, 0.35);
--color-grey-1: rgb(206, 214, 224);
--color-grey-2: rgb(164, 176, 190);
--color-grey-3: rgb(134, 144, 155);
/* inverse */
--color-dark-a: rgba(100, 116, 139, 0.35);
--color-dark-1: #64748B;
--color-dark-2: #475569;
--color-dark-3: #2c3441;
}

View File

@ -1 +0,0 @@
import e from"../utils.js";const c={axis:"",limit:!1,overflow:!0};class g{constructor(t){this.$elem=t,this._init()}_init(){this.$elem.style.transform="";var{x:t,y:n}=this.$elem.getBoundingClientRect();this.pos={x:t,y:n,_x:0,_y:0}}by(t,n={}){return this.$drag=t,this.opt=Object.assign(Object.create(null),c,n),this.opt.limit!==!1&&(this.opt.overflow=!1),t.style.cursor="move",this._handleResize=e.bind(window,"resize",this._init.bind(this)),this._handleMousedown=e.bind(t,"mousedown",p=>{if(this.disabled)return;var l=this.$elem.getBoundingClientRect();l.x-this.pos._x!==this.pos.x&&(this.pos.x=l.x-this.pos._x),l.y-this.pos._y!==this.pos.y&&(this.pos.y=l.y-this.pos._y);let r=p.pageX,a=p.pageY,u=document.documentElement.clientWidth,f=document.documentElement.clientHeight,d=l.width,m=l.height,s=[0,u-d,f-m,0];if(this.opt.limit==="parent"){let i=this.$elem.parentNode.getBoundingClientRect();s=[i.top,i.right-d,i.bottom-m,i.left]}let x=e.bind(document,"mousemove",i=>{i.preventDefault();let o=i.pageX-r+(l.x-this.pos.x),h=i.pageY-a+(l.y-this.pos.y);this.opt.axis==="x"&&(h=0),this.opt.axis==="y"&&(o=0),this.opt.overflow===!1&&(o<s[3]-this.pos.x?o=s[3]-this.pos.x:o>s[1]-this.pos.x&&(o=s[1]-this.pos.x),h<s[0]-this.pos.y?h=s[0]-this.pos.y:h>s[2]-this.pos.y&&(h=s[2]-this.pos.y)),this.pos._x=o,this.pos._y=h,this.$elem.dispatchEvent(new CustomEvent("dragging",{detail:{offset:{x:this.pos.x+o,y:this.pos.y+h},move:{x:o,y:h}}})),this.$elem.style.transform=`translate(${o}px, ${h}px)`}),y=e.bind(document,"mouseup",i=>{this.$elem.dispatchEvent(new CustomEvent("dragged",{detail:{offset:{x:this.pos.x+this.pos._x,y:this.pos.y+this.pos._y},move:{x:this.pos._x,y:this.pos._y}}})),e.unbind(document,"mousemove",x),e.unbind(document,"mouseup",y)})}),this}on(t,n){if(!(!t||typeof n!="function"))return e.bind(this,t,n)}off(t,n){e.unbind(this,t,n)}destroy(){e.unbind(window,"resize",this._handleResize),e.unbind(this.$drag,"mousedown",this._handleMousedown),delete this.$elem,delete this.$drag}}export{g as default};

View File

@ -1,85 +0,0 @@
# 拖拽插件
> 该插件可以让任意一个元素可以被拖拽,而不需要该元素是否具有定位属性。
> 使用时,在目标元素上添加`:drag`属性即可以实现拖拽功能。
## 依赖
> 依赖`Anot`框架
## 浏览器兼容性
+ chrome
+ firefox
+ safari
+ IE10+
## 用法
> 只需要在要拖拽的元素上添加`:drag`即可;
> 如果要拖拽的元素不是当前元素,只需要给该属性增加一个值为想要拖拽元素的类名或ID。
> 具体请看示例:
> **注意:** `拖拽的元素不是本身时,只会往父级一级一级找相匹配的`
```html
<!DOCTYPE html>
<html>
<head>
<style>
* {margin:0;padding:0}
.box {width:200px;height:100px;background:#aaa;}
.box .handle {width:200px;height:30px;background:#f30;}
</style>
</head>
<body :controller="test">
<div class="box" :drag></div>
<div class="box">
<div class="handle" :drag="box"></div>
</div>
<script>
import Anot from 'lib/drag/index.js'
Anot({
$id: 'test'
})
</script>
</body>
</html>
```
## 额外参数
### `data-limit`
> 用于限制元素的拖动范围,默认没有限制。 可选值为 "window"和"parent", 分别为 "限制在可视区"和"限制在父级元素的范围"
### `data-axis`
> 用于限制拖动的方向, 默认值为 "xy",即不限制方向。可选值为 "x"和"y", 即只能在"x轴"或"y轴"方向拖动。
### `data-beforedrag`
> 拖动前的回调,如果有设置回调方法, 则该回调的返回值,可决定该元素是否能被拖拽, 可用于在特殊场景下,临时禁用拖拽。
> `注:`
> 1. 该回调方法,会传入3个参数, 第1个为被拖拽的元素(dom对象), 第2个参数为 该元素的x轴绝对坐标, 第3个元素为y轴绝对坐标;
> 2. 该回调方法, 返回false时, 本次拖拽将临时失效, 返回其他值,或没有返回值,则忽略。
### `data-dragging`
> 元素被拖动时的回调。
> `注:`
> 1.该回调方法,会传入3个参数, 第1个为被拖拽的元素(dom对象), 第2个参数为 该元素的x轴绝对坐标, 第3个元素为y轴绝对坐标;
### `data-dragged`
> 元素被拖动结束后的回调。
> `注:`
> 1. 该回调方法,会传入3个参数, 第1个为被拖拽的元素(dom对象), 第2个参数为 该元素的x轴绝对坐标, 第3个元素为y轴绝对坐标;

View File

@ -1 +0,0 @@
import a from"./core.js";Anot.directive("drag",{priority:1500,init:function(e){e.expr='"'+e.expr+'"',e.overflow=!0,e.axis="xy",e.element.dataset.axis&&(e.axis=e.element.dataset.axis,delete e.element.dataset.axis),e.limit=!1,e.element.dataset.limit&&(e.limit=e.element.dataset.limit,e.overflow=!1,delete e.element.dataset.limit)},update:function(e){var t=this.element;if(e)for(t=this.element.parentNode;t;){if(t.classList||Anot.error(`${this.name}=${this.expr}, \u89E3\u6790\u5F02\u5E38[\u5143\u7D20\u4E0D\u5B58\u5728]`),t.tagName==="WC-LAYER"&&e==="layer"){t=t.root.children[1];break}if(t.classList.contains(e)||t.id===e)break;t=t.parentNode}new a(t).by(this.element,{limit:this.limit,axis:this.axis,overflow:this.overflow})}});

File diff suppressed because one or more lines are too long

View File

@ -1,10 +0,0 @@
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2022-06-23 15:46:28
* @version v1.0.6
*
*/
var d=Object.defineProperty;var n=(r,o,e)=>o in r?d(r,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[o]=e;var l=(r,o,e)=>(n(r,typeof o!="symbol"?o+"":o,e),e);import"../icon/index.js";import s from"../utils.js";class c extends HTMLElement{constructor(){super();l(this,"props",{value:"",checked:!1,readonly:!1,disabled:!1});Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;align-items:center;line-height:1;font-size:14px;cursor:pointer}:host label{display:flex;justify-content:center;align-items:center;min-width:32px;height: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 label.checked .dot{background:var(--color-dark-1)}:host label.checked .dot wc-icon{--size: 14px}:host .dot{display:flex;justify-content:center;align-items:center;width:16px;height:16px;margin-right:4px;border:1px solid var(--color-dark-1);border-radius:4px;background:#fff;color:#fff;transition:box-shadow .15s linear,background .15s linear}:host .dot wc-icon{--size: 0px;transition:width .15s linear}:host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-plain-a)}:host([type=danger]) label{color:var(--color-red-1)}:host([type=danger]) label .dot{border-color:var(--color-red-1)}:host([type=danger]) label.checked .dot{background:var(--color-red-1)}:host([type=danger]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-red-a)}:host([type=info]) label{color:var(--color-blue-1)}:host([type=info]) label .dot{border-color:var(--color-blue-1)}:host([type=info]) label.checked .dot{background:var(--color-blue-1)}:host([type=info]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-blue-a)}:host([type=success]) label{color:var(--color-green-1)}:host([type=success]) label .dot{border-color:var(--color-green-1)}:host([type=success]) label.checked .dot{background:var(--color-green-1)}:host([type=success]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-green-a)}:host([type=primary]) label{color:var(--color-teal-1)}:host([type=primary]) label .dot{border-color:var(--color-teal-1)}:host([type=primary]) label.checked .dot{background:var(--color-teal-1)}:host([type=primary]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-teal-a)}:host([type=warning]) label{color:var(--color-orange-1)}:host([type=warning]) label .dot{border-color:var(--color-orange-1)}:host([type=warning]) label.checked .dot{background:var(--color-orange-1)}:host([type=warning]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-orange-a)}:host([readonly]){cursor:default;opacity:.8}:host([disabled]){cursor:not-allowed;opacity:.6}:host([disabled]) label{color:var(--color-grey-2)}</style> <label tabindex="0"> <span class="dot"><wc-icon is="get"></wc-icon></span> <slot /> </label> ',this.__SWITCH__=this.root.lastElementChild,this.__ICO__=this.__SWITCH__.children[0],this._isInGroup=!1}static get observedAttributes(){return["value","checked","readonly","disabled"]}_checkGroup(){this._isInGroup=this.parentNode.tagName==="WC-CHECKBOX-GROUP",this._isInGroup&&this.parentNode.root&&this.parentNode.value.includes(this.value)&&(this.checked=!0)}get value(){return this.props.value}set value(e){this.props.value=e}get checked(){return this.props.checked}set checked(e){this.props.checked=!!e,this.__SWITCH__.classList.toggle("checked",this.props.checked)}get readOnly(){return this.props.readonly}set readOnly(e){var t=typeof e;e!==this.props.readonly&&(t==="boolean"&&e||t!=="boolean"?(this.props.readonly=!0,this.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&(t==="boolean"&&e||t!=="boolean"?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__SWITCH__.removeAttribute("tabindex")):(this.props.disabled=!1,this.removeAttribute("disabled")))}_toggleCheck(){this.disabled||this.readOnly||(this.checked=!this.checked,this._isInGroup?this.parentNode.dispatchEvent(new CustomEvent("child-picked",{detail:{value:this.value,checked:this.checked}})):this.dispatchEvent(new CustomEvent("input")))}connectedCallback(){this._checkGroup(),this._handlClick=s.bind(this,"click",e=>{e.stopPropagation(),this._toggleCheck()}),this._handlKeydown=s.bind(this,"keydown",e=>{e.keyCode===32&&this._toggleCheck()})}disconnectedCallback(){s.unbind(this,"click",this._handlClick),s.unbind(this,"keydown",this._handlKeydown)}attributeChangedCallback(e,t,a){if(t!==a)switch(e){case"value":this.props[e]=a;break;case"checked":case"readonly":case"disabled":var i=e;i==="readonly"&&(i="readOnly"),this[i]=a!==null;break}}}customElements.get("wc-checkbox")||customElements.define("wc-checkbox",c);export{c as default};

View File

@ -1,10 +0,0 @@
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2022-06-23 15:46:28
* @version v1.0.6
*
*/
var u=Object.defineProperty;var h=(i,r,e)=>r in i?u(i,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[r]=e;var l=(i,r,e)=>(h(i,typeof r!="symbol"?r+"":r,e),e);import d from"../utils.js";import"./checkbox-item.js";class o extends HTMLElement{constructor(){super();l(this,"props",{value:"",disabled:!1,readonly:!1});Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;flex-wrap:wrap}</style> <slot /> "}static get observedAttributes(){return["value","disabled","readonly"]}_updateChildrenStat(e){Array.from(this.children).forEach(t=>{t.tagName==="WC-CHECKBOX"?t.root&&(e&&(t.disabled=this.disabled,t.readOnly=this.readOnly),this.value.includes(t.value)?t.checked=!0:t.checked=!1):t.remove()})}get value(){return this.props.value}set value(e){e!==this.props.value&&(this.props.value=[...e],this._updateChildrenStat())}get readOnly(){return this.props.readonly}set readOnly(e){var t=typeof e;e!==this.props.readonly&&(t==="boolean"&&e||t!=="boolean"?(this.props.readonly=!0,this.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly")),this._updateChildrenStat(!0))}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&(t==="boolean"&&e||t!=="boolean"?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")),this._updateChildrenStat(!0))}connectedCallback(){this._pickedFn=d.bind(this,"child-picked",e=>{var t=[...this.props.value],s=t.indexOf(e.detail.value);e.detail.checked?s<0&&t.push(e.detail.value):~s&&t.splice(s,1),this.value=t,this.dispatchEvent(new CustomEvent("input"))}),this.__observer=new MutationObserver(e=>{this._updateChildrenStat(!0)}),this.__observer.observe(this,{childList:!0,subtree:!0})}disconnectedCallback(){d.unbind(this,"child-picked",this._pickedFn),this.__observer.disconnect()}attributeChangedCallback(e,t,s){if(t!==s)switch(e){case"value":s&&(this.value=s.split(",").map(n=>n.trim()));break;case"readonly":case"disabled":var a=e;a==="readonly"&&(a="readOnly"),this[a]=s!==null;break}}}customElements.get("wc-checkbox-group")||customElements.define("wc-checkbox-group",o);export{o as default};

View File

@ -1,10 +0,0 @@
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2022-06-23 15:46:28
* @version v1.0.6
*
*/
var h=Object.defineProperty;var d=(r,t,e)=>t in r?h(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var a=(r,t,e)=>(d(r,typeof t!="symbol"?t+"":t,e),e);import"../icon/index.js";import"./option.js";import o from"../utils.js";class n extends HTMLElement{constructor(){super();a(this,"props",{value:"",placeholder:"",size:"",disabled:!1});a(this,"state",{optionShow:!1});Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;min-width:128px;height:36px;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 .label{position:relative;display:flex;width:100%;height:100%;line-height:1;border:1px solid var(--color-grey-2);border-radius:inherit;white-space:nowrap;background:#fff;cursor:inherit;transition:background .15s linear}:host .preview{display:flex;align-items:center;width:100%;height:100%;padding:0 8px}:host .preview input{flex:1;width:0;border:0;font:inherit;color:inherit;background:none;outline:none;cursor:inherit}:host .preview input::placeholder{color:var(--color-grey-1)}:host .preview wc-icon{--size: 14px;color:var(--color-grey-2)}:host .options-box{overflow:hidden;visibility:hidden;position:absolute;left:0;top:36px;z-index:99;width:100%;height:0;border-radius:3px;background:#fff;box-shadow:0 3px 5px rgba(0,0,0,.15);transition:height .15s linear}:host .options-box.active{visibility:visible;height:auto;padding:6px 0}:host([size=large]){min-width:234px;height:52px;font-size:18px}:host([size=large]) .options-box{top:52px}:host([size=medium]){min-width:160px;height:44px}:host([size=medium]) .options-box{top:44px}:host([size=small]){min-width:96px;height:32px}:host([size=small]) .options-box{top:32px}:host([size=mini]){min-width:72px;height:26px;font-size:12px}:host([size=mini]) .preview wc-icon{--size: 10px}:host([size=mini]) .options-box{top:26px}:host(:focus-within){box-shadow:0 0 0 2px var(--color-plain-a)}:host([disabled]){cursor:not-allowed}:host([disabled]) .label{border-color:var(--color-grey-1);background:var(--color-plain-1);opacity:.6}</style> <div class="label"> <section class="preview"> <input readonly /> <wc-icon is="trigon-down"></wc-icon> </section> <div class="options-box"><slot /></div> </div> ';var e=this.root.children[1];this.__PREVIEW__=e.children[0],this.__OPTIONS__=e.children[1],this.__INPUT__=this.__PREVIEW__.children[0],this.__ICO__=this.__PREVIEW__.children[1]}static get observedAttributes(){return["value","placeholder","size","disabled"]}_updateChildrenStat(){Array.from(this.children).forEach(e=>{e.tagName==="WC-OPTION"?e.root&&(e.value===this.props.value?(e.setAttribute("active",""),this.__INPUT__.value=e.label||e.textContent):e.removeAttribute("active")):e.remove()})}get value(){return this.props.value}set value(e){this.props.value=e,this._updateChildrenStat()}get disabled(){return this.props.disabled}set disabled(e){var i=typeof e;e!==this.props.disabled&&(i==="boolean"&&e||i!=="boolean"?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__INPUT__.disabled=!0):(this.props.disabled=!1,this.removeAttribute("disabled"),this.__INPUT__.disabled=!1))}connectedCallback(){this._activeFn=o.bind(this.__PREVIEW__,"click",e=>{this.disabled||(this.state.optionShow=!this.state.optionShow,this.__OPTIONS__.classList.toggle("active",this.state.optionShow))}),this._pickedFn=o.bind(this.__OPTIONS__,"click",e=>{let i=e.target;if(i!==e.currentTarget){for(;i.tagName!=="WC-OPTION";)i=i.parentNode;this.props.value=i.value,this._updateChildrenStat(),this.dispatchEvent(new CustomEvent("input")),this.state.optionShow=!1,this.__OPTIONS__.classList.toggle("active",!1)}}),this._inactiveFn=o.outside(this,e=>{this.state.optionShow=!1,this.__OPTIONS__.classList.toggle("active",!1)}),o.nextTick(e=>this._updateChildrenStat())}disconnectedCallback(){this.state.options=[],o.unbind(this.__PREVIEW__,"click",this._activeFn),o.unbind(this.__OPTIONS__,"click",this._pickedFn),o.clearOutside(this._inactiveFn)}attributeChangedCallback(e,i,s){if(i!==s)switch(e){case"value":s!==null&&(this.value=s);break;case"placeholder":this.__INPUT__.placeholder=s||"";break;case"size":s&&Array.from(this.children).forEach(l=>{l.setAttribute("size",s)});break;case"disabled":this.disabled=s!==null;break}}}customElements.get("wc-dropdown")||customElements.define("wc-dropdown",n);export{n as default};

View File

@ -1 +0,0 @@
import"./button.js";import"./link.js";import"./input.js";import"./passwd.js";import"./textarea.js";import"./number.js";import"./radio.js";import"./checkbox.js";import"./switch.js";import"./select.js";import"./dropdown.js";import"./star.js";

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,10 +0,0 @@
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2022-06-23 15:46:28
* @version v1.0.6
*
*/
var n=Object.defineProperty;var b=(s,t,e)=>t in s?n(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var r=(s,t,e)=>(b(s,typeof t!="symbol"?t+"":t,e),e);import o from"../utils.js";class a extends HTMLElement{constructor(){super();r(this,"props",{value:"",label:"",disabled:!1});Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:flex;justify-content:space-between;align-items:center;height:36px;transition:background .15s linear;color:var(--color-dark-1);cursor:pointer}:host label{flex:1;display:flex;justify-content:space-between;align-items:center;height:100%;padding:0 8px;cursor:inherit}:host([size=large]){height:52px}:host([size=medium]){height:44px}:host([size=small]){height:32px}:host([size=mini]){height:26px}:host(:hover) label,:host([active]) label{background:var(--color-plain-1)}:host([disabled]){color:var(--color-grey-1);opacity:.6;cursor:not-allowed}</style> <label><slot /></label> ",this.__LABEL__=this.root.children[1]}static get observedAttributes(){return["value","label","disabled"]}get value(){return this.props.value}set value(e){e!==this.props.value&&(this.props.value=e)}get label(){return this.props.label}set label(e){e!==this.props.label&&(this.props.label=e,this.__LABEL__.textContent=e)}get disabled(){return this.props.disabled}set disabled(e){var i=typeof e;e!==this.props.disabled&&(i==="boolean"&&e||i!=="boolean"?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}connectedCallback(){this._clickFn=o.bind(this,"click",e=>{this.disabled&&e.stopPropagation()})}disconnectedCallback(){o.unbind(this,"click",this._clickFn)}attributeChangedCallback(e,i,l){if(i!==l)switch(e){case"value":case"label":l===null?this[e]="":this[e]=l;break;case"disabled":this.disabled=l!==null;break}}}customElements.get("wc-option")||customElements.define("wc-option",a);export{a as default};

File diff suppressed because one or more lines are too long

View File

@ -1,10 +0,0 @@
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2022-06-23 15:46:28
* @version v1.0.6
*
*/
var n=Object.defineProperty;var c=(r,o,e)=>o in r?n(r,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[o]=e;var i=(r,o,e)=>(c(r,typeof o!="symbol"?o+"":o,e),e);import a from"../utils.js";class d extends HTMLElement{constructor(){super();i(this,"props",{value:"",checked:!1,readonly:!1,disabled:!1});Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;align-items:center;line-height:1;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 label.checked .dot::after{visibility:visible;transform:scale(1)}:host .dot{display:flex;justify-content:center;align-items:center;width:16px;height:16px;margin-right:4px;border:1px solid var(--color-dark-1);border-radius:50%;background:#fff;transition:box-shadow .15s linear}:host .dot::after{display:block;visibility:hidden;width:6px;height:6px;border-radius:50%;background:var(--color-dark-1);content:"";transform:scale(0);transition:transform .15s linear}:host(:focus-within) .dot{box-shadow:0 0 0 2px var(--color-plain-a)}:host([type=danger]) label{color:var(--color-red-1)}:host([type=danger]) label .dot{border-color:var(--color-red-1)}:host([type=danger]) label .dot::after{background:var(--color-red-1)}:host([type=danger]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-red-a)}:host([type=success]) label{color:var(--color-green-1)}:host([type=success]) label .dot{border-color:var(--color-green-1)}:host([type=success]) label .dot::after{background:var(--color-green-1)}:host([type=success]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-green-a)}:host([type=primary]) label{color:var(--color-teal-1)}:host([type=primary]) label .dot{border-color:var(--color-teal-1)}:host([type=primary]) label .dot::after{background:var(--color-teal-1)}:host([type=primary]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-teal-a)}:host([type=warning]) label{color:var(--color-orange-1)}:host([type=warning]) label .dot{border-color:var(--color-orange-1)}:host([type=warning]) label .dot::after{background:var(--color-orange-1)}:host([type=warning]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-orange-a)}:host([type=info]) label{color:var(--color-blue-1)}:host([type=info]) label .dot{border-color:var(--color-blue-1)}:host([type=info]) label .dot::after{background:var(--color-blue-1)}:host([type=info]:focus-within) .dot{box-shadow:0 0 0 2px var(--color-blue-a)}:host([readonly]){cursor:default;opacity:.8}:host([disabled]){cursor:not-allowed;opacity:.6}:host([disabled]) label{color:var(--color-grey-2)}:host([disabled]) label .dot{border-color:var(--color-grey-1);box-shadow:none}:host([disabled]) label .dot::after{background:var(--color-grey-1)}</style> <label tabindex="0"> <span class="dot"></span> <slot /> </label> ',this.__SWITCH__=this.root.lastElementChild}static get observedAttributes(){return["value","checked","readonly","disabled"]}get value(){return this.props.value}set value(e){this.props.value=e}get checked(){return this.props.checked}set checked(e){this.props.checked=!!e,this.__SWITCH__.classList.toggle("checked",this.props.checked)}get readOnly(){return this.props.readonly}set readOnly(e){var t=typeof e;e!==this.props.readonly&&(t==="boolean"&&e||t!=="boolean"?(this.props.readonly=!0,this.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&(t==="boolean"&&e||t!=="boolean"?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__SWITCH__.removeAttribute("tabindex")):(this.props.disabled=!1,this.removeAttribute("disabled")))}_toggleCheck(){this.disabled||this.readOnly||this.checked||(this.checked=!0,this.parentNode.dispatchEvent(new CustomEvent("child-picked",{detail:this.value})))}connectedCallback(){this.value===this.parentNode.value&&(this.checked=!0),this._handleClick=a.catch(this,"click",e=>{e.stopPropagation(),this._toggleCheck()}),this._handlKeydown=a.bind(this,"keydown",e=>{e.keyCode===32&&this._toggleCheck()})}disconnectedCallback(){a.unbind(this,"click",this._handleClick),a.unbind(this,"keydown",this._handlKeydown)}attributeChangedCallback(e,t,s){if(t!==s)switch(e){case"value":this.value=s;break;case"checked":case"readonly":case"disabled":var l=e;l==="readonly"&&(l="readOnly"),this[l]=s!==null;break}}}customElements.get("wc-radio")||customElements.define("wc-radio",d);export{d as default};

View File

@ -1,10 +0,0 @@
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2022-06-23 15:46:28
* @version v1.0.6
*
*/
var n=Object.defineProperty;var u=(s,r,e)=>r in s?n(s,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[r]=e;var d=(s,r,e)=>(u(s,typeof r!="symbol"?r+"":r,e),e);import l from"../utils.js";import"./radio-item.js";class o extends HTMLElement{constructor(){super();d(this,"props",{value:null,disabled:!1,readonly:!1});Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;flex-wrap:wrap}</style> <slot /> "}static get observedAttributes(){return["value","disabled","readonly"]}_updateChildrenStat(e){Array.from(this.children).forEach(t=>{t.tagName==="WC-RADIO"?t.root&&(e&&(t.disabled=this.disabled,t.readOnly=this.readOnly),t.value===this.props.value?t.checked=!0:t.checked=!1):t.remove()})}get value(){return this.props.value}set value(e){e!==this.props.value&&(this.props.value=e,this._updateChildrenStat())}get readOnly(){return this.props.readonly}set readOnly(e){var t=typeof e;e!==this.props.readonly&&(t==="boolean"&&e||t!=="boolean"?(this.props.readonly=!0,this.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly")),this._updateChildrenStat(!0))}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&(t==="boolean"&&e||t!=="boolean"?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")),this._updateChildrenStat(!0))}connectedCallback(){this._pickedFn=l.bind(this,"child-picked",e=>{this.value=e.detail,this.dispatchEvent(new CustomEvent("input"))}),this.__observer=new MutationObserver(e=>{this._updateChildrenStat(!0)}),this.__observer.observe(this,{childList:!0,subtree:!0})}disconnectedCallback(){l.unbind(this,"child-picked",this._pickedFn),this.__observer.disconnect()}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"value":this.value=i;break;case"readonly":case"disabled":var a=e;a==="readonly"&&(a="readOnly"),this[a]=i!==null;break}}}customElements.get("wc-radio-group")||customElements.define("wc-radio-group",o);export{o as default};

File diff suppressed because one or more lines are too long

View File

@ -1,10 +0,0 @@
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2022-06-23 15:46:28
* @version v1.0.6
*
*/
var l=Object.defineProperty;var d=(i,t,e)=>t in i?l(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var a=(i,t,e)=>(d(i,typeof t!="symbol"?t+"":t,e),e);import c from"../utils.js";class o extends HTMLElement{constructor(){super();a(this,"props",{"active-text":null,"inactive-text":null,checked:!1,disabled:!1});Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;align-items:center}:host section{display:flex;justify-content:center;align-items:center;line-height:1;white-space:nowrap}:host label{display:flex;align-items:center;width:32px;height:18px;padding:3px;margin:5px;border-radius:21px;background:var(--color-plain-3);cursor:inherit}:host label.checked{flex-direction:row-reverse;background:var(--color-grey-3)}:host .dot{width:12px;height:12px;border-radius:50%;background:#fff}:host([disabled]){cursor:not-allowed;opacity:.6}:host([size=large]) label{width:46px;height:26px;padding:3px 5px}:host([size=large]) .dot{width:18px;height:18px}:host([size=medium]) label{width:38px;height:22px;padding:3px 4px}:host([size=medium]) .dot{width:16px;height:16px}:host([size=mini]) label{width:22px;height:14px;padding:2px}:host([size=mini]) .dot{width:10px;height:10px}:host([type=danger]) label.checked{background:var(--color-red-1)}:host([type=info]) label.checked{background:var(--color-blue-1)}:host([type=success]) label.checked{background:var(--color-green-1)}:host([type=primary]) label.checked{background:var(--color-teal-1)}:host([type=warning]) label.checked{background:var(--color-orange-1)}:host([type=inverse]) label.checked{background:var(--color-dark-1)}:host([color=purple]) label.checked{background:var(--color-purple-1)}</style> <section> <label> <span class="dot"></span> </label> <slot></slot> </section> ',this.__SWITCH__=this.root.lastElementChild.firstElementChild}static get observedAttributes(){return["active-text","inactive-text","checked","disabled"]}get value(){return this.props.checked}set value(e){this.checked=e}get checked(){return this.props.checked}set checked(e){this.props.checked=!!e,this.__SWITCH__.classList.toggle("checked",this.props.checked)}get disabled(){return this.props.disabled}set disabled(e){var s=typeof e;e!==this.props.disabled&&(s==="boolean"&&e||s!=="boolean"?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}_updateStat(){this.checked?this.props["active-text"]!==null&&(this.textContent=this.props["active-text"]):this.props["inactive-text"]!==null&&(this.textContent=this.props["inactive-text"])}connectedCallback(){this._handleClick=c.bind(this,"click",e=>{this.disabled||(this.checked=!this.checked,this._updateStat(),this.dispatchEvent(new CustomEvent("input")))})}disconnectedCallback(){c.unbind(this,"click",this._handleClick)}attributeChangedCallback(e,s,r){if(s!==r)switch(e){case"checked":case"disabled":this[e]=r!==null;break;case"active-text":case"inactive-text":this.props[e]=r+"",this._updateStat();break}}}customElements.get("wc-switch")||customElements.define("wc-switch",o);export{o as default};

View File

@ -1,10 +0,0 @@
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2022-06-23 15:46:28
* @version v1.0.6
*
*/
var b=Object.defineProperty;var c=(s,r,e)=>r in s?b(s,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[r]=e;var h=(s,r,e)=>(c(s,typeof r!="symbol"?r+"":r,e),e);import n from"../utils.js";class d extends HTMLElement{constructor(){super();h(this,"props",{value:"",placeholder:"",maxlength:0,minlength:0,autofocus:!1,readonly:!1,disabled:!1,lazy:0});Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:flex;width:100%;height:80px;user-select:none;-moz-user-select:none;color:var(--color-dark-1);border-radius:3px;cursor:text;transition:box-shadow .15s linear}.label{position:relative;width:100%;height:100%;font-size:14px;border:1px solid var(--color-grey-2);border-radius:inherit;background:var(--bg-color, #fff);color:inherit;cursor:inherit}.label textarea{flex:1;min-width:36px;width:100%;height:100%;padding:5px 8px;border:0;border-radius:inherit;color:inherit;font:inherit;background:none;outline:none;box-shadow:none;cursor:inherit;resize:none}.label textarea::placeholder{color:var(--color-grey-1)}.label .input-stat{display:none;position:absolute;right:4px;bottom:2px;z-index:1;line-height:1;font-size:12px;color:var(--color-grey-2)}:host([show-limit]) .label{padding-bottom:14px}:host([show-limit]) .label .input-stat{display:block}:host([disabled]){cursor:not-allowed}:host([disabled]) .label{background:var(--color-plain-1);opacity:.6}:host([readonly]){cursor:default}:host(:focus-within){box-shadow:0 0 0 2px var(--color-plain-a)}:host([type=primary]:focus-within){box-shadow:0 0 0 2px var(--color-teal-a)}:host([type=info]:focus-within){box-shadow:0 0 0 2px var(--color-blue-a)}:host([type=success]:focus-within){box-shadow:0 0 0 2px var(--color-green-a)}:host([type=danger]:focus-within){box-shadow:0 0 0 2px var(--color-red-a)}:host([type=warning]:focus-within){box-shadow:0 0 0 2px var(--color-orange-a)}:host([type=primary]) .label{border-color:var(--color-teal-2)}:host([type=info]) .label{border-color:var(--color-blue-2)}:host([type=success]) .label{border-color:var(--color-green-2)}:host([type=danger]) .label{border-color:var(--color-red-2)}:host([type=warning]) .label{border-color:var(--color-orange-2)}:host([no-border]),:host(:focus-within[no-border]){box-shadow:none}:host([no-border]) .label,:host(:focus-within[no-border]) .label{border:0}</style> <div class="label"> <textarea spellcheck="false"></textarea> <div class="input-stat">0/\u221E</div> </div> ',this.__OUTER__=this.root.children[1],this.__INPUT__=this.__OUTER__.children[0],this.__STAT__=this.__OUTER__.children[1]}static get observedAttributes(){return["value","placeholder","maxlength","minlength","autofocus","readonly","disabled","lazy"]}get readOnly(){return this.props.readonly}set readOnly(e){var t=typeof e;e!==this.props.readonly&&(t==="boolean"&&e||t!=="boolean"?(this.props.readonly=!0,this.setAttribute("readonly",""),this.__INPUT__.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly"),this.__INPUT__.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&(t==="boolean"&&e||t!=="boolean"?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__INPUT__.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled"),this.__INPUT__.removeAttribute("disabled")))}get value(){return this.__INPUT__.value}set value(e){this.__INPUT__.value=e}connectedCallback(){this.stamp=0,this._handleSubmit=n.catch(this.__INPUT__,"keydown",e=>{let{minlength:t,lazy:o}=this.props,a=this.value,i=Date.now();if(e.keyCode===13&&(e.ctrlKey||e.metaKey)){if(this.disabled||this.readOnly||o&&i-this.stamp<o||t&&t>0&&a.length<t)return;this.stamp=i,this.dispatchEvent(new CustomEvent("submit",{detail:this.value}))}}),this._statFn=n.bind(this.__INPUT__,"input,change",e=>{let{maxlength:t}=this.props,o=this.value.length;t=t||"\u221E",this.__STAT__.textContent=`${o}/${t}`})}disconnectedCallback(){n.unbind(this.__INPUT__,"keydown",this._handleSubmit),n.unbind(this.__INPUT__,"input,change",this._statFn)}attributeChangedCallback(e,t,o){if(t!==o)switch(e){case"autofocus":this.__INPUT__.setAttribute("autofocus",""),setTimeout(i=>{this.__INPUT__.focus()},10);break;case"placeholder":this.__INPUT__.setAttribute("placeholder",o);break;case"value":this.value=o||"";break;case"maxlength":{let i=this.value.length;if(o===null)this.__INPUT__.removeAttribute(e),this.props.maxlength=0,this.__STAT__.textContent=`${i}/\u221E`;else{let l=+o;l>0?(this.__INPUT__.setAttribute(e,l),this.props.maxlength=l,this.__STAT__.textContent=`${i}/${l}`):this.removeAttribute(e)}}break;case"lazy":this.props.lazy=o>>0;break;case"readonly":case"disabled":var a=e;a==="readonly"&&(a="readOnly"),this[a]=o!==null;break}}}customElements.get("wc-textarea")||customElements.define("wc-textarea",d);export{d as default};

View File

@ -1,10 +0,0 @@
/**
*
* @authors yutent (yutent.io@gmail.com)
* @date 2022-06-23 15:46:28
* @version v1.0.6
*
*/
var n=Object.defineProperty;var l=(e,i,t)=>i in e?n(e,i,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[i]=t;var o=(e,i,t)=>(l(e,typeof i!="symbol"?i+"":i,t),t);import d from"./svg.js";let a=d;window.EXT_SVG_DICT&&Object.assign(a,EXT_SVG_DICT);class h extends HTMLElement{constructor(){super();o(this,"props",{is:""});Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;width:var(--size, 36px);height:var(--size, 36px);color:inherit}:host(:not([is])){display:none}.icon{display:block;width:100%;height:100%;fill:currentColor}.icon.load{animation:load 1.5s linear infinite}.icon circle{stroke:currentColor;animation:circle 1.5s ease-in-out infinite}:host([size=large]){width:52px;height:52px}:host([size=medium]){width:44px;height:44px}:host([size=small]){width:32px;height:32px}:host([size=mini]){width:26px;height:26px}@keyframes circle{0%{stroke-dasharray:0,3812px;stroke-dashoffset:0}50%{stroke-dasharray:1906px,3812px;stroke-dashoffset:-287px}100%{stroke-dasharray:1906px,3812px;stroke-dashoffset:-2393px}}@keyframes load{to{transform:rotate(360deg)}}</style> <svg class="icon" viewBox="0 0 1024 1024"></svg> ',this.__ICO__=this.root.lastElementChild,this.drawPath()}static get observedAttributes(){return["is"]}get is(){return this.props.is}set is(t){t&&this.setAttribute("is",t)}drawPath(){var{is:t}=this.props,s=a[t];!this.__ICO__||t&&s&&(this.__ICO__.innerHTML=t==="loading"?s:`<path d="${s}" />`,this.__ICO__.classList.toggle("load",t==="loading"))}attributeChangedCallback(t,s,r){if(s!==r)switch(t){case"is":this.props.is=r,r?this.drawPath():this.removeAttribute("is");break}}}customElements.get("wc-icon")||customElements.define("wc-icon",h);export{h as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
function l(){}var o={nextTick:function(){let t=[],n=document.createTextNode("<!-- -->"),e=!1;function r(){let i=t.length;for(let a=0;a<i;a++)t[a]();t=t.slice(i)}return new MutationObserver(r).observe(n,{characterData:!0}),function(i){t.push(i),e=!e,n.data=e}}(),offset(t){try{var n=t.getBoundingClientRect();if(n.width||n.height||t.getClientRects().length){var e=t.ownerDocument,r=e.documentElement,i=e.defaultView;return{top:n.top+i.pageYOffset-r.clientTop,left:n.left+i.pageXOffset-r.clientLeft}}}catch(a){return{left:0,top:0}}},each(t,n){if(t){if(Array.isArray(t))for(let e=0,r;(r=t[e++])&&n(r,e-1)!==!1;);else for(let e in t)if(t.hasOwnProperty(e)&&n(t[e],e)===!1)break}},bind(t,n,e=l,r=!1){let i=n.split(",");return this.each(i,function(a){a=a.trim(),t.addEventListener(a,e,r)}),e},catch(t,n,e,r){function i(a){a.stopPropagation&&a.stopPropagation(),e&&e(a)}return this.bind(t,n,i,r)},unbind(t,n,e=l,r=!1){let i=n.split(",");this.each(i,function(a){a=a.trim(),t.removeEventListener(a,e,r)})},outside(t,n=l){return this.bind(document,"mousedown",e=>{if(e)if(e.path){for(var r=e.path.concat();r.length>3;)if(r.shift()===t)return}else{var i=e.explicitOriginalTarget||e.target;if(t===i||t.contains(i)||t.root&&t.root.contains(i))return}n(e)})},clearOutside(t=l){this.unbind(document,"mousedown",t)}};export{o as default};

View File

@ -1,101 +0,0 @@
/**
*
* @author yutent<yutent.io@gmail.com>
* @date 2019/09/16 20:51:19
*/
const { app, BrowserWindow, protocol, Menu, ipcMain } = require('electron')
const { join, resolve, extname } = require('path')
const { cat, echo, isfile } = require('./tools/utils.js')
const os = require('os')
const createMenu = require('./tools/menu')
const MIME_TYPES = {
'.js': 'text/javascript',
'.html': 'text/html',
'.htm': 'text/plain',
'.css': 'text/css',
'.jpg': 'image/jpg',
'.png': 'image/png',
'.gif': 'image/gif',
'.svg': 'image/svg+xml',
'.ico': 'image/ico'
}
const ROOT = __dirname
const HOST_FILE = resolve(app.getPath('userData'), 'host.cache')
const LOCK_FILE = resolve(app.getPath('userData'), 'lock')
/* ********** 修复环境变量 start *********** */
let pathEnv = new Set()
process.env.PATH.split(':').forEach(_ => {
pathEnv.add(_)
})
pathEnv.add('/usr/local/bin')
pathEnv.add('/usr/local/sbin')
process.env.PATH = Array.from(pathEnv).join(':')
pathEnv = null
/* ********** 修复环境变量 end *********** */
/* ----------------------------------------------------- */
app.commandLine.appendSwitch('--lang', 'zh-CN')
app.commandLine.appendSwitch('--autoplay-policy', 'no-user-gesture-required')
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { secure: true, standard: true } }
])
/* ----------------------------------------------------- */
if (!isfile(HOST_FILE)) {
echo('{}', HOST_FILE)
}
ipcMain.on('ready', ev => {
ev.returnValue = { HOST_FILE, LOCK_FILE, HOST: os.hostname() }
})
// 初始化应用
app.once('ready', () => {
// 注册协议
protocol.registerBufferProtocol('app', (req, cb) => {
let file = req.url.replace(/^app:\/\/local\//, '')
let ext = extname(req.url)
let buff = cat(resolve(ROOT, file))
cb({ data: buff, mimeType: MIME_TYPES[ext] })
})
Menu.setApplicationMenu(null)
// 创建浏览器窗口
let win = new BrowserWindow({
title: 'Hosts切换器',
width: 1000,
height: 640,
resizable: false,
maximizable: false,
icon: resolve(ROOT, './images/app.png'),
webPreferences: {
// webSecurity: false,
// experimentalFeatures: true,
// nodeIntegration: true,
preload: join(ROOT, './tools/inject.js')
}
})
win.on('closed', () => {
app.exit()
win = null
})
// win.openDevTools()
// 然后加载应用的 index.html
win.loadURL('app://local/index.html')
if (process.platform === 'darwin') {
createMenu(win)
}
})

View File

@ -1,98 +0,0 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2022/07/14 11:54:32
*/
const { ipcRenderer, shell, contextBridge } = require('electron')
const { resolve } = require('path')
const { cat, echo, isfile, writable } = require('./utils.js')
const { HOST_FILE, LOCK_FILE, HOST } = ipcRenderer.sendSync('ready')
let timer = null
contextBridge.exposeInMainWorld('electron', {
hostname: HOST,
open(url) {
shell.openExternal(url)
},
checkPermission() {
return writable('/etc/hosts')
},
getHistory() {
if (isfile(LOCK_FILE)) {
var cache = cat(HOST_FILE)
return JSON.parse(cache)
}
var cache = cat('/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
echo(JSON.stringify(dict), HOST_FILE)
echo('', LOCK_FILE)
return dict
},
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'
}
echo(JSON.stringify(dict), HOST_FILE)
echo(txt, '/etc/hosts')
}, 1000)
}
})

View File

@ -1,65 +0,0 @@
/**
* 菜单项
* @author yutent<yutent.io@gmail.com>
* @date 2019/01/21 20:34:04
*/
const { Menu } = require('electron')
module.exports = function (win) {
let menuList = Menu.buildFromTemplate([
{
label: 'Hosts切换器',
submenu: [
{ role: 'about', label: '关于 Hosts切换器' },
{ type: 'separator' },
{ role: 'quit', label: '退出' }
]
},
{
label: '编辑',
submenu: [
{ role: 'undo', label: '撤消重做' },
{ role: 'redo', label: '重做' },
{ type: 'separator' },
{ role: 'cut', label: '剪切' },
{ role: 'copy', label: '复制' },
{ role: 'paste', label: '粘贴' },
{ role: 'selectall', label: '全选' }
]
},
{
label: '显示',
submenu: [
{ label: 'Hosts切换器' },
{
type: 'separator'
},
{ label: 'Hosts切换器' }
]
},
{
label: '窗口',
submenu: [
{
role: 'minimize',
label: '最小化',
click() {
win.minimize()
}
}
]
},
{
role: 'help',
label: '帮助',
submenu: [
{
label: '官网',
click() {}
}
]
}
])
Menu.setApplicationMenu(menuList)
}

View File

@ -1,87 +0,0 @@
/**
*
* @author yutent<yutent.io@gmail.com>
* @date 2022/07/14 11:06:47
*/
const fs = require('fs')
const { parse } = require('path')
/**
* [stat 返回文件/目录的状态信息]
* @param {[string]} path [目标路径]
*/
function stat(path) {
try {
return fs.statSync(path)
} catch (err) {
return EMPTY_STAT
}
}
/**
* [isdir 判断目标是否为目录]
* @param {String} path [目标路径]
*/
function isdir(path) {
try {
return stat(path).isDirectory()
} catch (err) {}
}
/**
* [mkdir 新建目录]
* @param {String} dir [目标路径]
* @param {Number} mode [目录权限, node v10.12起支持]
*/
function mkdir(dir, mode = 0o755) {
try {
fs.mkdirSync(dir, { recursive: true, mode: mode })
return true
} catch (err) {}
}
//
exports.cat = function (file) {
try {
return fs.readFileSync(file)
} catch (e) {}
}
exports.echo = function (data, file, append) {
if (!file) {
return data
}
let updir = parse(file).dir
let opt = {}
if (!isdir(updir)) {
mkdir(updir)
}
try {
if (append) {
fs.appendFileSync(file, data, opt)
} else {
fs.writeFileSync(file, data, opt)
}
} catch (err) {}
}
exports.isfile = function (path) {
try {
return stat(path).isFile()
} catch (err) {
return false
}
}
exports.writable = function (file) {
try {
fs.accessSync('/etc/hosts', fs.constants.W_OK)
return true
} catch (e) {
return false
}
}

View File

@ -6,7 +6,8 @@ gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GLib, Gio, GObject, GdkPixbuf
from webengine.gtk3 import WebEngine, create_setting, create_hmr_server
from we.gtk3 import WebEngine, create_setting, create_hmr_server
# from webengine.gtk3 import WebEngine, create_setting, create_hmr_server
from window import Window
APP_ID = 'fun.wkit.hosts-switch'

View File

@ -8,6 +8,7 @@ import 'es.shim'
import { html, css, Component } from 'wkit'
import { createApp, createRouter } from 'wkitd'
import store from './store.js'
import './components/home.js'
createApp({
@ -23,13 +24,6 @@ createApp({
width: 100%;
height: 100vh;
}
.app {
display: flex;
width: 100%;
}
router-view {
flex: 1;
}
`
],
methods: {
@ -38,6 +32,8 @@ createApp({
}
},
render() {
return html` <wc-home></wc-home> `
return html` <wc-home @contextmenu.prevent2=${function () {}}></wc-home> `
}
}).mount()
})
.use(store)
.mount()

View File

@ -3,34 +3,29 @@
* @author yutent<yutent.io@gmail.com>
* @date 2023/08/08 18:19:17
*/
import { html, css, Component, classMap, nextTick } from 'wkit'
import { html, css, Component, classMap, nextTick, outsideClick } from 'wkit'
import 'ui/icon/index.js'
import 'ui/scroll/index.js'
import 'ui/layer/index.js'
// import 'local/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 './sidebar.js'
import './permission.js'
import './records.js'
import { getHistory, saveHosts } from '../utils/index.js'
import { checkPermission, getHistory, saveHosts, noop } from '../utils/index.js'
const HOST_DATA = await getHistory()
let tmp_records = Object.create(null)
function noop() {}
class Home extends Component {
static props = {
filter: '',
activeDomain: localStorage.getItem('last_domain') || '', //当前选中的域名
editDomain: '', // 当前临时要编辑的域名, 即右键菜单选择到的
domains: Object.keys(HOST_DATA),
records: [],
permissionShow: false
}
@ -59,74 +54,14 @@ class Home extends Component {
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;
}
.layout-left .domain-list {
width: 100%;
}
.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;
}
.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 {
.main {
flex: 1;
display: flex;
flex-direction: column;
}
.layout-right .toolbar {
.main .toolbar {
display: flex;
align-items: center;
justify-content: space-between;
@ -135,54 +70,9 @@ class Home extends Component {
border-bottom: 1px solid var(--color-plain-3);
background: var(--color-plain-1);
}
`,
css`
.layout-right .main {
.main .list {
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;
}
`,
@ -208,59 +98,33 @@ class Home extends Component {
`
]
mounted() {
async 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)
}
let writable = await checkPermission()
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]
}
if (writable) {
this.$store.HOST_DATA = HOST_DATA
this.$store.domains = Object.keys(HOST_DATA)
this.$refs.domain.mounted()
outsideClick(this.$refs.context, _ => this.$refs.context.close())
} else {
this.permissionShow = true
}
}
addRecord() {
if (this.$store.activeDomain) {
this.$store.records.push({
record: '',
value: '',
enabled: true,
remark: ''
})
nextTick(_ => (this.$refs.list.scrollTop = 1e6))
} else {
layer.toast('请先选择域名', 'warn')
}
document.title = `伪域名解析 ${name} `
localStorage.setItem('last_domain', name)
nextTick(() => {
this.$refs.records.scrollTop = 0
})
}
showMenu(ev) {
@ -276,7 +140,7 @@ class Home extends Component {
elem = elem.parentNode
}
this.editDomain = elem.dataset.name
nextTick(_ => {
setTimeout(_ => {
this.$refs.context.moveTo({ left: pageX + 'px', top: pageY + 'px' })
this.$refs.context.show()
})
@ -347,113 +211,39 @@ class Home extends Component {
}
}
// 同一个记录, 允许一条被激活
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
let { HOST_DATA, activeDomain, records } = this.$store
if (activeDomain) {
HOST_DATA[activeDomain] = records
}
// electron.saveHosts(HOST_DATA)
saveHosts(HOST_DATA)
layer.toast('保存成功', 'success')
}
render() {
return html`
<div class="layout-left noselect">
<wc-scroll>
<ul class="domain-list" @contextmenu.prevent=${this.showMenu}>
${this.domains.map(
it => html`
<li
class=${classMap({
item: true,
active: it === this.activeDomain
})}
data-name=${it}
@click=${this.toggleDomain}
>
<span>${it}</span>
<wc-icon name="right"></wc-icon>
</li>
`
)}
${this.domains.length < 1
? html`<li class="item blank">没有域名</li>`
: ''}
</ul>
</wc-scroll>
<section class="action">
<wc-button circle icon="plus" @click=${this.addDomain}> </wc-button>
</section>
</div>
<wc-sidebar
ref="domain"
@toggle-domain=${_ => (this.$refs.list.scrollTop = 0)}
@show-menu=${ev => this.showMenu(ev.event)}
></wc-sidebar>
<div class="layout-right noselect">
<main class="main noselect">
<header class="toolbar">
<wc-button size="m" icon="plus" type="primary" @click="addRecord"
<wc-button
size="m"
icon="plus"
type="primary"
@click=${this.addRecord}
>新增记录</wc-button
>
<wc-button size="m" icon="fly" type="info" @click="save"
<wc-button size="m" icon="fly" type="info" @click=${this.save}
>保存</wc-button
>
</header>
<main class="main">
<header class="thead item">
<span>主机记录</span>
<span>类型</span>
<span class="long">记录值</span>
<span>操作</span>
<span>备注</span>
</header>
<wc-scroll class="records" ref="records">
${this.records.map(
it => html`
<div class="item">
<wc-input
size="m"
autofocus
@change="updateCacheDict(it)"
:value=${it.record}
label="根域请填 @"
></wc-input>
<span>A</span>
<wc-input
size="m"
class="long"
:value=${it.value}
label="请填写IP"
></wc-input>
<wc-space gap="s">
<wc-link size="m" type="danger" @click="$remove"
>删除</wc-link
>
<wc-link size="m" type="info" @click="clone(it)"
>克隆</wc-link
>
<wc-switch
size="m"
:value=${it.enabled}
@change=${this.recordChanges(it)}
></wc-switch>
</wc-space>
<wc-input size="m" no-border :value=${it.remark}></wc-input>
</div>
`
)}
</wc-scroll>
</main>
</div>
<wc-records class="list" ref="list"></wc-records>
</main>
<wc-permission
class=${classMap({ visible: this.permissionShow })}

View File

@ -5,16 +5,14 @@
*/
import { html, css, Component } from 'wkit'
import { checkPermission } from '../utils/index.js'
const tips_header = `/************************************************************/
* hosts文件没有写权限 *
/************************************************************/
`
class Permission extends Component {
static props = {
foo: ''
}
static styles = css`
:host {
display: none;
@ -72,8 +70,13 @@ class Permission extends Component {
}
`
check() {
//
async check() {
let writable = await checkPermission()
if (writable) {
location.reload()
} else {
layer.toast('hosts文件没有写权限, 请按提示修改', 'error')
}
}
render() {

View File

@ -0,0 +1,158 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/08/08 18:19:17
*/
import { html, css, Component, classMap, nextTick } from 'wkit'
import { noop } from '../utils/index.js'
class Records extends Component {
static styles = css`
:host {
display: flex;
flex-direction: column;
padding: 8px;
background: #fff;
}
.thead {
flex-shrink: 0;
}
.records {
overflow: hidden;
flex: 1;
}
.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;
}
.thead {
line-height: 40px;
}
.item span {
flex: 1;
}
.item .long {
flex: 1.5;
}
.item wc-input {
flex: 1;
min-width: 0;
--wc-input-border-color: transparent;
}
.item:last-child {
border-bottom: none;
}
`
set scrollTop(val) {
this.$refs.records.scrollTop = val
}
// 同一个记录, 允许一条被激活
recordChanges(ev, item) {
let { tmp_records } = this.$store
item.enabled = ev.target.value
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
}
}
}
}
}
updateCacheDict(ev, item) {
let { records } = this.$store
let tmp_records = Object.create(null)
item.record = ev.target.value
for (let it of records) {
if (tmp_records[it.record]) {
tmp_records[it.record].push(it)
} else {
tmp_records[it.record] = [it]
}
}
this.$store.tmp_records = tmp_records
}
clone(item) {
let { tmp_records, records } = this.$store
var params = { ...item }
params.enabled = false
records.push(params)
tmp_records[params.record].push(records.at(-1))
nextTick(_ => (this.$refs.records.scrollTop = 1e6))
}
render() {
return html`
<header class="thead item">
<span>主机记录</span>
<span>类型</span>
<span class="long">记录值</span>
<span>操作</span>
<span>备注</span>
</header>
<wc-scroll class="records" ref="records">
${this.$store.records.map(
(it, i) => html`
<div class="item">
<wc-input
size="m"
autofocus
@change=${ev => this.updateCacheDict(ev, it)}
:value=${it.record}
label="根域请填 @"
></wc-input>
<span>A</span>
<wc-input
size="m"
class="long"
:value=${it.value}
@change=${ev => (it.value = ev.target.value)}
label="请填写IP"
></wc-input>
<wc-space gap="s">
<wc-link
size="m"
type="danger"
@click=${ev => this.$store.records.splice(i, 1)}
>删除</wc-link
>
<wc-link size="m" type="info" @click=${ev => this.clone(it)}
>克隆</wc-link
>
<wc-switch
size="m"
:value=${it.enabled}
@change=${ev => this.recordChanges(ev, it)}
></wc-switch>
</wc-space>
<wc-input size="m" no-border :value=${it.remark}></wc-input>
</div>
`
)}
</wc-scroll>
`
}
}
Records.reg('records')

View File

@ -0,0 +1,165 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/08/08 18:19:17
*/
import { html, css, Component, classMap, nextTick } from 'wkit'
import { noop } from '../utils/index.js'
class Sidebar extends Component {
static styles = css`
:host {
flex-shrink: 0;
display: flex;
flex-direction: column;
width: 180px;
height: 100vh;
background: var(--color-plain-2);
}
.noselect {
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
.domain-list {
overflow: hidden;
flex: 1;
width: 100%;
}
.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;
}
.item wc-icon {
--wc-icon-size: 12px;
margin-left: 8px;
color: var(--color-grey-2);
}
.item:hover,
.item.active {
background: #fff;
}
.item.active {
border-right: 2px solid var(--color-orange-1);
color: var(--color-orange-1);
}
.item.active wc-icon {
color: var(--color-orange-1);
}
.item.blank {
justify-content: center;
cursor: default;
}
.item.blank:hover {
background: none;
}
.action {
flex-shrink: 0;
display: flex;
align-items: center;
height: 50px;
padding: 0 10px;
}
`
addDomain() {
layer
.prompt('请输入根域名', function (val, done) {
if (
val === 'localhost' ||
val === 'local' ||
/^[\w.\-]+\.[a-z]+$/.test(val)
) {
done()
} else {
layer.toast('域名格式错误', 'error')
}
})
.then(val => {
this.$store.domains.push(val)
// HOST_DATA[val] = []
// if (!this.$store.activeDomain) {
// this.toggleDomain(null, val)
// }
// this.save()
// this.$emit('save')
})
.catch(noop)
}
toggleDomain(ev, name) {
let { HOST_DATA, records } = this.$store
name = name || ev.currentTarget.dataset.name
this.$store.activeDomain = name
this.$store.records = records = (HOST_DATA[name] || []).sort((a, b) =>
a.record.localeCompare(b.record)
)
let tmp_records = Object.create(null)
for (let it of records) {
if (tmp_records[it.record]) {
tmp_records[it.record].push(it)
} else {
tmp_records[it.record] = [it]
}
}
this.$store.tmp_records = tmp_records
document.title = `伪域名解析 ${name} `
localStorage.setItem('last_domain', name)
nextTick(() => {
this.$emit('toggle-domain')
})
}
mounted() {
this.toggleDomain(null, this.$store.activeDomain)
}
render() {
return html`
<wc-scroll class="domain-list noselect">
<ul
@contextmenu.prevent=${ev => this.$emit('show-menu', { event: ev })}
>
${this.$store.domains.map(
it => html`
<li
class=${classMap({
item: true,
active: it === this.$store.activeDomain
})}
data-name=${it}
@click=${this.toggleDomain}
>
<span>${it}</span>
<wc-icon name="right"></wc-icon>
</li>
`
)}
${this.$store.domains.length < 1
? html`<li class="item blank">没有域名</li>`
: ''}
</ul>
</wc-scroll>
<section class="action">
<wc-button circle icon="plus" @click=${this.addDomain}> </wc-button>
</section>
`
}
}
Sidebar.reg('sidebar')

View File

@ -20,10 +20,12 @@
"imports":{
"es.shim":"app:///lib/es.shim.js",
"wkit":"app:///lib/wkit.js",
"wkit":"http://127.0.0.1:9999/src/index.js",
"wkitd":"app:///lib/wkitd.js",
"fetch":"app:///lib/fetch.js",
"crypto":"app:///lib/crypto.js",
"ui/":"app:///lib/ui/"
"ui/":"app:///lib/ui/",
"local/":"http://127.0.0.1:8090/dist/"
}
}
</script>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,13 +1,13 @@
var G=Object.defineProperty;var Z=(i,e,t)=>e in i?G(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var d=(i,e,t)=>(Z(i,typeof e!="symbol"?e+"":e,t),t),q=(i,e,t)=>{if(!e.has(i))throw TypeError("Cannot "+t)};var E=(i,e,t)=>(q(i,e,"read from private field"),t?t.call(i):e.get(i)),m=(i,e,t)=>{if(e.has(i))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(i):e.set(i,t)},T=(i,e,t,o)=>(q(i,e,"write to private field"),o?o.call(i,t):e.set(i,t),t);var C=(i,e,t)=>(q(i,e,"access private method"),t);import"wkit";var c=Symbol("router"),h=Symbol("router-view"),y=Symbol("store"),x=new Set;var P=class extends WeakMap{broadcast(){for(let e of x)e.$requestUpdate()}assign(e){x.add(e)}deassign(e){x.add(e)}},F=new P;Object.defineProperty(window,"wkitd",{get(){return F},set(i){console.error("Can not set readonly property wkitd of window")},enumerable:!1});import{html as K,css as oe,Component as ie}from"wkit";var J=encodeURIComponent,W=decodeURIComponent;function w(){}function U(i,e,t){var o;if(Array.isArray(e))e.forEach(function(r,s){o=i?`${i}[${Array.isArray(r)?s:""}]`:s,typeof r=="object"?U(o,r,t):t(o,r)});else for(let r in e)o=i?`${i}[${r}]`:r,typeof e[r]=="object"?U(o,e[r],t):t(o,e[r])}function H(i=""){let e=new URLSearchParams(i),t=Object.create(null);for(let[o,r]of e.entries()){let s=W(o),n=W(r),a=0;if(/(\w+)\[(\w*?)\]/.test(s)){let u=RegExp.$1,l=RegExp.$2;s=u,!l||+l==+l?(n=[n],a|=2):(a|=1,n={[l]:n})}t[s]?a&2?t[s]=t[s].concat(n):a&1?Object.assign(t[s],n):(Array.isArray(t[n])||(t[s]=[t[s]]),t[s].push(n)):t[s]=n}return t}function k(i={}){if(i===null)return"";if(typeof i=="string"||typeof i=="number"||typeof i=="boolean")return i;let e=[];return typeof i=="object"&&U("",i,function(o,r){e.push(o+"="+J(r))}),e.join("&")}import{Component as te}from"wkit";import{bind as V}from"wkit";var Y=/^(#!|#)[\/]+?/,B=/(\/[^/]*)(:[A-Za-z0-9_]+)(\?)?/g,v="hash",L="history",O=class{type=v;#e=new Map;#s=new Set;#n=new Map;#t=!1;#r=Object.create(null);#o;constructor(e=v){this.type=e,V(window,"popstate",this.#i.bind(this))}get route(){return this.#r}get views(){return Array.from(this.#s)}#i(e){this.#t&&this.#p()}#h(e){if(e.path==="!")e.regexp=null;else{let t=[],o;if(e.path.includes("?")&&e.path.at(-1)!=="?")throw new SyntaxError(`The exp "?" can only be used in the last.
var J=Object.defineProperty;var V=(i,e,t)=>e in i?J(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var d=(i,e,t)=>(V(i,typeof e!="symbol"?e+"":e,t),t),q=(i,e,t)=>{if(!e.has(i))throw TypeError("Cannot "+t)};var b=(i,e,t)=>(q(i,e,"read from private field"),t?t.call(i):e.get(i)),m=(i,e,t)=>{if(e.has(i))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(i):e.set(i,t)},T=(i,e,t,o)=>(q(i,e,"write to private field"),o?o.call(i,t):e.set(i,t),t);var C=(i,e,t)=>(q(i,e,"access private method"),t);import"wkit";var c=Symbol("router"),h=Symbol("router-view"),y=Symbol("store"),x=new Set;var P=class extends WeakMap{broadcast(){for(let e of x)e.$requestUpdate()}assign(e){x.add(e)}deassign(e){x.add(e)}},Y=new P;Object.defineProperty(window,"wkitd",{get(){return Y},set(i){console.error("Can not set readonly property wkitd of window")},enumerable:!1});import{html as Z,css as ne,Component as F}from"wkit";var B=encodeURIComponent,W=decodeURIComponent;function w(){}function H(i,e,t){Object.defineProperty(i,e,{get(){return t},set(o){},enumerable:!1})}function U(i,e,t){var o;if(Array.isArray(e))e.forEach(function(r,s){o=i?`${i}[${Array.isArray(r)?s:""}]`:s,typeof r=="object"?U(o,r,t):t(o,r)});else for(let r in e)o=i?`${i}[${r}]`:r,typeof e[r]=="object"?U(o,e[r],t):t(o,e[r])}function M(i=""){let e=new URLSearchParams(i),t=Object.create(null);for(let[o,r]of e.entries()){let s=W(o),n=W(r),a=0;if(/(\w+)\[(\w*?)\]/.test(s)){let u=RegExp.$1,l=RegExp.$2;s=u,!l||+l==+l?(n=[n],a|=2):(a|=1,n={[l]:n})}t[s]?a&2?t[s]=t[s].concat(n):a&1?Object.assign(t[s],n):(Array.isArray(t[n])||(t[s]=[t[s]]),t[s].push(n)):t[s]=n}return t}function v(i={}){if(i===null)return"";if(typeof i=="string"||typeof i=="number"||typeof i=="boolean")return i;let e=[];return typeof i=="object"&&U("",i,function(o,r){e.push(o+"="+B(r))}),e.join("&")}import{Component as ie}from"wkit";import{bind as L}from"wkit";var Q=/^(#!|#)[\/]+?/,ee=/(\/[^/]*)(:[A-Za-z0-9_]+)(\?)?/g,k="hash",te="history",R=class{type=k;#e=new Map;#s=new Set;#n=new Map;#t=!1;#r=Object.create(null);#o;constructor(e=k){this.type=e,L(window,"popstate",this.#i.bind(this))}get route(){return this.#r}get views(){return Array.from(this.#s)}#i(e){this.#t&&this.#p()}#h(e){if(e.path==="!")e.regexp=null;else{let t=[],o;if(e.path.includes("?")&&e.path.at(-1)!=="?")throw new SyntaxError(`The exp "?" can only be used in the last.
${JSON.stringify(e)}
`);o=e.path.replace(B,function(r,s,n,a){return t.push(n.slice(1)),s==="/"&&(s="/?"),s+"([A-Za-z0-9_]+)"+a}),o="^"+o+"$",e.regexp=new RegExp(o),e.vars=t}return e}#a(e){if(e.path!=="!"&&e.path[0]!=="/"){console.error('route path must start with "/"');return}e.path=e.path.replace(/^[\/]+|[\/]+$|\s+/g,"/"),this.#e.set(e.path,this.#h(e)),this.#s.add(e.name)}#p(){let e=this.type===v,t=window.wkitd.get(h),o=location.hash,r=e?location.hash:location.href.replace(location.origin,"").replace(o,""),s;if(r.includes("?")&&([r,s]=r.split("?")),r=r.replace(Y,"/"),!(!t||r===this.#r.path)){for(let[n,a]of this.#e){let u=r.match(a.regexp);if(u){let l=Object.create(null);for(let b=1;b<u.length;b++)l[[a.vars[b-1]]]=u[b];let A={path:r,name:a.name,params:l,query:H(s)};return this.#o?this.#o(this.route,A,()=>{this.#l(A)}):this.#l(A)}}if(this.#e.get("!")){let n=this.#e.get("!");t.current=n.name,this.#r={path:r,name:n.name,params:{},query:{}}}}}#l(e){let t=window.wkitd.get(h);t.current=e.name,this.#r=e,this.#c()}#c(){for(let[e,t]of this.#n)t.call(e,this.route)}init(){this.#t=!0,this.#i()}rsync(e,t){this.#n.set(e,t),this.#t&&this.#c()}beforeEach(e=w){this.#o=e}addRoute(e){Array.isArray(e)?e.forEach(t=>{this.#a(t)}):this.#a(e),this.#t&&this.#i()}go(e=0){history.go(e)}back(){this.go(-1)}forward(){this.go(1)}push(e={path:"",query:{}},t=!1){let o="",r="";typeof e=="string"?o=e.trim():(r=k(e.query||""),o=e.path+(r?`?${r}`:"")),!(!o&&o===location.hash.slice(1))&&(this.type===v?t?location.replace(o.replace(/^\//,"#/")):location.hash=o:(t?window.history.replaceState({path:o},null,o+r):window.history.pushState({path:o},null,o+r),this.#p()))}replace(e={path:"",query:{}}){this.push(e,!0)}};function M(){return()=>new O}function Q(){return()=>new O(L)}import{Component as j,html as ee,css as D,raw as I}from"wkit";var $,_=class extends j{constructor(){super(...arguments);m(this,$,[])}created(){window.wkitd.set(h,this)}sync(t){T(this,$,t)}render(){let t={immediate:!0,custom:[{transform:"translateX(-32px)",opacity:0},{transform:"translateX(0)",opacity:1}]};if(this.keepAlive){let o=E(this,$).map(r=>[this.transition?`<${r} ref="${r}" :__keep_alive__="%s" #animation="%s" style="%s"></${r}>`:`<${r} ref="${r}" :__keep_alive__="%s" style=%s></${r}>`,[this.current===r,{...t,immediate:this.current===r},this.current===r?"":"display:none"]]);return I(o.map(r=>r[0]).join(""),o.map(r=>r[1]).flat())}else if(this.current)return this.transition?I(`<${this.current} #animation="%s"></${this.current}>`,[t]):I(`<${this.current}></${this.current}>`)}};$=new WeakMap,d(_,"props",{keepAlive:!1,transition:!1,current:{type:String,default:"",attribute:!1,observer(t,o){this.keepAlive&&t&&(o&&this.$refs[o]&&this.$refs[o].deactivated(),this.$refs[t]?.$requestUpdate(),this.$refs[t]?.$animate(),this.$refs[t]?.activated())}}}),d(_,"styles",D`
`);o=e.path.replace(ee,function(r,s,n,a){return t.push(n.slice(1)),s==="/"&&(s="/?"),s+"([A-Za-z0-9_]+)"+a}),o="^"+o+"$",e.regexp=new RegExp(o),e.vars=t}return e}#a(e){if(e.path!=="!"&&e.path[0]!=="/"){console.error('route path must start with "/"');return}e.path=e.path.replace(/^[\/]+|[\/]+$|\s+/g,"/"),this.#e.set(e.path,this.#h(e)),this.#s.add(e.name)}#p(){let e=this.type===k,t=window.wkitd.get(h),o=location.hash||"#/",r=e?o:location.href.replace(location.origin,"").replace(o,""),s;if(r.includes("?")&&([r,s]=r.split("?")),r=r.replace(Q,"/"),!(!t||r===this.#r.path)){for(let[n,a]of this.#e){let u=r.match(a.regexp);if(u){let l=Object.create(null);for(let E=1;E<u.length;E++)l[[a.vars[E-1]]]=u[E];let A={path:r,name:a.name,params:l,query:M(s)};return this.#o?this.#o(this.route,A,()=>{this.#l(A)}):this.#l(A)}}if(this.#e.get("!")){let n=this.#e.get("!");t.current=n.name,this.#r={path:r,name:n.name,params:{},query:{}}}}}#l(e){let t=window.wkitd.get(h);t.current=e.name,this.#r=e,this.#c()}#c(){for(let[e,t]of this.#n)t.call(e,this.route)}init(){this.#t=!0,this.#i()}rsync(e,t){this.#n.set(e,t),this.#t&&this.#c()}beforeEach(e=w){this.#o=e}addRoute(e){Array.isArray(e)?e.forEach(t=>{this.#a(t)}):this.#a(e),this.#t&&this.#i()}go(e=0){history.go(e)}back(){this.go(-1)}forward(){this.go(1)}push(e={path:"",query:{}},t=!1){let o="",r="";typeof e=="string"?o=e.trim():(r=v(e.query||""),o=e.path+(r?`?${r}`:"")),!(!o&&o===location.hash.slice(1))&&(this.type===k?t?location.replace(o.replace(/^\//,"#/")):location.hash=o:(t?window.history.replaceState({path:o},null,o+r):window.history.pushState({path:o},null,o+r),this.#p()))}replace(e={path:"",query:{}}){this.push(e,!0)}};function j(){return()=>new R}function re(){return()=>new R(te)}import{Component as D,html as oe,css as N,raw as I}from"wkit";var $,_=class extends D{constructor(){super(...arguments);m(this,$,[])}created(){window.wkitd.set(h,this)}sync(t){T(this,$,t)}render(){let t={immediate:!0,custom:[{transform:"translateX(-32px)",opacity:0},{transform:"translateX(0)",opacity:1}]};if(this.keepAlive){let o=b(this,$).map(r=>[this.transition?`<${r} ref="${r}" :__keep_alive__="%s" #animation="%s" style="%s"></${r}>`:`<${r} ref="${r}" :__keep_alive__="%s" style=%s></${r}>`,[this.current===r,{...t,immediate:this.current===r},this.current===r?"":"display:none"]]);return I(o.map(r=>r[0]).join(""),o.map(r=>r[1]).flat())}else if(this.current)return this.transition?I(`<${this.current} #animation="%s"></${this.current}>`,[t]):I(`<${this.current}></${this.current}>`)}};$=new WeakMap,d(_,"props",{keepAlive:!1,transition:!1,current:{type:String,default:"",attribute:!1,observer(t,o){this.keepAlive&&t&&(o&&this.$refs[o]&&this.$refs[o].deactivated(),this.$refs[t]?.$requestUpdate(),this.$refs[t]?.$animate(),this.$refs[t]?.activated())}}}),d(_,"styles",N`
:host {
display: block;
}
`);var f,R,N,S,X,g=class extends j{constructor(){super(...arguments);m(this,R);m(this,S);m(this,f,"")}mounted(){this.$router.rsync(this,t=>{this.classList.toggle("active",t.path===this.to.path)})}render(){return T(this,f,C(this,S,X).call(this)),ee`<a title=${E(this,f)} @click=${C(this,R,N)}>
`);var f,O,X,S,z,g=class extends D{constructor(){super(...arguments);m(this,O);m(this,S);m(this,f,"")}mounted(){this.$router.rsync(this,t=>{this.classList.toggle("active",t.path===this.to.path)})}render(){return T(this,f,C(this,S,z).call(this)),oe`<a title=${b(this,f)} @click=${C(this,O,X)}>
<slot></slot
></a>`}};f=new WeakMap,R=new WeakSet,N=function(){let t=this.$router.type,{path:o}=this.to;this.disabled||(t==="hash"?location.hash=E(this,f):this.$router.push(this.to))},S=new WeakSet,X=function(){let t=this.$router.type,{path:o="",query:r={}}=this.to,s=typeof r=="string"?r.replaceAll("?",""):k(r);return o=o.replace(/^\//,""),s&&(o+="?"+s),"/"+o},d(g,"props",{to:Object,disabled:!1}),d(g,"styles",D`
></a>`}};f=new WeakMap,O=new WeakSet,X=function(){let t=this.$router.type,{path:o}=this.to;this.disabled||(t==="hash"?location.hash=b(this,f):this.$router.push(this.to))},S=new WeakSet,z=function(){let t=this.$router.type,{path:o="",query:r={}}=this.to,s=typeof r=="string"?r.replaceAll("?",""):v(r);return o=o.replace(/^\//,""),s&&(o+="?"+s),"/"+o},d(g,"props",{to:Object,disabled:!1}),d(g,"styles",N`
:host {
display: inline-flex;
align-items: center;
@ -28,7 +28,7 @@ var G=Object.defineProperty;var Z=(i,e,t)=>e in i?G(i,e,{enumerable:!0,configura
opacity: 0.6;
cursor: not-allowed;
}
`);customElements.get("router-view")||customElements.define("router-view",_);customElements.get("router-link")||customElements.define("router-link",g);function ke({history:i=M(),routes:e=[]}={}){let t=i();window.wkitd.set(c,t),t.addRoute(e);function o(){Object.defineProperty(te.prototype,"$router",{get(){return window.wkitd.get(c)},set(r){console.error("Can not set readonly property $router of Component")},enumerable:!1})}return o.beforeEach=t.beforeEach.bind(t),o}import{Component as z}from"wkit";function re(i={}){let e=!1;return function(){Object.defineProperty(z.prototype,"$store",{get(){return window.wkitd.get(y)},set(t){if(e)return console.error("Can not set readonly property $store of Component");window.wkitd.set(y,new Proxy(t,{set(o,r,s){return o[r]=s,window.wkitd.broadcast(),!0}})),e=!0},enumerable:!1}),z.prototype.$store=i}}var p=class extends ie{};function Pe({data:i={},styles:e=[],methods:t={},mounted:o=w,render:r}={}){return new function(){p.props=i,p.styles=e,Object.assign(p.prototype,t,{mounted:o}),this.use=function(s=w,...n){return s.apply(p.prototype,n),this},this.mount=function(){let s=window.wkitd.get(c);r?p.prototype.render=r:s?p.prototype.render=function(){return K`<router-view></router-view>`}:(p.styles=oe`
`);customElements.get("router-view")||customElements.define("router-view",_);customElements.get("router-link")||customElements.define("router-link",g);function Re({history:i=j(),routes:e=[]}={}){let t=i();window.wkitd.set(c,t),t.addRoute(e);function o(){Object.defineProperty(ie.prototype,"$router",{get(){return window.wkitd.get(c)},set(r){console.error("Can not set readonly property $router of Component")},enumerable:!1})}return o.beforeEach=t.beforeEach.bind(t),o}import{Component as K}from"wkit";function G(i){return i===null?i:new Proxy(i,{get(e,t,o){let r=Reflect.get(e,t,o);return typeof r=="object"?G(r):r},set(e,t,o,r){return Reflect.set(e,t,o,r),window.wkitd.broadcast(),!0}})}function se(i={}){let e=!1;return function(){Object.defineProperty(K.prototype,"$store",{get(){return window.wkitd.get(y)},set(t){if(e)return console.error("Can not set readonly property $store of Component");window.wkitd.set(y,G(t)),e=!0},enumerable:!1}),K.prototype.$store=i}}var p=class extends F{};function Ie({data:i={},styles:e=[],methods:t={},mounted:o=w,render:r}={}){return new function(){p.props=i,p.styles=e,Object.assign(p.prototype,t,{mounted:o,created(){H(F.prototype,"$app",this)}}),this.use=function(s=w,...n){return s.apply(p.prototype,n),this},this.mount=function(){let s=window.wkitd.get(c);r?p.prototype.render=r:s?p.prototype.render=function(){return Z`<router-view></router-view>`}:(p.styles=ne`
:host {
font-family: monospace;
color: #647889;
@ -37,7 +37,7 @@ var G=Object.defineProperty;var Z=(i,e,t)=>e in i?G(i,e,{enumerable:!0,configura
margin: 16px 0;
background: #f7f8fb;
}
`,p.prototype.render=function(){return K`
`,p.prototype.render=function(){return Z`
<h1>It works!!!</h1>
<cite>
If you don't use router, you may define the
@ -51,4 +51,4 @@ var G=Object.defineProperty;var Z=(i,e,t)=>e in i?G(i,e,{enumerable:!0,configura
<pre><code> })</code></pre>
<pre><code> .mount()</code></pre>
</div>
`}),s&&(p.prototype.mounted=function(...n){let a=window.wkitd.get(h);if(a)a.sync(s.views),s.init(),o.call(this,...n);else throw new Error('<router-view /> not found, "Router" works Unexpected.')}),p.reg("app")}}}function Ue(){return window.wkitd.get(y)}function Ie(){return window.wkitd.get(c)}function We(){return window.wkitd.get(c)?.route}export{Pe as createApp,ke as createRouter,re as createStore,M as createWebHashHistory,Q as createWebHistory,We as getCurrentPage,Ie as getRouter,Ue as getStore};
`}),s&&(p.prototype.mounted=function(...n){let a=window.wkitd.get(h);if(a)a.sync(s.views),s.init(),o.call(this,...n);else throw new Error('<router-view /> not found, "Router" works Unexpected.')}),p.reg("app")}}}function We(){return window.wkitd.get(y)}function He(){return window.wkitd.get(c)}function Me(){return window.wkitd.get(c)?.route}export{Ie as createApp,Re as createRouter,se as createStore,j as createWebHashHistory,re as createWebHistory,Me as getCurrentPage,He as getRouter,We as getStore};

View File

@ -0,0 +1,15 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/09/04 11:11:51
*/
import { createStore } from 'wkitd'
export default createStore({
HOST_DATA: {},
activeDomain: localStorage.getItem('last_domain') || '', //当前选中的域名
domains: [],
records: [],
tmp_records: []
})

View File

@ -1,11 +1,21 @@
const CONFIG_DIR = '/home/yutent/.config/hosts-switch'
const HOST_FILE = `${CONFIG_DIR}/host.cache`
const LOCK_FILE = `${CONFIG_DIR}/lock`
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2023/09/04 19:18:28
*/
await native.init()
const APP_CONFIG_DIR = `${native.env.CONFIG_DIR}/hosts-switch`
const HOST_FILE = `${APP_CONFIG_DIR}/host.cache`
const LOCK_FILE = `${APP_CONFIG_DIR}/lock`
let timer
export function noop() {}
export function checkPermission() {
return writable('/etc/hosts')
return native.fs.access('/etc/hosts', 'w')
}
export async function getHistory() {
@ -79,7 +89,8 @@ export function saveHosts(dict) {
}
txt += '\n'
}
native.fs.write(HOST_FILE, JSON.stringify(dict))
native.fs.write('/etc/hosts', txt)
}, 1000)
console.log(txt)
// native.fs.write(HOST_FILE, JSON.stringify(dict))
// native.fs.write('/etc/hosts', txt)
}, 500)
}