一大波更新
parent
74f4cd22d4
commit
419a13e4e6
|
@ -6,6 +6,6 @@
|
||||||
.Spotlight-V100
|
.Spotlight-V100
|
||||||
.Trashes
|
.Trashes
|
||||||
|
|
||||||
|
we
|
||||||
__pycache__
|
__pycache__
|
||||||
*.txt
|
*.txt
|
BIN
icons/app.icns
BIN
icons/app.icns
Binary file not shown.
|
@ -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 |
218
src/css/app.css
218
src/css/app.css
|
@ -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;
|
|
||||||
}
|
|
240
src/css/app.scss
240
src/css/app.scss
|
@ -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 |
108
src/index.html
108
src/index.html
|
@ -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>
|
|
234
src/js/app.js
234
src/js/app.js
|
@ -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
|
@ -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;
|
|
||||||
}
|
|
|
@ -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};
|
|
|
@ -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轴绝对坐标;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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};
|
|
||||||
|
|
|
@ -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};
|
|
||||||
|
|
|
@ -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};
|
|
||||||
|
|
|
@ -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
|
@ -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
|
@ -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};
|
|
||||||
|
|
|
@ -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
|
@ -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};
|
|
||||||
|
|
|
@ -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};
|
|
||||||
|
|
|
@ -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
|
@ -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};
|
|
101
src/main.js
101
src/main.js
|
@ -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)
|
|
||||||
}
|
|
||||||
})
|
|
|
@ -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)
|
|
||||||
}
|
|
||||||
})
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,8 @@ gi.require_version('Gtk', '3.0')
|
||||||
|
|
||||||
from gi.repository import Gtk, Gdk, GLib, Gio, GObject, GdkPixbuf
|
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
|
from window import Window
|
||||||
|
|
||||||
APP_ID = 'fun.wkit.hosts-switch'
|
APP_ID = 'fun.wkit.hosts-switch'
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'es.shim'
|
||||||
import { html, css, Component } from 'wkit'
|
import { html, css, Component } from 'wkit'
|
||||||
import { createApp, createRouter } from 'wkitd'
|
import { createApp, createRouter } from 'wkitd'
|
||||||
|
|
||||||
|
import store from './store.js'
|
||||||
import './components/home.js'
|
import './components/home.js'
|
||||||
|
|
||||||
createApp({
|
createApp({
|
||||||
|
@ -23,13 +24,6 @@ createApp({
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
.app {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
router-view {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
`
|
`
|
||||||
],
|
],
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -38,6 +32,8 @@ createApp({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
return html` <wc-home></wc-home> `
|
return html` <wc-home @contextmenu.prevent2=${function () {}}></wc-home> `
|
||||||
}
|
}
|
||||||
}).mount()
|
})
|
||||||
|
.use(store)
|
||||||
|
.mount()
|
||||||
|
|
|
@ -3,34 +3,29 @@
|
||||||
* @author yutent<yutent.io@gmail.com>
|
* @author yutent<yutent.io@gmail.com>
|
||||||
* @date 2023/08/08 18:19:17
|
* @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/icon/index.js'
|
||||||
import 'ui/scroll/index.js'
|
import 'ui/scroll/index.js'
|
||||||
import 'ui/layer/index.js'
|
import 'ui/layer/index.js'
|
||||||
|
// import 'local/layer/index.js'
|
||||||
import 'ui/space/index.js'
|
import 'ui/space/index.js'
|
||||||
import 'ui/form/input.js'
|
import 'ui/form/input.js'
|
||||||
import 'ui/form/switch.js'
|
import 'ui/form/switch.js'
|
||||||
import 'ui/form/button.js'
|
import 'ui/form/button.js'
|
||||||
import 'ui/form/link.js'
|
import 'ui/form/link.js'
|
||||||
|
|
||||||
|
import './sidebar.js'
|
||||||
import './permission.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()
|
const HOST_DATA = await getHistory()
|
||||||
|
|
||||||
let tmp_records = Object.create(null)
|
|
||||||
|
|
||||||
function noop() {}
|
|
||||||
|
|
||||||
class Home extends Component {
|
class Home extends Component {
|
||||||
static props = {
|
static props = {
|
||||||
filter: '',
|
|
||||||
activeDomain: localStorage.getItem('last_domain') || '', //当前选中的域名
|
|
||||||
editDomain: '', // 当前临时要编辑的域名, 即右键菜单选择到的
|
editDomain: '', // 当前临时要编辑的域名, 即右键菜单选择到的
|
||||||
domains: Object.keys(HOST_DATA),
|
|
||||||
records: [],
|
|
||||||
permissionShow: false
|
permissionShow: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,74 +54,14 @@ class Home extends Component {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
|
||||||
css`
|
css`
|
||||||
.layout-left {
|
.main {
|
||||||
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 {
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.layout-right .toolbar {
|
.main .toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -135,54 +70,9 @@ class Home extends Component {
|
||||||
border-bottom: 1px solid var(--color-plain-3);
|
border-bottom: 1px solid var(--color-plain-3);
|
||||||
background: var(--color-plain-1);
|
background: var(--color-plain-1);
|
||||||
}
|
}
|
||||||
`,
|
.main .list {
|
||||||
css`
|
|
||||||
.layout-right .main {
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex: 1;
|
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,60 +98,34 @@ class Home extends Component {
|
||||||
`
|
`
|
||||||
]
|
]
|
||||||
|
|
||||||
mounted() {
|
async mounted() {
|
||||||
window.foo = this
|
window.foo = this
|
||||||
// let hosts = getHistory()
|
|
||||||
// console.log(hosts)
|
|
||||||
// this.domains = Object.keys(hosts)
|
|
||||||
this.toggleDomain(null, this.activeDomain)
|
|
||||||
}
|
|
||||||
|
|
||||||
addDomain() {
|
let writable = await checkPermission()
|
||||||
layer
|
|
||||||
.prompt('请输入根域名', function (val, done) {
|
if (writable) {
|
||||||
if (
|
this.$store.HOST_DATA = HOST_DATA
|
||||||
val === 'localhost' ||
|
this.$store.domains = Object.keys(HOST_DATA)
|
||||||
val === 'local' ||
|
this.$refs.domain.mounted()
|
||||||
/^[\w.\-]+\.[a-z]+$/.test(val)
|
outsideClick(this.$refs.context, _ => this.$refs.context.close())
|
||||||
) {
|
|
||||||
done()
|
|
||||||
} else {
|
} else {
|
||||||
layer.toast('域名格式错误', 'error')
|
this.permissionShow = true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addRecord() {
|
||||||
|
if (this.$store.activeDomain) {
|
||||||
|
this.$store.records.push({
|
||||||
|
record: '',
|
||||||
|
value: '',
|
||||||
|
enabled: true,
|
||||||
|
remark: ''
|
||||||
})
|
})
|
||||||
.then(val => {
|
nextTick(_ => (this.$refs.list.scrollTop = 1e6))
|
||||||
this.domains.push(val)
|
|
||||||
HOST_DATA[val] = []
|
|
||||||
if (!this.activeDomain) {
|
|
||||||
this.toggleDomain(null, val)
|
|
||||||
}
|
|
||||||
this.save()
|
|
||||||
})
|
|
||||||
.catch(noop)
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleDomain(ev, name) {
|
|
||||||
name = name || ev.currentTarget.dataset.name
|
|
||||||
this.activeDomain = name
|
|
||||||
|
|
||||||
this.records = (HOST_DATA[name] || []).sort((a, b) =>
|
|
||||||
a.record.localeCompare(b.record)
|
|
||||||
)
|
|
||||||
|
|
||||||
tmp_records = Object.create(null)
|
|
||||||
for (let it of this.records) {
|
|
||||||
if (tmp_records[it.record]) {
|
|
||||||
tmp_records[it.record].push(it)
|
|
||||||
} else {
|
} else {
|
||||||
tmp_records[it.record] = [it]
|
layer.toast('请先选择域名', 'warn')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
document.title = `伪域名解析 ${name} `
|
|
||||||
localStorage.setItem('last_domain', name)
|
|
||||||
nextTick(() => {
|
|
||||||
this.$refs.records.scrollTop = 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
showMenu(ev) {
|
showMenu(ev) {
|
||||||
this.$refs.context.close()
|
this.$refs.context.close()
|
||||||
|
@ -276,7 +140,7 @@ class Home extends Component {
|
||||||
elem = elem.parentNode
|
elem = elem.parentNode
|
||||||
}
|
}
|
||||||
this.editDomain = elem.dataset.name
|
this.editDomain = elem.dataset.name
|
||||||
nextTick(_ => {
|
setTimeout(_ => {
|
||||||
this.$refs.context.moveTo({ left: pageX + 'px', top: pageY + 'px' })
|
this.$refs.context.moveTo({ left: pageX + 'px', top: pageY + 'px' })
|
||||||
this.$refs.context.show()
|
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() {
|
save() {
|
||||||
if (this.activeDomain) {
|
let { HOST_DATA, activeDomain, records } = this.$store
|
||||||
HOST_DATA[this.activeDomain] = this.records
|
if (activeDomain) {
|
||||||
|
HOST_DATA[activeDomain] = records
|
||||||
}
|
}
|
||||||
// electron.saveHosts(HOST_DATA)
|
saveHosts(HOST_DATA)
|
||||||
layer.toast('保存成功', 'success')
|
layer.toast('保存成功', 'success')
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="layout-left noselect">
|
<wc-sidebar
|
||||||
<wc-scroll>
|
ref="domain"
|
||||||
<ul class="domain-list" @contextmenu.prevent=${this.showMenu}>
|
@toggle-domain=${_ => (this.$refs.list.scrollTop = 0)}
|
||||||
${this.domains.map(
|
@show-menu=${ev => this.showMenu(ev.event)}
|
||||||
it => html`
|
></wc-sidebar>
|
||||||
<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>
|
|
||||||
|
|
||||||
<div class="layout-right noselect">
|
<main class="main noselect">
|
||||||
<header class="toolbar">
|
<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
|
||||||
>
|
>
|
||||||
<wc-button size="m" icon="fly" type="info" @click="save"
|
<wc-button size="m" icon="fly" type="info" @click=${this.save}
|
||||||
>保存</wc-button
|
>保存</wc-button
|
||||||
>
|
>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main class="main">
|
<wc-records class="list" ref="list"></wc-records>
|
||||||
<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>
|
</main>
|
||||||
</div>
|
|
||||||
|
|
||||||
<wc-permission
|
<wc-permission
|
||||||
class=${classMap({ visible: this.permissionShow })}
|
class=${classMap({ visible: this.permissionShow })}
|
||||||
|
|
|
@ -5,16 +5,14 @@
|
||||||
*/
|
*/
|
||||||
import { html, css, Component } from 'wkit'
|
import { html, css, Component } from 'wkit'
|
||||||
|
|
||||||
|
import { checkPermission } from '../utils/index.js'
|
||||||
|
|
||||||
const tips_header = `/************************************************************/
|
const tips_header = `/************************************************************/
|
||||||
* hosts文件没有写权限 *
|
* hosts文件没有写权限 *
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
`
|
`
|
||||||
|
|
||||||
class Permission extends Component {
|
class Permission extends Component {
|
||||||
static props = {
|
|
||||||
foo: ''
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = css`
|
static styles = css`
|
||||||
:host {
|
:host {
|
||||||
display: none;
|
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() {
|
render() {
|
||||||
|
|
|
@ -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')
|
|
@ -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')
|
|
@ -20,10 +20,12 @@
|
||||||
"imports":{
|
"imports":{
|
||||||
"es.shim":"app:///lib/es.shim.js",
|
"es.shim":"app:///lib/es.shim.js",
|
||||||
"wkit":"app:///lib/wkit.js",
|
"wkit":"app:///lib/wkit.js",
|
||||||
|
"wkit":"http://127.0.0.1:9999/src/index.js",
|
||||||
"wkitd":"app:///lib/wkitd.js",
|
"wkitd":"app:///lib/wkitd.js",
|
||||||
"fetch":"app:///lib/fetch.js",
|
"fetch":"app:///lib/fetch.js",
|
||||||
"crypto":"app:///lib/crypto.js",
|
"crypto":"app:///lib/crypto.js",
|
||||||
"ui/":"app:///lib/ui/"
|
"ui/":"app:///lib/ui/",
|
||||||
|
"local/":"http://127.0.0.1:8090/dist/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -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)}
|
${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 {
|
:host {
|
||||||
display: block;
|
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
|
<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 {
|
:host {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
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;
|
opacity: 0.6;
|
||||||
cursor: not-allowed;
|
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 {
|
:host {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
color: #647889;
|
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;
|
margin: 16px 0;
|
||||||
background: #f7f8fb;
|
background: #f7f8fb;
|
||||||
}
|
}
|
||||||
`,p.prototype.render=function(){return K`
|
`,p.prototype.render=function(){return Z`
|
||||||
<h1>It works!!!</h1>
|
<h1>It works!!!</h1>
|
||||||
<cite>
|
<cite>
|
||||||
If you don't use router, you may define the
|
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> })</code></pre>
|
||||||
<pre><code> .mount()</code></pre>
|
<pre><code> .mount()</code></pre>
|
||||||
</div>
|
</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};
|
||||||
|
|
|
@ -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: []
|
||||||
|
})
|
|
@ -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
|
let timer
|
||||||
|
|
||||||
|
export function noop() {}
|
||||||
|
|
||||||
export function checkPermission() {
|
export function checkPermission() {
|
||||||
return writable('/etc/hosts')
|
return native.fs.access('/etc/hosts', 'w')
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getHistory() {
|
export async function getHistory() {
|
||||||
|
@ -79,7 +89,8 @@ export function saveHosts(dict) {
|
||||||
}
|
}
|
||||||
txt += '\n'
|
txt += '\n'
|
||||||
}
|
}
|
||||||
native.fs.write(HOST_FILE, JSON.stringify(dict))
|
console.log(txt)
|
||||||
native.fs.write('/etc/hosts', txt)
|
// native.fs.write(HOST_FILE, JSON.stringify(dict))
|
||||||
}, 1000)
|
// native.fs.write('/etc/hosts', txt)
|
||||||
|
}, 500)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue