1.1.0
parent
c8e3f1ce47
commit
bf543518f7
11
README.md
11
README.md
|
@ -1,2 +1,11 @@
|
||||||
# 伪域名解析工具
|
# 伪域名解析工具
|
||||||
> macos & linux专用。windows自己找别的。
|
> macos & linux专用。windows自己找别的。
|
||||||
|
|
||||||
|
|
||||||
|
## Update Logs
|
||||||
|
|
||||||
|
|
||||||
|
# v1.1.0 - 2019-12-11
|
||||||
|
- 支持域名删除、编辑
|
||||||
|
- 支持克隆记录
|
||||||
|
- 优化记录编辑、UI
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "dns-host",
|
"name": "dns-host",
|
||||||
"version": "1.0.2",
|
"version": "1.1.0",
|
||||||
"description": "伪域名解析",
|
"description": "伪域名解析",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
html{font-size:1vw;width:100%;height:100%}body{position:fixed;left:0;top:0;display:flex;width:100%;height:100%;line-height:1.5;font-size:1.4rem;color:#62778d}.layout-left{display:flex;flex-direction:column;width:18rem;height:64rem;background:#526273}.layout-left 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:4rem;padding:0 2rem 0 1rem;color:#f3f5fb;cursor:pointer;transition:background .1s ease-in-out}.layout-left .domain-list .item wc-icon{--size:1.2rem;margin:auto -1.5rem auto .5rem;color:#7e909a}.layout-left .domain-list .item:hover,.layout-left .domain-list .item.active{background:#62778d}.layout-left .domain-list .item.active{border-left:0.3rem solid #ffb618}.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:5rem;padding:0 1rem}.layout-right{flex:1;display:flex;flex-direction:column;background:#f7f8fb}.layout-right .toolbar{display:flex;align-items:center;justify-content:space-between;height:4rem;padding:0 1.5rem;background:#e8ebf4;box-shadow:0 0.2rem 0.5rem rgba(0,0,0,0.1)}.layout-right .toolbar wc-input{width:20rem}.layout-right .main{overflow:hidden;flex:1;display:flex;flex-direction:column;margin:2rem 1rem;padding:0 .5rem;background:#fff}.layout-right .thead{display:flex;align-items:center;justify-content:center;height:4rem;margin-bottom:.8rem;border-bottom:0.1rem solid #e8ebf4;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:4rem}.layout-right .record-list .item{display:flex;justify-content:center;align-items:center;height:4rem;padding:0 1rem;border-bottom:0.1rem solid #e8ebf4;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:hover{background:#f3f5fb}.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:5rem;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:1.6rem;color:#eb3b48}.permission-error fieldset{width:60rem;padding:0 3rem 3rem;border:0.1rem solid #ffb618;border-radius:.8rem}.permission-error fieldset legend{padding:0 1rem;font-size:1.6rem}.permission-error fieldset dt{margin-top:2rem;font-weight:bold}.permission-error fieldset code{display:block;padding:.8rem 1rem;margin-top:.8rem;border-left:0.3rem solid #dae1e9;background:rgba(255,255,255,0.3);font-family:'Courier New', Courier, monospace}.permission-error.show{display:flex}
|
html{font-size:1vw;width:100%;height:100%}body{position:fixed;left:0;top:0;display:flex;width:100%;height:100%;line-height:1.5;font-size:1.4rem;color:#62778d}.layout-left{display:flex;flex-direction:column;width:18rem;height:64rem;background:#526273}.layout-left 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:4rem;padding:0 2rem 0 1rem;color:#f3f5fb;cursor:pointer;transition:background .1s ease-in-out}.layout-left .domain-list .item wc-icon{--size:1.2rem;margin:auto -1.5rem auto .5rem;color:#7e909a}.layout-left .domain-list .item:hover,.layout-left .domain-list .item.active{background:#62778d}.layout-left .domain-list .item.active{border-left:0.3rem solid #ffb618;color:#ffb618;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:5rem;padding:0 1rem}.layout-right{flex:1;display:flex;flex-direction:column;background:#f7f8fb}.layout-right .toolbar{display:flex;align-items:center;justify-content:space-between;height:4rem;padding:0 1.5rem;background:#e8ebf4;box-shadow:0 0.2rem 0.5rem rgba(0,0,0,0.1)}.layout-right .toolbar wc-input{width:20rem}.layout-right .main{overflow:hidden;flex:1;display:flex;flex-direction:column;margin:2rem 1rem;padding:0 .5rem;background:#fff}.layout-right .thead{display:flex;align-items:center;justify-content:center;height:4rem;margin-bottom:.8rem;border-bottom:0.1rem solid #e8ebf4;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:4rem}.layout-right .record-list .item{display:flex;justify-content:center;align-items:center;height:4rem;padding:0 1rem;border-bottom:0.1rem solid #e8ebf4;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:.5rem}.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:5rem;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:1.6rem;color:#eb3b48}.permission-error fieldset{width:60rem;padding:0 3rem 3rem;border:0.1rem solid #ffb618;border-radius:.8rem}.permission-error fieldset legend{padding:0 1rem;font-size:1.6rem}.permission-error fieldset dt{margin-top:2rem;font-weight:bold}.permission-error fieldset code{display:block;padding:.8rem 1rem;margin-top:.8rem;border-left:0.3rem solid #dae1e9;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:10rem;padding:.5rem 0;background:#fff}.context-menu .item{height:3rem;line-height:3rem;padding:0 1.5rem;cursor:pointer}.context-menu .item:hover{background:#f2f5fc}
|
||||||
|
|
|
@ -38,7 +38,7 @@ body {
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&.active {background:nth($cd, 1);}
|
&.active {background:nth($cd, 1);}
|
||||||
&.active {border-left:.3rem solid nth($co, 1);}
|
&.active {border-left:.3rem solid nth($co, 1);color:nth($co, 1);font-weight:bold;}
|
||||||
&.blank {
|
&.blank {
|
||||||
justify-content:center;cursor:default;
|
justify-content:center;cursor:default;
|
||||||
&:hover {background:none;}
|
&:hover {background:none;}
|
||||||
|
@ -93,8 +93,8 @@ body {
|
||||||
wc-input,span,section {flex:1;}
|
wc-input,span,section {flex:1;}
|
||||||
.long {flex:1.5;}
|
.long {flex:1.5;}
|
||||||
section {display:flex;align-items:center;justify-content:center;}
|
section {display:flex;align-items:center;justify-content:center;}
|
||||||
|
wc-button {margin-left:.5rem;}
|
||||||
|
|
||||||
&:hover {background:nth($cp, 1);}
|
|
||||||
&:last-child {border-bottom:none;}
|
&:last-child {border-bottom:none;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,3 +132,17 @@ body {
|
||||||
&.show {display:flex;}
|
&.show {display:flex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.context-menu {
|
||||||
|
display:flex;
|
||||||
|
flex-direction:column;
|
||||||
|
width:10rem;
|
||||||
|
padding:.5rem 0;
|
||||||
|
background:#fff;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
height:3rem;line-height:3rem;padding:0 1.5rem;cursor:pointer;
|
||||||
|
|
||||||
|
&:hover {background:#f2f5fc;}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,11 +13,12 @@
|
||||||
|
|
||||||
<div class="layout-left">
|
<div class="layout-left">
|
||||||
<wc-scroll>
|
<wc-scroll>
|
||||||
<ul class="domain-list">
|
<ul class="domain-list" @contextmenu="showMenu">
|
||||||
<li
|
<li
|
||||||
class="item"
|
class="item"
|
||||||
:class="{active: it === curr}"
|
:class="{active: it === activeDomain}"
|
||||||
:for="it in domains"
|
:for="it in domains"
|
||||||
|
:data-name="it"
|
||||||
@click="toggleDomain(it)">
|
@click="toggleDomain(it)">
|
||||||
<span :text="it"></span>
|
<span :text="it"></span>
|
||||||
<wc-icon is="right"></wc-icon>
|
<wc-icon is="right"></wc-icon>
|
||||||
|
@ -44,22 +45,23 @@
|
||||||
<main class="main">
|
<main class="main">
|
||||||
<header class="thead">
|
<header class="thead">
|
||||||
<span class="long">主机记录</span>
|
<span class="long">主机记录</span>
|
||||||
<span>记录类型</span>
|
<span>类型</span>
|
||||||
<span class="long">记录值</span>
|
<span class="long">记录值</span>
|
||||||
<span>操作</span>
|
<span class="long">操作</span>
|
||||||
<span>备注</span>
|
<span>备注</span>
|
||||||
</header>
|
</header>
|
||||||
<wc-scroll ref="records">
|
<wc-scroll ref="records">
|
||||||
<ul class="record-list">
|
<ul class="record-list">
|
||||||
<li class="item" :for="it in records">
|
<li class="item" :for="it in records">
|
||||||
<wc-input autofocus class="long" :duplex="it.record" label="根域请填 @"></wc-input>
|
<wc-input auto-border autofocus class="long" @change="updateCacheDict(it)" :duplex="it.record" label="根域请填 @"></wc-input>
|
||||||
<span>A</span>
|
<span>A</span>
|
||||||
<wc-input class="long" :duplex="it.value" label="请填写IP"></wc-input>
|
<wc-input auto-border class="long" :duplex="it.value" label="请填写IP"></wc-input>
|
||||||
<section>
|
<section class="long">
|
||||||
<wc-switch :duplex="it.enabled" @change="recordChanges(it)"></wc-switch>
|
<wc-switch :duplex="it.enabled" @change="recordChanges(it)"></wc-switch>
|
||||||
<wc-button size="mini" color="red" @active="$remove">删除</wc-button>
|
<wc-button size="mini" color="red" @active="$remove">删除</wc-button>
|
||||||
|
<wc-button size="mini" color="blue" @active="clone(it)">克隆</wc-button>
|
||||||
</section>
|
</section>
|
||||||
<wc-input :duplex="it.remark"></wc-input>
|
<wc-input auto-border :duplex="it.remark"></wc-input>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</wc-scroll>
|
</wc-scroll>
|
||||||
|
@ -93,5 +95,12 @@
|
||||||
</dl>
|
</dl>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</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>
|
</body>
|
||||||
</html>
|
</html>
|
111
src/js/app.js
111
src/js/app.js
|
@ -9,6 +9,7 @@ import '/lib/form/button.js'
|
||||||
import '/lib/form/input.js'
|
import '/lib/form/input.js'
|
||||||
import '/lib/form/switch.js'
|
import '/lib/form/switch.js'
|
||||||
import layer from '/lib/layer/index.js'
|
import layer from '/lib/layer/index.js'
|
||||||
|
import { clickOutside } from '/lib/utils.js'
|
||||||
|
|
||||||
const log = console.log
|
const log = console.log
|
||||||
|
|
||||||
|
@ -25,19 +26,23 @@ Anot({
|
||||||
$id: 'app',
|
$id: 'app',
|
||||||
state: {
|
state: {
|
||||||
filter: '',
|
filter: '',
|
||||||
curr: '', //当前选中的域名
|
activeDomain: '', //当前选中的域名
|
||||||
|
editDomain: '', // 当前临时要编辑的域名, 即右键菜单选择到的
|
||||||
domains: [],
|
domains: [],
|
||||||
records: [],
|
records: [],
|
||||||
permissionShow: false
|
permissionShow: false
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
// this.$refs.preview.show()
|
// this.$refs.context.show()
|
||||||
this.check()
|
this.check()
|
||||||
|
clickOutside(this.$refs.context, ev => {
|
||||||
|
this.$refs.context.close()
|
||||||
|
})
|
||||||
},
|
},
|
||||||
watch: {},
|
watch: {},
|
||||||
methods: {
|
methods: {
|
||||||
addRecord() {
|
addRecord() {
|
||||||
if (this.curr) {
|
if (this.activeDomain) {
|
||||||
this.records.unshift({
|
this.records.unshift({
|
||||||
record: '',
|
record: '',
|
||||||
value: '',
|
value: '',
|
||||||
|
@ -61,7 +66,7 @@ Anot({
|
||||||
.then(val => {
|
.then(val => {
|
||||||
this.domains.push(val)
|
this.domains.push(val)
|
||||||
dict[val] = []
|
dict[val] = []
|
||||||
if (!this.curr) {
|
if (!this.activeDomain) {
|
||||||
this.toggleDomain(val)
|
this.toggleDomain(val)
|
||||||
}
|
}
|
||||||
this.save()
|
this.save()
|
||||||
|
@ -69,7 +74,7 @@ Anot({
|
||||||
.catch(Anot.noop)
|
.catch(Anot.noop)
|
||||||
},
|
},
|
||||||
toggleDomain(name) {
|
toggleDomain(name) {
|
||||||
this.curr = name
|
this.activeDomain = name
|
||||||
this.records = dict[name]
|
this.records = dict[name]
|
||||||
tmp_records = Object.create(null)
|
tmp_records = Object.create(null)
|
||||||
for (let it of this.records) {
|
for (let it of this.records) {
|
||||||
|
@ -79,10 +84,78 @@ Anot({
|
||||||
tmp_records[it.record] = [it]
|
tmp_records[it.record] = [it]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
document.title = `伪域名解析「 ${name} 」`
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$refs.records.scrollTop = 0
|
this.$refs.records.scrollTop = 0
|
||||||
}, 50)
|
}, 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}」?`, (val, done) => {
|
||||||
|
if (dict[this.editDomain].length > 0) {
|
||||||
|
return layer.toast(
|
||||||
|
'该域名下有主机记录, 请先删除主机记录后再删除域名',
|
||||||
|
'error'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
delete dict[this.editDomain]
|
||||||
|
this.domains.remove(this.editDomain)
|
||||||
|
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 && val !== this.editDomain) {
|
||||||
|
if (/^[\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.editDomain = ''
|
||||||
|
this.save()
|
||||||
|
this.toggleDomain(val)
|
||||||
|
})
|
||||||
|
.catch(Anot.noop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
check() {
|
check() {
|
||||||
var check = ipcRenderer.sendSync('dns-host', { type: 'check' })
|
var check = ipcRenderer.sendSync('dns-host', { type: 'check' })
|
||||||
|
|
||||||
|
@ -102,6 +175,26 @@ Anot({
|
||||||
this.permissionShow = true
|
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)
|
||||||
|
this.$refs.records.scrollTop = 0
|
||||||
|
},
|
||||||
// 同一个记录, 允许一条被激活
|
// 同一个记录, 允许一条被激活
|
||||||
recordChanges(item) {
|
recordChanges(item) {
|
||||||
if (item.enabled) {
|
if (item.enabled) {
|
||||||
|
@ -115,11 +208,11 @@ Anot({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
save() {
|
save() {
|
||||||
if (this.curr) {
|
if (this.activeDomain) {
|
||||||
dict[this.curr] = this.records.$model
|
dict[this.activeDomain] = this.records.$model
|
||||||
ipcRenderer.send('dns-host', { type: 'set', data: dict })
|
|
||||||
layer.toast('保存成功', 'success')
|
|
||||||
}
|
}
|
||||||
|
ipcRenderer.send('dns-host', { type: 'set', data: dict })
|
||||||
|
layer.toast('保存成功', 'success')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
"use strict";import Drag 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&&(t.classList||Anot.error(`${this.name}=${this.expr}, 解析异常[元素不存在]`),!t.classList.contains(e)&&t.id!==e);)t=t.parentNode;new Drag(t).by(this.element,{limit:this.limit,axis:this.axis,overflow:this.overflow})}});
|
"use strict";import Drag 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}, 解析异常[元素不存在]`),"WC-LAYER"===t.tagName&&"layer"===e){t=t.root.children[1];break}if(t.classList.contains(e)||t.id===e)break;t=t.parentNode}new Drag(t).by(this.element,{limit:this.limit,axis:this.axis,overflow:this.overflow})}});
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-09-27 11:36:21
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,273 +1,14 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-09-16 10:23:25
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const log = console.log
|
import"../icon/index.js";import{bind,unbind}from"../utils.js";export default class Checkbox extends HTMLElement{static get observedAttributes(){return["label","color","value","checked","readonly","disabled"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{label:"",color:"",value:[],checked:!1,readonly:!1,disabled:!1},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-block;line-height:1;font-size:14px}:host label{display:flex;justify-content:center;align-items:center;min-width:32px;height:32px;padding:0 5px;line-height:0;-moz-user-select:none;user-select:none;white-space:nowrap;cursor:inherit;color:#7e909a}:host .dot{--size: 18px;padding:2px;margin-right:3px}:host([readonly]){opacity:0.8}:host([disabled]){cursor:not-allowed;opacity:0.6}:host([size='large']){font-size:16px}:host([size='large']) label{height:42px}:host([size='large']) .dot{--size: 22px}:host([size='medium']) label{height:38px}:host([size='medium']) .dot{--size: 20px}:host([size='mini']){font-size:12px}:host([size='mini']) label{height:20px}:host([size='mini']) .dot{--size: 14px}:host([color='red']) label.checked{color:#ff5061}:host([color='red']) label.checked .dot{border-color:#ff5061}:host([color='red']) label.checked .dot::after{background:#ff5061}:host([color='blue']) label.checked{color:#66b1ff}:host([color='blue']) label.checked .dot{border-color:#66b1ff}:host([color='blue']) label.checked .dot::after{background:#66b1ff}:host([color='green']) label.checked{color:#58d68d}:host([color='green']) label.checked .dot{border-color:#58d68d}:host([color='green']) label.checked .dot::after{background:#58d68d}:host([color='teal']) label.checked{color:#3fc2a7}:host([color='teal']) label.checked .dot{border-color:#3fc2a7}:host([color='teal']) label.checked .dot::after{background:#3fc2a7}:host([color='orange']) label.checked{color:#ffb618}:host([color='orange']) label.checked .dot{border-color:#ffb618}:host([color='orange']) label.checked .dot::after{background:#ffb618}:host([color='dark']) label.checked{color:#62778d}:host([color='dark']) label.checked .dot{border-color:#62778d}:host([color='dark']) label.checked .dot::after{background:#62778d}:host([color='purple']) label.checked{color:#ac61ce}:host([color='purple']) label.checked .dot{border-color:#ac61ce}:host([color='purple']) label.checked .dot::after{background:#ac61ce}\n</style> <label> <wc-icon class=\"dot\" is=\"checkbox-off\"></wc-icon> <slot></slot> </label> ",this.__SWITCH__=this.root.lastElementChild,this.__ICO__=this.__SWITCH__.children[0]}get value(){return this.props.value}set value(e){log(e,this,this.props.label),Array.isArray(e)?(this.props.value=e,this.checked=this.props.value.includes(this.props.label)):console.error("checkbox组件的value必须是数组, 当前为: "+typeof e)}get checked(){return this.props.checked}set checked(e){this.props.checked=!!e;var{value:o,checked:t,label:l,color:r}=this.props;this.__SWITCH__.classList.toggle("checked",t),this.__ICO__.setAttribute("is","checkbox-"+(t?"on":"off"));var s=o.indexOf(l);t?(this.__ICO__.setAttribute("color",r),s<0&&o.push(l)):(this.__ICO__.removeAttribute("color"),~s&&o.splice(s,1))}get readonly(){return this.props.readonly}set readonly(e){var o=typeof e;e!==this.props.readonly&&("boolean"===o&&e||"boolean"!==o?(this.props.readonly=!0,this.setAttribute("readonly","")):(this.props.readonly=!1,this.removeAttribute("readonly")))}get disabled(){return this.props.disabled}set disabled(e){var o=typeof e;e!==this.props.disabled&&("boolean"===o&&e||"boolean"!==o?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}connectedCallback(){this._handlClick=bind(this,"click",e=>{e.preventDefault(),this.disabled||this.readonly||(this.checked=!this.checked,this.dispatchEvent(new CustomEvent("input")))})}disconnectedCallback(){unbind(this,"click",this._handlClick)}attributeChangedCallback(e,o,t){if(null!==t&&o!==t)switch(e){case"label":case"color":this.props[e]=t;break;case"checked":case"readonly":case"disabled":this[e]=!0}}};
|
||||||
|
|
||||||
|
|
||||||
import "../icon/index.js"
|
|
||||||
import { bind, unbind } from "../utils.js"
|
|
||||||
|
|
||||||
export default class Checkbox extends HTMLElement {
|
|
||||||
static get observedAttributes() {
|
|
||||||
return ["label","color","value","checked","readonly","disabled"]
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
Object.defineProperty(this, 'root', {
|
|
||||||
value: this.attachShadow({ mode: 'open' }),
|
|
||||||
writable: true,
|
|
||||||
enumerable: false,
|
|
||||||
configurable: true
|
|
||||||
})
|
|
||||||
Object.defineProperty(this, 'props', {
|
|
||||||
value: {
|
|
||||||
label: '',
|
|
||||||
color: '',
|
|
||||||
value: [],
|
|
||||||
checked: false,
|
|
||||||
readonly: false,
|
|
||||||
disabled: false
|
|
||||||
},
|
|
||||||
writable: true,
|
|
||||||
enumerable: false,
|
|
||||||
configurable: true
|
|
||||||
})
|
|
||||||
|
|
||||||
this.root.innerHTML = `<style>* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0; }
|
|
||||||
|
|
||||||
::before,
|
|
||||||
::after {
|
|
||||||
box-sizing: border-box; }
|
|
||||||
|
|
||||||
:host {
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 1;
|
|
||||||
font-size: 14px; }
|
|
||||||
:host label {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
min-width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
padding: 0 5px;
|
|
||||||
line-height: 0;
|
|
||||||
-moz-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
white-space: nowrap;
|
|
||||||
cursor: inherit;
|
|
||||||
color: #7e909a; }
|
|
||||||
:host .dot {
|
|
||||||
--size: 18px;
|
|
||||||
padding: 2px;
|
|
||||||
margin-right: 3px; }
|
|
||||||
|
|
||||||
:host([readonly]) {
|
|
||||||
opacity: 0.8; }
|
|
||||||
|
|
||||||
:host([disabled]) {
|
|
||||||
cursor: not-allowed;
|
|
||||||
opacity: 0.6; }
|
|
||||||
|
|
||||||
:host([size='large']) {
|
|
||||||
font-size: 16px; }
|
|
||||||
:host([size='large']) label {
|
|
||||||
height: 42px; }
|
|
||||||
:host([size='large']) .dot {
|
|
||||||
--size: 22px; }
|
|
||||||
|
|
||||||
:host([size='medium']) label {
|
|
||||||
height: 38px; }
|
|
||||||
|
|
||||||
:host([size='medium']) .dot {
|
|
||||||
--size: 20px; }
|
|
||||||
|
|
||||||
:host([size='mini']) {
|
|
||||||
font-size: 12px; }
|
|
||||||
:host([size='mini']) label {
|
|
||||||
height: 20px; }
|
|
||||||
:host([size='mini']) .dot {
|
|
||||||
--size: 14px; }
|
|
||||||
|
|
||||||
:host([color='red']) label.checked {
|
|
||||||
color: #ff5061; }
|
|
||||||
:host([color='red']) label.checked .dot {
|
|
||||||
border-color: #ff5061; }
|
|
||||||
:host([color='red']) label.checked .dot::after {
|
|
||||||
background: #ff5061; }
|
|
||||||
|
|
||||||
:host([color='blue']) label.checked {
|
|
||||||
color: #66b1ff; }
|
|
||||||
:host([color='blue']) label.checked .dot {
|
|
||||||
border-color: #66b1ff; }
|
|
||||||
:host([color='blue']) label.checked .dot::after {
|
|
||||||
background: #66b1ff; }
|
|
||||||
|
|
||||||
:host([color='green']) label.checked {
|
|
||||||
color: #58d68d; }
|
|
||||||
:host([color='green']) label.checked .dot {
|
|
||||||
border-color: #58d68d; }
|
|
||||||
:host([color='green']) label.checked .dot::after {
|
|
||||||
background: #58d68d; }
|
|
||||||
|
|
||||||
:host([color='teal']) label.checked {
|
|
||||||
color: #3fc2a7; }
|
|
||||||
:host([color='teal']) label.checked .dot {
|
|
||||||
border-color: #3fc2a7; }
|
|
||||||
:host([color='teal']) label.checked .dot::after {
|
|
||||||
background: #3fc2a7; }
|
|
||||||
|
|
||||||
:host([color='orange']) label.checked {
|
|
||||||
color: #ffb618; }
|
|
||||||
:host([color='orange']) label.checked .dot {
|
|
||||||
border-color: #ffb618; }
|
|
||||||
:host([color='orange']) label.checked .dot::after {
|
|
||||||
background: #ffb618; }
|
|
||||||
|
|
||||||
:host([color='dark']) label.checked {
|
|
||||||
color: #62778d; }
|
|
||||||
:host([color='dark']) label.checked .dot {
|
|
||||||
border-color: #62778d; }
|
|
||||||
:host([color='dark']) label.checked .dot::after {
|
|
||||||
background: #62778d; }
|
|
||||||
|
|
||||||
:host([color='purple']) label.checked {
|
|
||||||
color: #ac61ce; }
|
|
||||||
:host([color='purple']) label.checked .dot {
|
|
||||||
border-color: #ac61ce; }
|
|
||||||
:host([color='purple']) label.checked .dot::after {
|
|
||||||
background: #ac61ce; }
|
|
||||||
</style>
|
|
||||||
<label>
|
|
||||||
<wc-icon class="dot" is="checkbox-off"></wc-icon>
|
|
||||||
<slot></slot>
|
|
||||||
</label>
|
|
||||||
`
|
|
||||||
|
|
||||||
|
|
||||||
this.__SWITCH__ = this.root.lastElementChild
|
|
||||||
this.__ICO__ = this.__SWITCH__.children[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
get value() {
|
|
||||||
return this.props.value
|
|
||||||
}
|
|
||||||
|
|
||||||
set value(val) {
|
|
||||||
log(val, this, this.props.label)
|
|
||||||
if (Array.isArray(val)) {
|
|
||||||
this.props.value = val
|
|
||||||
this.checked = this.props.value.includes(this.props.label)
|
|
||||||
} else {
|
|
||||||
console.error('checkbox组件的value必须是数组, 当前为: ' + typeof val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get checked() {
|
|
||||||
return this.props.checked
|
|
||||||
}
|
|
||||||
|
|
||||||
set checked(val) {
|
|
||||||
this.props.checked = !!val
|
|
||||||
var { value, checked, label, color } = this.props
|
|
||||||
this.__SWITCH__.classList.toggle('checked', checked)
|
|
||||||
this.__ICO__.setAttribute('is', 'checkbox-' + (checked ? 'on' : 'off'))
|
|
||||||
|
|
||||||
var idx = value.indexOf(label)
|
|
||||||
if (checked) {
|
|
||||||
this.__ICO__.setAttribute('color', color)
|
|
||||||
if (idx < 0) {
|
|
||||||
value.push(label)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.__ICO__.removeAttribute('color')
|
|
||||||
if (~idx) {
|
|
||||||
value.splice(idx, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get readonly() {
|
|
||||||
return this.props.readonly
|
|
||||||
}
|
|
||||||
|
|
||||||
set readonly(val) {
|
|
||||||
var type = typeof val
|
|
||||||
|
|
||||||
if (val === this.props.readonly) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ((type === 'boolean' && val) || type !== 'boolean') {
|
|
||||||
this.props.readonly = true
|
|
||||||
this.setAttribute('readonly', '')
|
|
||||||
} else {
|
|
||||||
this.props.readonly = false
|
|
||||||
this.removeAttribute('readonly')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get disabled() {
|
|
||||||
return this.props.disabled
|
|
||||||
}
|
|
||||||
|
|
||||||
set disabled(val) {
|
|
||||||
var type = typeof val
|
|
||||||
|
|
||||||
if (val === this.props.disabled) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if ((type === 'boolean' && val) || type !== 'boolean') {
|
|
||||||
this.props.disabled = true
|
|
||||||
this.setAttribute('disabled', '')
|
|
||||||
} else {
|
|
||||||
this.props.disabled = false
|
|
||||||
this.removeAttribute('disabled')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
this._handlClick = bind(this, 'click', ev => {
|
|
||||||
ev.preventDefault()
|
|
||||||
|
|
||||||
if (!this.disabled && !this.readonly) {
|
|
||||||
this.checked = !this.checked
|
|
||||||
this.dispatchEvent(new CustomEvent('input'))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnectedCallback() {
|
|
||||||
unbind(this, 'click', this._handlClick)
|
|
||||||
}
|
|
||||||
|
|
||||||
attributeChangedCallback(name, old, val) {
|
|
||||||
if (val === null || old === val) {return}
|
|
||||||
switch (name) {
|
|
||||||
case 'label':
|
|
||||||
case 'color':
|
|
||||||
this.props[name] = val
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'checked':
|
|
||||||
case 'readonly':
|
|
||||||
case 'disabled':
|
|
||||||
this[name] = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(!customElements.get('wc-checkbox')){
|
if(!customElements.get('wc-checkbox')){
|
||||||
customElements.define('wc-checkbox', Checkbox)
|
customElements.define('wc-checkbox', Checkbox)
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-09-27 11:36:21
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-09-27 11:36:21
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-09-27 11:36:21
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-09-27 11:36:21
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-09-27 11:36:21
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-09-27 11:36:21
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-09-27 11:36:21
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @authors yutent (yutent@doui.cc)
|
* @authors yutent (yutent@doui.cc)
|
||||||
* @date 2019-12-02 15:38:50
|
* @date 2019-12-11 17:59:30
|
||||||
* @version v2.0.1
|
* @version v2.0.1
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue