diff --git a/package.json b/package.json index 727f880..d03c26e 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,12 @@ "name": "dns-host", "version": "1.0.0", "description": "伪域名解析", - "main": "main.js", + "main": "src/main.js", "scripts": { "start": "electron .", - "pack": "electron-builder" + "pack": "electron-builder", + "pack:mac": "electron-builder --mac", + "pack:linux": "electron-builder --linux" }, "author": { "name": "yutent", @@ -46,7 +48,7 @@ } }, "devDependencies": { - "electron": "^6.0.5", - "electron-builder": "^21.2.0" + "electron": "^7.1.0", + "electron-builder": "^22.0.0" } } diff --git a/src/css/app.css b/src/css/app.css new file mode 100644 index 0000000..b31f80c --- /dev/null +++ b/src/css/app.css @@ -0,0 +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:none;flex-direction:column;align-items:center;width:100%;height:100%;padding:5rem;background:rgba(250,146,146,0.35);-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} diff --git a/src/css/app.scss b/src/css/app.scss new file mode 100644 index 0000000..6430887 --- /dev/null +++ b/src/css/app.scss @@ -0,0 +1,134 @@ +@charset "UTF-8"; +/** + * {sonist app style} + * @authors yutent + * @date 2018/12/16 17:15:07 + */ + + +@import "./var.scss"; + + +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:nth($cd, 1); +} + + +.layout-left { + display:flex;flex-direction:column; + width:18rem;height:64rem; + background:nth($cd, 2); + + wc-scroll {flex:1;} + + .domain-list { + width:100%; + + .item { + display:flex;justify-content:flex-end;align-items:center; + height:4rem;padding:0 2rem 0 1rem; + color:nth($cp, 1);cursor:pointer; + @include ts(background); + + wc-icon {--size:1.2rem;margin:auto -1.5rem auto .5rem;color:nth($cgr, 3);} + + &:hover, + &.active {background:nth($cd, 1);} + &.active {border-left:.3rem solid nth($co, 1);} + &.blank { + justify-content:center;cursor:default; + &:hover {background:none;} + } + } + } + + .action { + display:flex;align-items:center; + height:5rem;padding:0 1rem; + } + +} + + +.layout-right { + flex:1;display:flex;flex-direction:column; + background:#f7f8fb; + + .toolbar { + display:flex;align-items:center;justify-content:space-between; + height:4rem;padding:0 1.5rem; + background:nth($cp, 2);box-shadow:0 .2rem .5rem rgba(0, 0, 0, .1); + + wc-input {width:20rem;} + } + + .main { + overflow:hidden; + flex:1;display:flex;flex-direction:column;margin:2rem 1rem;padding:0 .5rem; + background:#fff; + } + + .thead { + display:flex;align-items:center;justify-content:center; + height:4rem;margin-bottom:.8rem; + border-bottom:.1rem solid nth($cp, 2);text-align:center; + + span {flex:1;} + .long {flex:1.5;} + } + + wc-scroll {flex:1;} + .record-list { + width:100%;line-height:4rem; + + .item { + display:flex;justify-content:center;align-items:center; + height:4rem;padding:0 1rem; + border-bottom:.1rem solid nth($cp, 2);text-align:center; + + wc-input,span,section {flex:1;} + .long {flex:1.5;} + section {display:flex;align-items:center;justify-content:center;} + + &:hover {background:nth($cp, 1);} + &:last-child {border-bottom:none;} + } + } +} + + + + + +.permission-error { + position:fixed;left:0;top:0;z-index:102401; + display:none;flex-direction:column;align-items:center; + width:100%;height:100%;padding:5rem; + background:rgba(250, 146, 146, .35); + backdrop-filter:blur(.5rem); + + pre {font-family:'Courier New', Courier, monospace;font-size:1.6rem;color:nth($cr, 2);} + + fieldset { + width:60rem;padding:0 3rem 3rem; + border:.1rem solid nth($co, 1);border-radius:.8rem; + + legend {padding:0 1rem;font-size:1.6rem;} + + dt {margin-top:2rem;font-weight:bold;} + code { + display:block; + padding:.8rem 1rem;margin-top:.8rem; + border-left:.3rem solid nth($cp, 3); + background:rgba(255, 255, 255, .3); + font-family:'Courier New', Courier, monospace; + } + } + + &.show {display:flex;} +} + diff --git a/src/css/var.scss b/src/css/var.scss new file mode 100644 index 0000000..a090875 --- /dev/null +++ b/src/css/var.scss @@ -0,0 +1,15 @@ +$ct: #3fc2a7 #19b491 #16967a; +$cg: #58d68d #2ecc71 #27ae60; +$cpp: #ac61ce #9b59b6 #8e44ad; +$cb: #66b1ff #409eff #3a8ee6; +$cr: #ff5061 #eb3b48 #ce3742; +$co: #ffb618 #f39c12 #e67e22; +$cp: #f3f5fb #e8ebf4 #dae1e9; +$cgr: #aabac3 #90a3ae #7e909a; +$cd: #62778d #526273 #425064; + +@mixin ts($c: all, $t: .1s, $m: ease-in-out){ + transition:$c $t $m; +} + + diff --git a/src/images/app.png b/src/images/app.png new file mode 100644 index 0000000..fabef8b Binary files /dev/null and b/src/images/app.png differ diff --git a/src/index.html b/src/index.html index e69de29..12db07c 100644 --- a/src/index.html +++ b/src/index.html @@ -0,0 +1,97 @@ + + + + + + + + + + + + + +
+ +
    +
  • + + +
  • +
  • 没有域名
  • +
+
+
+ +
+
+ +
+ +
+ 新增记录 + 保存 +
+ +
+
+ 主机记录 + 记录类型 + 记录值 + 操作 + 备注 +
+ +
    +
  • + + A + +
    + + 删除 +
    + +
  • +
+
+
+
+ + + +
+
+/************************************************************/
+ *                   hosts文件没有写权限                      *
+/************************************************************/
+    
+
+ 操作指引 +
+
MacOS用户
+
打开终端, 执行以下命令
+
sudo chown $USER:admin /etc/hosts
+ +
Linux用户
+
打开终端, 执行以下命令
+
sudo chown $USER: /etc/hosts
+ +
完成之后
+
点击下面的按钮重新检测.
+
+ 权限检测 +
+
+
+
+ + \ No newline at end of file diff --git a/src/js/app.js b/src/js/app.js new file mode 100644 index 0000000..7af2481 --- /dev/null +++ b/src/js/app.js @@ -0,0 +1,86 @@ +/** + * {sonist app} + * @author yutent + * @date 2018/12/16 17:15:57 + */ + +import '/lib/anot.js' +import '/lib/form/button.js' +import '/lib/form/input.js' +import '/lib/form/switch.js' +import layer from '/lib/layer/index.js' + +const log = console.log + +const { remote, ipcRenderer } = require('electron') + +const WIN = remote.getCurrentWindow() + +const $doc = Anot(document) + +Anot({ + $id: 'app', + state: { + filter: '', + curr: '', //当前选中的域名 + domains: [], + records: [ + { + record: '', + value: '', + enabled: true, + remark: '' + } + ], + permissionShow: false + }, + mounted() { + // this.$refs.preview.show() + this.check() + }, + methods: { + addRecord() { + log('---') + if (this.curr) { + this.records.unshift({ + record: '', + value: '', + enabled: true, + remark: '' + }) + this.$refs.records.scrollTop = 0 + } else { + layer.toast('请先选择域名') + } + }, + addDomain() { + layer + .prompt('请输入根域名', function(val, done) { + if (/^[\w.]+\.[a-z]+$/.test(val)) { + done() + } else { + layer.toast('域名格式错误', 'error') + } + }) + .then(val => { + this.domains.push(val) + if (!this.curr) { + this.toggleDomain(val) + } + }) + .catch(Anot.noop) + }, + toggleDomain(name) { + this.curr = name + }, + check() { + var check = ipcRenderer.sendSync('dns-host', { type: 'check' }) + + if (check) { + } else { + this.permissionShow = true + } + }, + save() {} + } +}) diff --git a/src/lib/form/button.js b/src/lib/form/button.js index 85a65ab..2522820 100644 --- a/src/lib/form/button.js +++ b/src/lib/form/button.js @@ -1,7 +1,7 @@ /** * * @authors yutent (yutent@doui.cc) - * @date 2019-09-16 20:52:26 + * @date 2019-09-27 11:36:21 * @version v2.0.1 * */ diff --git a/src/lib/form/checkbox.js b/src/lib/form/checkbox.js index 23ab531..7855e9a 100644 --- a/src/lib/form/checkbox.js +++ b/src/lib/form/checkbox.js @@ -1,14 +1,273 @@ /** * * @authors yutent (yutent@doui.cc) - * @date 2019-09-16 20:52:26 + * @date 2019-09-16 10:23:25 * @version v2.0.1 * */ 'use strict' -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=" ",this.__SWITCH__=this.root.lastElementChild,this.__ICO__=this.__SWITCH__.children[0]}get value(){return this.props.value}set value(e){if(!Array.isArray(e))throw TypeError(":duplex指令需要传入一个数组, 当前为: "+typeof e);this.props.value=e,this.checked=this.props.value.includes(this.props.label)}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 c=o.indexOf(l);t?(this.__ICO__.setAttribute("color",r),c<0&&o.push(l)):(this.__ICO__.removeAttribute("color"),~c&&o.splice(c,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}}}; +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: 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 = ` + +` + + + 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')){ customElements.define('wc-checkbox', Checkbox) diff --git a/src/lib/form/input.js b/src/lib/form/input.js index 036046f..887340f 100644 --- a/src/lib/form/input.js +++ b/src/lib/form/input.js @@ -1,14 +1,14 @@ /** * * @authors yutent (yutent@doui.cc) - * @date 2019-09-16 20:52:26 + * @date 2019-09-27 11:36:21 * @version v2.0.1 * */ 'use strict' -import"../scroll/index.js";import"../icon/index.js";import{ebind,bind,unbind,clickOutside}from"../utils.js";const TYPES=["text","textarea","password"],INPUTS={text:'',textarea:''};export default class Input extends HTMLElement{static get observedAttributes(){return["value","icon","type","label","placeholder","mvidx","autofocus","readonly","disabled"]}constructor(){super();var e,t=this.getAttribute("type");"textarea"!==t&&(t="text"),e=INPUTS[t],Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{value:"",icon:"",type:"text",label:"",placeholder:"",mvidx:null,autofocus:!1,readonly:!1,disabled:!1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=`
${e}
    `,this.props.type=t,this.__OUTER__=this.root.children[1],this.__PREPEND__=this.__OUTER__.children[0],this.__INPUT__=this.__OUTER__.children[1],this.__ICO__=this.__OUTER__.children[2],this.__APPEND__=this.__OUTER__.children[3],this.__LIST__=this.__OUTER__.children[4]}get readonly(){return this.props.readonly}set readonly(e){var t=typeof e;e!==this.props.readonly&&("boolean"===t&&e||"boolean"!==t?(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&&("boolean"===t&&e||"boolean"!==t?(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}get type(){return this.__INPUT__.type}set type(e){"textarea"!==e&&(this.__INPUT__.type=e)}_moveSelect(e){var{list:t}=this.props;if(t&&t.length){e.preventDefault();var i=38===e.keyCode?-1:1,s=Array.from(this.__LIST__.firstElementChild.firstElementChild.children);null===this.props.mvidx?this.props.mvidx=0:this.props.mvidx+=i,this.props.mvidx<0?this.props.mvidx=0:this.props.mvidx>s.length-1&&(this.props.mvidx=s.length-1),s.forEach((e,t)=>{t===this.props.mvidx?(this.__LIST__.firstElementChild.scrollTop=e.offsetTop-150,e.setAttribute("focus","")):e.removeAttribute("focus")})}}_fetchSelect(e,t){var i=this.props.list[e];this.value=i.value,this.dispatchEvent(new CustomEvent("select",{detail:i})),this._handleChange(t),this.__LIST__.classList.remove("show"),this.props.mvidx=null}connectedCallback(){for(var e=this.__PREPEND__.assignedNodes(),t=this.__APPEND__.assignedNodes();e.length>1;)this.removeChild(e.pop());for(;t.length>1;)this.removeChild(t.pop());e.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("prepend",""),t.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("append","");var{type:i}=this.props;this._handleSubmit=ebind(this.__INPUT__,"keydown",e=>{if(!this.disabled&&!this.readonly){if((38===e.keyCode||40===e.keyCode)&&"text"===this.type)return this._moveSelect(e);if(13===e.keyCode){if("text"===this.type&&null!==this.props.mvidx)return this._fetchSelect(this.props.mvidx,e);("text"===i||"textarea"===i&&(e.ctrlKey||e.metaKey))&&this.dispatchEvent(new CustomEvent("submit",{detail:this.value}))}}}),this._handleWheel=ebind(this.__INPUT__,"wheel"),"text"===i&&(this._handleChange=bind(this.__INPUT__,"input",e=>{e.preventDefault(),this.dispatchEvent(new CustomEvent("fetch-suggest",{detail:{value:this.value,send:e=>{this.props.list=e,this._parseSuggestion()}}}))}),this._parseSuggestion=bind(this.__INPUT__,"click",e=>{var{list:t}=this.props;let{x:i,y:s,width:o}=this.getBoundingClientRect();if(t&&t.length){var l=t.map((e,t)=>`
  • ${e.value}
  • `).join("");this.__LIST__.firstElementChild.firstElementChild.innerHTML=l,this.__LIST__.classList.toggle("show",!0),this.__LIST__.style.cssText=`left:${i}px;top:${s+50}px;width:${o}px;`}else this.__LIST__.classList.toggle("show",!1)}),this._inactiveFn=clickOutside(this,e=>{this.__LIST__.classList.remove("show")}),this._handleSelect=bind(this.__LIST__,"click",e=>{"LI"===e.target.tagName&&(this._fetchSelect(e.target.dataset.idx,e),this.dispatchEvent(new CustomEvent("input")))}))}disconnectedCallback(){unbind(this.__INPUT__,"wheel",this._handleWheel),unbind(this.__INPUT__,"keydown",this._handleSubmit),unbind(this.__INPUT__,"input",this._handleChange),unbind(document,"mousedown",this._inactiveFn),unbind(this.__LIST__,"click",this._handleSelect)}attributeChangedCallback(e,t,i){if(null!==i&&t!==i)switch(e){case"icon":this.props.icon=i,i?this.__ICO__.setAttribute("is",i):(this.removeAttribute("icon"),this.__ICO__.removeAttribute("is"));break;case"autofocus":this.__INPUT__.setAttribute("autofocus",""),setTimeout(e=>{this.__INPUT__.focus()},10);break;case"label":case"placeholder":this.__INPUT__.setAttribute("placeholder",i);break;case"type":~TYPES.indexOf(i)?this.type=i:this.type="text";break;case"value":this.value=i;break;case"readonly":case"disabled":this[e]=!0}}}; +import"../scroll/index.js";import"../icon/index.js";import{ebind,bind,unbind,clickOutside}from"../utils.js";const TYPES=["text","textarea","password"],INPUTS={text:'',textarea:''};export default class Input extends HTMLElement{static get observedAttributes(){return["value","icon","type","label","placeholder","mvidx","autofocus","readonly","disabled"]}constructor(){super();var e,t=this.getAttribute("type");"textarea"!==t&&(t="text"),e=INPUTS[t],Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{value:"",icon:"",type:"text",label:"",placeholder:"",mvidx:null,autofocus:!1,readonly:!1,disabled:!1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=`
    ${e}
      `,this.props.type=t,this.__OUTER__=this.root.children[1],this.__PREPEND__=this.__OUTER__.children[0],this.__INPUT__=this.__OUTER__.children[1],this.__ICO__=this.__OUTER__.children[2],this.__APPEND__=this.__OUTER__.children[3],this.__LIST__=this.__OUTER__.children[4]}get readonly(){return this.props.readonly}set readonly(e){var t=typeof e;e!==this.props.readonly&&("boolean"===t&&e||"boolean"!==t?(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&&("boolean"===t&&e||"boolean"!==t?(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}get type(){return this.__INPUT__.type}set type(e){"textarea"!==e&&(this.__INPUT__.type=e)}_moveSelect(e){var{list:t}=this.props;if(t&&t.length){e.preventDefault();var i=38===e.keyCode?-1:1,s=Array.from(this.__LIST__.firstElementChild.firstElementChild.children);null===this.props.mvidx?this.props.mvidx=0:this.props.mvidx+=i,this.props.mvidx<0?this.props.mvidx=0:this.props.mvidx>s.length-1&&(this.props.mvidx=s.length-1),s.forEach((e,t)=>{t===this.props.mvidx?(this.__LIST__.firstElementChild.scrollTop=e.offsetTop-150,e.setAttribute("focus","")):e.removeAttribute("focus")})}}_fetchSelect(e,t){var i=this.props.list[e];this.value=i.value,this.dispatchEvent(new CustomEvent("select",{detail:i})),this._handleChange(t),this.__LIST__.classList.remove("show"),this.props.mvidx=null}connectedCallback(){for(var e=this.__PREPEND__.assignedNodes(),t=this.__APPEND__.assignedNodes();e.length>1;)this.removeChild(e.pop());for(;t.length>1;)this.removeChild(t.pop());e.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("prepend",""),t.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("append","");var{type:i}=this.props;this._handleSubmit=ebind(this.__INPUT__,"keydown",e=>{if(!this.disabled&&!this.readonly){if((38===e.keyCode||40===e.keyCode)&&"text"===this.type)return this._moveSelect(e);if(13===e.keyCode){if("text"===this.type&&null!==this.props.mvidx)return this._fetchSelect(this.props.mvidx,e);("text"===i||"textarea"===i&&(e.ctrlKey||e.metaKey))&&this.dispatchEvent(new CustomEvent("submit",{detail:this.value}))}}}),this._handleWheel=ebind(this.__INPUT__,"wheel"),"text"===i&&(this._handleChange=bind(this.__INPUT__,"input",e=>{e.preventDefault(),this.dispatchEvent(new CustomEvent("fetch-suggest",{detail:{value:this.value,send:e=>{this.props.list=e,this._parseSuggestion()}}}))}),this._parseSuggestion=bind(this.__INPUT__,"click",e=>{var{list:t}=this.props;let{x:i,y:s,width:o}=this.getBoundingClientRect();if(t&&t.length){var l=t.map((e,t)=>`
    • ${e.value}
    • `).join("");this.__LIST__.firstElementChild.firstElementChild.innerHTML=l,this.__LIST__.classList.toggle("show",!0),this.__LIST__.style.cssText=`left:${i}px;top:${s+50}px;width:${o}px;`}else this.__LIST__.classList.toggle("show",!1)}),this._inactiveFn=clickOutside(this,e=>{this.__LIST__.classList.remove("show")}),this._handleSelect=bind(this.__LIST__,"click",e=>{"LI"===e.target.tagName&&(this._fetchSelect(e.target.dataset.idx,e),this.dispatchEvent(new CustomEvent("input")))}))}disconnectedCallback(){unbind(this.__INPUT__,"wheel",this._handleWheel),unbind(this.__INPUT__,"keydown",this._handleSubmit),unbind(this.__INPUT__,"input",this._handleChange),unbind(document,"mousedown",this._inactiveFn),unbind(this.__LIST__,"click",this._handleSelect)}attributeChangedCallback(e,t,i){if(null!==i&&t!==i)switch(e){case"icon":this.props.icon=i,i?this.__ICO__.setAttribute("is",i):(this.removeAttribute("icon"),this.__ICO__.removeAttribute("is"));break;case"autofocus":this.__INPUT__.setAttribute("autofocus",""),setTimeout(e=>{this.__INPUT__.focus()},10);break;case"label":case"placeholder":this.__INPUT__.setAttribute("placeholder",i);break;case"type":~TYPES.indexOf(i)?this.type=i:this.type="text";break;case"value":this.value=i;break;case"readonly":case"disabled":this[e]=!0}}}; if(!customElements.get('wc-input')){ customElements.define('wc-input', Input) diff --git a/src/lib/form/number.js b/src/lib/form/number.js new file mode 100644 index 0000000..de073a3 --- /dev/null +++ b/src/lib/form/number.js @@ -0,0 +1,15 @@ +/** + * + * @authors yutent (yutent@doui.cc) + * @date 2019-09-27 11:36:21 + * @version v2.0.1 + * + */ + +'use strict' + +import"../scroll/index.js";import"../icon/index.js";import{ebind,bind,unbind}from"../utils.js";export default class Number extends HTMLElement{static get observedAttributes(){return["value","max","min","step","autofocus","readonly","disabled"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{value:0,max:null,min:null,step:1,autofocus:!1,readonly:!1,disabled:!1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="
      - \x3c!-- --\x3e + \x3c!-- --\x3e
      ",this.__OUTER__=this.root.children[1],this.__INPUT__=this.__OUTER__.children[1]}get readonly(){return this.props.readonly}set readonly(e){var t=typeof e;e!==this.props.readonly&&("boolean"===t&&e||"boolean"!==t?(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&&("boolean"===t&&e||"boolean"!==t?(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.props.value}set value(e){var t=+e;e=t==t?t:0,this.props.value=e,this.__INPUT__.value=this.props.value,this._checkActionEnable()}_checkActionEnable(){var{max:e,min:t,value:i}=this.props;null!==e&&this.__OUTER__.children[2].classList.toggle("disabled",i>=e),null!==t&&this.__OUTER__.children[0].classList.toggle("disabled",i<=t)}_updateValue(e){var{max:t,min:i,value:s,step:a}=this.props;if("+"===e){if(null!==t&&ts-a)return;s-=a}this.props.value=+s.toFixed(2),this.__INPUT__.value=this.props.value,this._checkActionEnable(),this.dispatchEvent(new CustomEvent("input"))}connectedCallback(){this._handleSubmit=ebind(this.__INPUT__,"keydown",e=>{if(!this.disabled&&!this.readonly)return 38===e.keyCode||40===e.keyCode?(e.preventDefault(),this._updateValue(38===e.keyCode?"+":"-")):void(13===e.keyCode&&(e.preventDefault(),this.dispatchEvent(new CustomEvent("submit",{detail:this.value}))))}),this._handleChange=ebind(this.__INPUT__,"change",e=>{isFinite(this.__INPUT__.value)?(this.props.value=+this.__INPUT__.value,this.__INPUT__.value.endsWith(".")||(this.__INPUT__.value=this.props.value)):this.__INPUT__.value=this.props.value=0,this.dispatchEvent(new CustomEvent("input"))}),this._handleAction=bind(this.__OUTER__,"click",e=>{if(!this.disabled&&!this.readonly){var t=e.target;if("SPAN"===t.tagName||"SPAN"===t.parentNode){var i=t.dataset.act||t.parentNode.dataset.act;this._updateValue(i)}}})}disconnectedCallback(){unbind(this.__INPUT__,"keydown",this._handleSubmit)}attributeChangedCallback(e,t,i){if(null!==i&&t!==i)switch(e){case"autofocus":this.__INPUT__.setAttribute("autofocus",""),setTimeout(e=>{this.__INPUT__.focus()},10);break;case"value":this.value=i>>0;break;case"step":case"max":case"min":var s=+i;s==s&&(this.props[e]=s),this._checkActionEnable();break;case"readonly":case"disabled":this[e]=!0}}}; + +if(!customElements.get('wc-number')){ + customElements.define('wc-number', Number) +} diff --git a/src/lib/form/progress.js b/src/lib/form/progress.js new file mode 100644 index 0000000..50759da --- /dev/null +++ b/src/lib/form/progress.js @@ -0,0 +1,15 @@ +/** + * + * @authors yutent (yutent@doui.cc) + * @date 2019-09-27 11:36:21 + * @version v2.0.1 + * + */ + +'use strict' + +export default class Progress extends HTMLElement{static get observedAttributes(){return["value","max"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{value:0,max:1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=" ",this.__THUMB__=this.root.children[1].lastElementChild}get value(){return this.props.value}set value(e){this.props.value=+e,this.calculate()}calculate(){var{max:e,value:a}=this.props;this.__THUMB__.style.width=`${100*a/e}%`}connectedCallback(){this.calculate()}attributeChangedCallback(e,a,l){if(null!==l&&a!==l)switch(e){case t:var t=+l;(t!=t||t<1)&&(t=1),this.props.max=t,this.calculate();break;case"value":var r=+l;r==r&&(this.props.value=r,this.calculate())}}}; + +if(!customElements.get('wc-progress')){ + customElements.define('wc-progress', Progress) +} diff --git a/src/lib/form/radio.js b/src/lib/form/radio.js new file mode 100644 index 0000000..72e413b --- /dev/null +++ b/src/lib/form/radio.js @@ -0,0 +1,15 @@ +/** + * + * @authors yutent (yutent@doui.cc) + * @date 2019-09-27 11:36:21 + * @version v2.0.1 + * + */ + +'use strict' + +import{bind,unbind}from"../utils.js";export default class Radio extends HTMLElement{static get observedAttributes(){return["label","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:"",checked:!1,readonly:!1,disabled:!1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=" ",this.__SWITCH__=this.root.lastElementChild}get value(){return this.props.label}set value(e){this.checked=this.props.label===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 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._handleClick=bind(this,"click",e=>{this.disabled||this.readonly||this.checked||(this.checked=!0,this.dispatchEvent(new CustomEvent("input")))})}disconnectedCallback(){unbind(this,"click",this._handleClick)}attributeChangedCallback(e,o,t){if(null!==t&&o!==t)switch(e){case"label":this.props.label=t;break;case"checked":case"readonly":case"disabled":this[e]=!0}}}; + +if(!customElements.get('wc-radio')){ + customElements.define('wc-radio', Radio) +} diff --git a/src/lib/form/select.js b/src/lib/form/select.js index 75da8c9..77a3894 100644 --- a/src/lib/form/select.js +++ b/src/lib/form/select.js @@ -1,14 +1,14 @@ /** * * @authors yutent (yutent@doui.cc) - * @date 2019-09-16 20:52:26 + * @date 2019-09-27 11:36:21 * @version v2.0.1 * */ 'use strict' -import"../scroll/index.js";import"../icon/index.js";import{ebind,bind,unbind,clickOutside}from"../utils.js";function parseOptions(e,t){let i="";for(let s of e)if(s.list){i+=`
      ${s.name}
      `;for(let e of s.list)t.DICT[e.value]=e,e.disabled||t.LIST.push(e),i+=`
      ${e.label}
      `}else s.disabled||t.LIST.push(s),t.DICT[s.value]=s,i+=`
      ${s.label}
      `;return i}export default class Select extends HTMLElement{static get observedAttributes(){return["label","placeholder","multi","value","options","mvidx","disabled"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{label:"",placeholder:"",multi:"",value:"",options:"",mvidx:null,disabled:!1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="
      ",this.__OUTER__=this.root.children[1],this.__PREPEND__=this.__OUTER__.children[0],this.__INPUT__=this.__OUTER__.children[1],this.__APPEND__=this.__OUTER__.children[3],this.__OPTG__=this.__OUTER__.children[4]}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&("boolean"===t&&e||"boolean"!==t?(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.props.value}set value(e){var{DICT:t,active:i}=this.props;this.props.value=e,this.__INPUT__.value=t&&t[e]&&t[e].label||e,i||this._updateStyle()}_renderOptions(e){this.props.DICT={},this.props.LIST=[];var t=this.__OPTG__.firstElementChild.firstElementChild;t.innerHTML=parseOptions(e,this.props),this.props.ITEMS=Array.from(t.children).filter(e=>"DD"===e.tagName&&!e.hasAttribute("disabled")),this.value=this.props.value}_moveSelect(e){var{LIST:t,DICT:i,ITEMS:s}=this.props;if(t&&t.length){e.preventDefault();var o=38===e.keyCode?-1:1;null===this.props.mvidx?this.props.mvidx=0:this.props.mvidx+=o,this.props.mvidx<0?this.props.mvidx=0:this.props.mvidx>s.length-1&&(this.props.mvidx=s.length-1),s.forEach((e,t)=>{t===this.props.mvidx?(this.__OPTG__.firstElementChild.scrollTop=e.offsetTop-150,e.setAttribute("focus","")):e.removeAttribute("focus")})}}_updateStyle(e){var{LIST:t,ITEMS:i,value:s}=this.props;if(t&&t.length){if(void 0===e)for(let i,o=-1;i=t[++o];)if(s===i.value){e=o;break}this.props.mvidx=e,i.forEach((t,i)=>{i===e?t.setAttribute("focus",""):t.removeAttribute("focus")})}}_fetchSelect(e,t){var i=this.props.LIST[e];this.value=i.value,this.dispatchEvent(new CustomEvent("select",{detail:i})),t&&this._updateStyle(e),this.props.active=!1,this.__OPTG__.classList.remove("show")}connectedCallback(){for(var e=this.__PREPEND__.assignedNodes(),t=this.__APPEND__.assignedNodes();e.length>1;)this.removeChild(e.pop());for(;t.length>1;)this.removeChild(t.pop());function i(){var{x:e,y:t,width:i}=this.getBoundingClientRect(),s=this.getAttribute("size");this.props.active=!0,t+=s&&"mini"===s?32:50,this.__OPTG__.style.cssText=`left:${e}px;top:${t}px;width:${i}px;`}e.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("prepend",""),t.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("append",""),this._handleKeydown=ebind(this.__INPUT__,"keydown",e=>{if(!this.disabled&&!this.readonly)return 38===e.keyCode||40===e.keyCode?this.props.active?this._moveSelect(e):(i.call(this),void this.__OPTG__.classList.toggle("show",!0)):13===e.keyCode&&null!==this.props.mvidx&&this.props.active?this._fetchSelect(this.props.mvidx):void 0}),this._activeFn=bind(this.__INPUT__,"click",e=>{var{options:t}=this.props;i.call(this),this.__OPTG__.classList.toggle("show")}),this._handleSelect=bind(this.__OPTG__,"click",e=>{"DD"!==e.target.tagName||e.target.hasAttribute("disabled")||(this._fetchSelect(+e.target.dataset.idx,!0),this.dispatchEvent(new CustomEvent("input")))}),this._inactiveFn=clickOutside(this,e=>{this.__OPTG__.classList.toggle("show",!1),this.props.active=!1})}attributeChangedCallback(e,t,i){if(null!==i&&t!==i)switch(e){case"label":case"placeholder":this.__INPUT__.setAttribute("placeholder",i);break;case"options":if(i){try{this._renderOptions(JSON.parse(i))}catch(e){}this.removeAttribute("options")}break;case"value":this.value=i;break;case"readonly":case"disabled":this[e]=!0}}disconnectedCallback(){unbind(this.__INPUT__,"keydown",this._handleKeydown),unbind(this.__INPUT__,"click",this._activeFn),unbind(document,"mousedown",this._inactiveFn),unbind(this.__OPTG__,"click",this._handleSelect)}}; +import"../scroll/index.js";import"../icon/index.js";import{ebind,bind,unbind,clickOutside}from"../utils.js";function parseOptions(e,t){let i="";for(let s of e)if(s.list){i+=`
      ${s.name}
      `;for(let e of s.list)t.DICT[e.value]=e,e.disabled||t.LIST.push(e),i+=`
      ${e.label}
      `}else s.disabled||t.LIST.push(s),t.DICT[s.value]=s,i+=`
      ${s.label}
      `;return i}export default class Select extends HTMLElement{static get observedAttributes(){return["label","placeholder","multi","value","options","mvidx","disabled"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{label:"",placeholder:"",multi:"",value:"",options:"",mvidx:null,disabled:!1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="
      ",this.__OUTER__=this.root.children[1],this.__PREPEND__=this.__OUTER__.children[0],this.__INPUT__=this.__OUTER__.children[1],this.__APPEND__=this.__OUTER__.children[3],this.__OPTG__=this.__OUTER__.children[4]}get disabled(){return this.props.disabled}set disabled(e){var t=typeof e;e!==this.props.disabled&&("boolean"===t&&e||"boolean"!==t?(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.props.value}set value(e){var{DICT:t,active:i}=this.props;this.props.value=e,this.__INPUT__.value=t&&t[e]&&t[e].label||e,i||this._updateStyle()}_renderOptions(e){this.props.DICT={},this.props.LIST=[];var t=this.__OPTG__.firstElementChild.firstElementChild;t.innerHTML=parseOptions(e,this.props),this.props.ITEMS=Array.from(t.children).filter(e=>"DD"===e.tagName&&!e.hasAttribute("disabled")),this.value=this.props.value}_moveSelect(e){var{LIST:t,DICT:i,ITEMS:s}=this.props;if(t&&t.length){e.preventDefault();var o=38===e.keyCode?-1:1;null===this.props.mvidx?this.props.mvidx=0:this.props.mvidx+=o,this.props.mvidx<0?this.props.mvidx=0:this.props.mvidx>s.length-1&&(this.props.mvidx=s.length-1),s.forEach((e,t)=>{t===this.props.mvidx?(this.__OPTG__.firstElementChild.scrollTop=e.offsetTop-150,e.setAttribute("focus","")):e.removeAttribute("focus")})}}_updateStyle(e){var{LIST:t,ITEMS:i,value:s}=this.props;if(t&&t.length){if(void 0===e)for(let i,o=-1;i=t[++o];)if(s===i.value){e=o;break}this.props.mvidx=e,i.forEach((t,i)=>{i===e?t.setAttribute("focus",""):t.removeAttribute("focus")})}}_fetchSelect(e,t){var i=this.props.LIST[e];this.value=i.value,this.dispatchEvent(new CustomEvent("select",{detail:i})),t&&this._updateStyle(e),this.props.active=!1,this.__OPTG__.classList.remove("show")}connectedCallback(){for(var e=this.__PREPEND__.assignedNodes(),t=this.__APPEND__.assignedNodes();e.length>1;)this.removeChild(e.pop());for(;t.length>1;)this.removeChild(t.pop());function i(){var{x:e,y:t,width:i}=this.getBoundingClientRect(),s=this.getAttribute("size");this.props.active=!0,t+=s&&"mini"===s?32:50,this.__OPTG__.style.cssText=`left:${e}px;top:${t}px;width:${i}px;`}e.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("prepend",""),t.length&&"textarea"!==this.props.type&&this.__OUTER__.setAttribute("append",""),this._handleKeydown=ebind(this.__INPUT__,"keydown",e=>{if(!this.disabled&&!this.readonly)return 38===e.keyCode||40===e.keyCode?this.props.active?this._moveSelect(e):(i.call(this),void this.__OPTG__.classList.toggle("show",!0)):13===e.keyCode&&null!==this.props.mvidx&&this.props.active?this._fetchSelect(this.props.mvidx):void 0}),this._activeFn=bind(this.__INPUT__,"click",e=>{var{options:t}=this.props;i.call(this),this.__OPTG__.classList.toggle("show")}),this._handleSelect=bind(this.__OPTG__,"click",e=>{"DD"!==e.target.tagName||e.target.hasAttribute("disabled")||(this._fetchSelect(+e.target.dataset.idx,!0),this.dispatchEvent(new CustomEvent("input")))}),this._inactiveFn=clickOutside(this,e=>{this.__OPTG__.classList.toggle("show",!1),this.props.active=!1})}attributeChangedCallback(e,t,i){if(null!==i&&t!==i)switch(e){case"label":case"placeholder":this.__INPUT__.setAttribute("placeholder",i);break;case"options":if(i){try{this._renderOptions(JSON.parse(i))}catch(e){}this.removeAttribute("options")}break;case"value":this.value=i;break;case"readonly":case"disabled":this[e]=!0}}disconnectedCallback(){unbind(this.__INPUT__,"keydown",this._handleKeydown),unbind(this.__INPUT__,"click",this._activeFn),unbind(document,"mousedown",this._inactiveFn),unbind(this.__OPTG__,"click",this._handleSelect)}}; if(!customElements.get('wc-select')){ customElements.define('wc-select', Select) diff --git a/src/lib/form/star.js b/src/lib/form/star.js new file mode 100644 index 0000000..d6bed42 --- /dev/null +++ b/src/lib/form/star.js @@ -0,0 +1,15 @@ +/** + * + * @authors yutent (yutent@doui.cc) + * @date 2019-09-27 11:36:21 + * @version v2.0.1 + * + */ + +'use strict' + +import{ebind,bind,unbind}from"../utils.js";export default class Star extends HTMLElement{static get observedAttributes(){return["value","text","size","color","allow-half","show-value","starSize","disabled"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{value:0,text:[],size:"",color:"","allow-half":!1,"show-value":!1,starSize:32,disabled:!1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML=' ',this.__BOX__=this.root.children[1],this.__STARS__=Array.from(this.__BOX__.children),this.__TEXT__=this.__STARS__.pop()}get value(){return this.props.value}set value(e){var t=+e;(e=t==t&&t>0?t:0)>5&&(e=5),this.props.value=e,this._updateDraw(-1)}_updateDraw(e,t=0){var s="star-half",{value:o,tmp:a={i:0,f:0}}=this.props;-1===e&&(e=Math.floor(o),t=+(o%1).toFixed(1),e>0&&e===o&&(e--,t=1)),this.props["allow-half"]||(t=t>0?1:0),e===a.i&&t===a.f||(t>.5&&(s="star-full"),this.__STARS__.forEach((t,s)=>{t.setAttribute("is",s0&&(this.__STARS__[e].setAttribute("is",s),this.__STARS__[e].setAttribute("color",this.props.color)),this.props.tmp={i:e,f:t},0===e&&0===t?this.__TEXT__.textContent="":5===this.props.text.length?this.__TEXT__.textContent=this.props.text[e]:this.props["show-value"]&&(this.__TEXT__.textContent=e+t))}connectedCallback(){ebind(this.__BOX__,"mousemove",e=>{if(!this.props.disabled&&"WC-ICON"===e.target.tagName){let t=+e.target.dataset.idx;this._updateDraw(t,+(e.offsetX/this.props.starSize).toFixed(1))}}),ebind(this.__BOX__,"click",e=>{var{tmp:t,disabled:s}=this.props;s||"WC-ICON"===e.target.tagName&&(this.props.value=t.i+t.f,this.dispatchEvent(new CustomEvent("input")))}),ebind(this.__BOX__,"mouseleave",e=>{this.props.disabled||this._updateDraw(-1)})}attributeChangedCallback(e,t,s){if(null!==s&&t!==s)switch(e){case"size":this.props.starSize=this.__STARS__[0].clientWidth;break;case"allow-half":case"show-value":case"disabled":this.props[e]=!0;break;case"color":s&&(this.props.color=s);break;case"text":s&&5===(s=s.split("|")).length&&(this.props.text=s.map(e=>e.trim()));break;case"value":this.value=s}}}; + +if(!customElements.get('wc-star')){ + customElements.define('wc-star', Star) +} diff --git a/src/lib/form/switch.js b/src/lib/form/switch.js index 418260d..3e43d7c 100644 --- a/src/lib/form/switch.js +++ b/src/lib/form/switch.js @@ -1,14 +1,14 @@ /** * * @authors yutent (yutent@doui.cc) - * @date 2019-09-16 20:52:26 + * @date 2019-09-27 11:36:21 * @version v2.0.1 * */ 'use strict' -import{bind,unbind}from"../utils.js";export default class Switch extends HTMLElement{static get observedAttributes(){return["checked","disabled"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{checked:!1,disabled:!1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="
      ",this.__SWITCH__=this.root.lastElementChild.firstElementChild}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 t=typeof e;e!==this.props.disabled&&("boolean"===t&&e||"boolean"!==t?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}connectedCallback(){this._handleClick=bind(this,"click",e=>{this.disabled||(this.checked=!this.checked,this.dispatchEvent(new CustomEvent("input")))})}disconnectedCallback(){unbind(this,"click",this._handleClick)}attributeChangedCallback(e,t,i){if(null!==i&&t!==i)switch(e){case"checked":case"disabled":this[e]=!0}}}; +import{bind,unbind}from"../utils.js";export default class Switch extends HTMLElement{static get observedAttributes(){return["active-text","inactive-text","checked","disabled"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{"active-text":null,"inactive-text":null,checked:!1,disabled:!1},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="
      ",this.__SWITCH__=this.root.lastElementChild.firstElementChild}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 t=typeof e;e!==this.props.disabled&&("boolean"===t&&e||"boolean"!==t?(this.props.disabled=!0,this.setAttribute("disabled","")):(this.props.disabled=!1,this.removeAttribute("disabled")))}connectedCallback(){this._handleClick=bind(this,"click",e=>{this.disabled||(this.checked=!this.checked,this.checked?null!==this.props["active-text"]&&(this.textContent=this.props["active-text"]):null!==this.props["inactive-text"]&&(this.textContent=this.props["inactive-text"]),this.dispatchEvent(new CustomEvent("input")))})}disconnectedCallback(){unbind(this,"click",this._handleClick)}attributeChangedCallback(e,t,i){if(null!==i&&t!==i)switch(e){case"checked":case"disabled":this[e]=!0;break;case"active-text":case"inactive-text":this.props[e]=i+""}}}; if(!customElements.get('wc-switch')){ customElements.define('wc-switch', Switch) diff --git a/src/lib/icon/index.js b/src/lib/icon/index.js index 3fbca35..5f25460 100644 --- a/src/lib/icon/index.js +++ b/src/lib/icon/index.js @@ -1,7 +1,7 @@ /** * * @authors yutent (yutent@doui.cc) - * @date 2019-09-16 20:52:26 + * @date 2019-09-27 11:36:21 * @version v2.0.1 * */ diff --git a/src/lib/layer/index.js b/src/lib/layer/index.js index dd20221..35c5348 100644 --- a/src/lib/layer/index.js +++ b/src/lib/layer/index.js @@ -1,14 +1,14 @@ /** * * @authors yutent (yutent@doui.cc) - * @date 2019-09-16 20:52:26 + * @date 2019-11-06 09:26:52 * @version v2.0.1 * */ 'use strict' -import"../form/input.js";import Drag from"../drag/core.js";import{nextTick,bind,unbind,clickOutside}from"../utils.js";const LANGUAGES={en:{TITLE:"Dialog",BTNS:["Cancel","OK"]},zh:{TITLE:"提示",BTNS:["取消","确定"]}};LANGUAGES["zh-CN"]=LANGUAGES.zh;const lang=LANGUAGES[window.__ENV_LANG__||navigator.language]||LANGUAGES.en;let uniqueInstance=null,toastInstance=null;const UNIQUE_TYPES=["alert","confirm","prompt"];function renderBtns(t){var e="";return t.forEach((t,s)=>{e+=``}),e}class Layer extends HTMLElement{static get observedAttributes(){return["left","right","top","bottom","from","to","btns","type","title","blur","background","mask","mask-close","mask-color","fixed"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{left:"auto",right:"auto",top:"auto",bottom:"auto",from:Object.create(null),to:Object.create(null),btns:[],type:"",title:"",blur:!1,background:null,mask:!1,"mask-close":!1,"mask-color":null,fixed:!0},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
      ',this.__TITLE__=this.root.children[1].firstElementChild,this.__BODY__=this.root.children[1].children[1],this.__CTRL__=this.root.children[1].lastElementChild,this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}set title(t){this.props.title=t,t?(this.__TITLE__.firstElementChild?this.__TITLE__.insertBefore(document.createTextNode(t),this.__TITLE__.firstElementChild):this.__TITLE__.textContent=t,this.__TITLE__.style.display="flex"):this.__TITLE__.style.display=""}set type(t){var{btns:e}=this.props;if(t&&!this._handleBtnClick){switch(t){case"alert":for(;e.length>1;)e.splice(0,1);break;case"confirm":case"prompt":for(;e.length>2;)e.splice(0,1);break;case"toast":case"notify":case"frame":if("notify"===t){var s=document.createElement("wc-icon");s.setAttribute("is","close"),this.__TITLE__.appendChild(s)}e=[];break;default:t="common"}this.props.type=t,e.length?(this.__CTRL__.innerHTML=renderBtns(e),this.__CTRL__.style.display="flex"):this.__CTRL__.style.display="",this.setAttribute(t,"")}}set fixed(t){this.props.fixed=!!t,this._updateFixedStat()}_updateFixedStat(){UNIQUE_TYPES.includes(this.props.type)||(this.props.fixed?this._dragIns&&(this._dragIns.destroy(),this._dragIns=null):(this._dragIns=new Drag(this.root.children[1]).by(this.__TITLE__,{overflow:!!this.props.hasOwnProperty("overflow")&&this.props.overflow}),this.removeAttribute("fixed")))}_intercept(t){this.props.intercept?this.props.intercept(t,e=>{delete this.props.intercept,this.resolve(t),this.close()}):(this.resolve(t),this.close())}close(t){if(!1===this.wrapped)if(this._dragIns&&this._dragIns.destroy(),UNIQUE_TYPES.includes(this.props.type)&&(uniqueInstance=null),delete this.promise,unbind(this.__CTRL__,"click",this._handleBtnClick),this.props.from&&!t){let t="opacity:0;";for(let e in this.props.from)t+=`${e}:${this.props.from[e]};`;this.root.children[1].style.cssText+=t,this.timer=setTimeout(()=>{this.parentNode.removeChild(this)},200)}else clearTimeout(this.timer),this.parentNode.removeChild(this);else this.removeAttribute("common")}show(){!1!==this.wrapped&&this.setAttribute("common","")}connectedCallback(){this.type=this.props.type,this.title=this.props.title,this._handleBtnClick=bind(this.__CTRL__,"click",t=>{if("BUTTON"===t.target.tagName){var e=+t.target.dataset.idx,{type:s}=this.props;switch(s){case"alert":this.resolve(),this.close();break;case"confirm":case"prompt":if(0===e)this.reject(),this.close();else{let t="prompt"===s?this.__INPUT__.value:null;this._intercept(t)}break;default:this._intercept(e)}}}),"prompt"===this.props.type&&(this.__INPUT__=this.__BODY__.firstElementChild.assignedNodes().pop(),this._handleSubmit=bind(this.__INPUT__,"submit",t=>{this._intercept(t.detail)})),this.props.mask&&this.setAttribute("mask",""),this._updateFixedStat(),this.props.mask&&(this._handlMask=clickOutside(this.root.children[1],t=>{this.props["mask-close"]?(!1===this.wrapped&&this.reject(null),this.close()):UNIQUE_TYPES.includes(this.props.type)&&(this.root.children[1].classList.toggle("scale",!0),setTimeout(t=>{this.root.children[1].classList.remove("scale")},100))}),this.props["mask-color"]&&(this.style.backgroundColor=this.props["mask-color"])),this.props.blur&&this.root.children[1].classList.toggle("blur",!0);let t=this.props.from?"":"opacity:1;";if(this.props.background&&(t+=`background: ${this.props.background};`),(this.props.radius||0===this.props.radius)&&(t+=`border-radius: ${this.props.radius};`),this.props.size)for(let e in this.props.size)t+=`${e}:${this.props.size[e]};`;if(this.props.from){for(let e in this.props.from)t+=`${e}:${this.props.from[e]};`;setTimeout(t=>{let e="opacity:1;";for(let t in this.props.to)e+=`${t}:${this.props.to[t]};`;this.root.children[1].style.cssText+=e},50)}t&&(this.root.children[1].style.cssText+=t),"toast"===this.props.type&&(this.timer=setTimeout(()=>{toastInstance=null,this.close()},3e3)),"notify"===this.props.type&&(this._handleClose=bind(this.__TITLE__,"click",t=>{"WC-ICON"===t.target.tagName&&this.close()}))}disconnectedCallback(){unbind(document,"mousedown",this._handlMask),unbind(this.__TITLE__,"click",this._handleClose)}attributeChangedCallback(t,e,s){if(null!==s&&e!==s)switch(t){case"title":case"type":this[t]=s;break;case"mask-color":case"background":this.props[t]=s;break;case"mask":case"mask-close":case"blur":this.props[t]=!0;break;case"left":case"right":case"top":case"bottom":null!==s&&(this.props.from[t]=s,this.props.to=this.props.from,this.removeAttribute(t));break;case"fixed":this.fixed=!0}}}function _layer(t){var e=document.createElement("wc-layer");if("toast"===t.type){var{type:s,content:o}=t;t={type:s,content:o,from:{top:0},to:{top:"30px"}},toastInstance&&toastInstance.close(!0),toastInstance=e}else e.props.mask=t.mask,!1===t.btns?e.props.btns=[]:t.btns&&t.btns.length?e.props.btns=t.btns:e.props.btns=lang.BTNS.concat(),t.intercept&&"function"==typeof t.intercept&&(e.props.intercept=t.intercept),e.props.mask=t.mask,e.props["mask-close"]=t["mask-close"],t.hasOwnProperty("overflow")&&(e.props.overflow=t.overflow),e.props["mask-color"]=t["mask-color"],e.props.blur=t.blur,e.props.radius=t.radius,e.props.background=t.background,t.size&&"object"==typeof t.size&&(e.props.size=t.size),UNIQUE_TYPES.includes(t.type)&&(uniqueInstance&&uniqueInstance.close(!0),uniqueInstance=e);return t.to&&"object"==typeof t.to&&(e.props.to=t.to,t.from&&"object"==typeof t.from?e.props.from=t.from:e.props.from=t.to),e.props.type=t.type,e.props.fixed=t.fixed,e.props.title=t.title,e.innerHTML=t.content,e.wrapped=!1,document.body.appendChild(e),e.promise}Object.assign(_layer,{alert(t,e=lang.TITLE){return this({type:"alert",title:e,content:t,mask:!0})},confirm(t,e=lang.TITLE,s){return"function"==typeof e&&(s=e,e=lang.TITLE),this({type:"confirm",title:e,content:t,mask:!0,intercept:s})},prompt(t=lang.TITLE,e){return this({type:"prompt",title:t,content:'',mask:!0,intercept:e})},frame(t,e={}){return this({...e,type:"frame",content:``,mask:!0,"mask-close":!0})},notify(t){return this({type:"notify",title:"通知",content:t,blur:!0,from:{right:"-300px",top:0},to:{right:0}})},toast(t,e="info"){switch(e){case"info":case"warn":case"error":break;default:e="info"}return this({content:`\n
      \n \n ${t}\n
      `,type:"toast"})}}),window.layer=_layer;export default _layer; +import"../form/input.js";import Drag from"../drag/core.js";import{nextTick,bind,unbind,clickOutside}from"../utils.js";const LANGUAGES={en:{TITLE:"Dialog",BTNS:["Cancel","OK"]},zh:{TITLE:"提示",BTNS:["取消","确定"]}};LANGUAGES["zh-CN"]=LANGUAGES.zh;const lang=LANGUAGES[window.__ENV_LANG__||navigator.language]||LANGUAGES.en;let uniqueInstance=null,toastInstance=null;const UNIQUE_TYPES=["alert","confirm","prompt"];function renderBtns(t){var e="";return t.forEach((t,s)=>{e+=``}),e}class Layer extends HTMLElement{static get observedAttributes(){return["left","right","top","bottom","from","to","btns","type","title","blur","background","mask","mask-close","mask-color","fixed"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{left:"auto",right:"auto",top:"auto",bottom:"auto",from:Object.create(null),to:Object.create(null),btns:[],type:"",title:"",blur:!1,background:null,mask:!1,"mask-close":!1,"mask-color":null,fixed:!0},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
      ',this.__TITLE__=this.root.children[1].firstElementChild,this.__BODY__=this.root.children[1].children[1],this.__CTRL__=this.root.children[1].lastElementChild,this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}set title(t){this.props.title=t,t?(this.__TITLE__.firstElementChild?this.__TITLE__.insertBefore(document.createTextNode(t),this.__TITLE__.firstElementChild):this.__TITLE__.textContent=t,this.__TITLE__.style.display="flex"):this.__TITLE__.style.display=""}set type(t){var{btns:e}=this.props;if(t&&!this._handleBtnClick){switch(t){case"alert":for(;e.length>1;)e.splice(0,1);break;case"confirm":case"prompt":for(;e.length>2;)e.splice(0,1);break;case"toast":case"notify":case"frame":if("notify"===t){var s=document.createElement("wc-icon");s.setAttribute("is","close"),this.__TITLE__.appendChild(s)}e=[];break;default:t="common"}this.props.type=t,e.length?(this.__CTRL__.innerHTML=renderBtns(e),this.__CTRL__.style.display="flex"):this.__CTRL__.style.display="",this.setAttribute(t,"")}}set fixed(t){this.props.fixed=!!t,this._updateFixedStat()}_updateFixedStat(){UNIQUE_TYPES.includes(this.props.type)||(this.props.fixed?this._dragIns&&(this._dragIns.destroy(),this._dragIns=null):(this._dragIns=new Drag(this.root.children[1]).by(this.__TITLE__,{overflow:!!this.props.hasOwnProperty("overflow")&&this.props.overflow}),this.removeAttribute("fixed")))}_intercept(t){this.props.intercept?this.props.intercept(t,e=>{delete this.props.intercept,this.resolve(t),this.close()}):(this.resolve(t),this.close())}close(t){if(!1===this.wrapped)if(this._dragIns&&this._dragIns.destroy(),UNIQUE_TYPES.includes(this.props.type)&&(uniqueInstance=null),delete this.promise,unbind(this.__CTRL__,"click",this._handleBtnClick),this.props.from&&!t){let t="opacity:0;";for(let e in this.props.from)t+=`${e}:${this.props.from[e]};`;this.root.children[1].style.cssText+=t,this.timer=setTimeout(()=>{this.parentNode.removeChild(this),this.dispatchEvent(new CustomEvent("close"))},200)}else clearTimeout(this.timer),this.parentNode.removeChild(this),this.dispatchEvent(new CustomEvent("close"));else this.removeAttribute("common"),this.dispatchEvent(new CustomEvent("close"))}show(){!1!==this.wrapped&&this.setAttribute("common","")}connectedCallback(){this.type=this.props.type,this.title=this.props.title,this._handleBtnClick=bind(this.__CTRL__,"click",t=>{if("BUTTON"===t.target.tagName){var e=+t.target.dataset.idx,{type:s}=this.props;switch(s){case"alert":this.resolve(),this.close();break;case"confirm":case"prompt":if(0===e)this.reject(),this.close();else{let t="prompt"===s?this.__INPUT__.value:null;this._intercept(t)}break;default:this._intercept(e)}}}),"prompt"===this.props.type&&(this.__INPUT__=this.__BODY__.firstElementChild.assignedNodes().pop(),this._handleSubmit=bind(this.__INPUT__,"submit",t=>{this._intercept(t.detail)})),this.props.mask&&this.setAttribute("mask",""),this._updateFixedStat(),this.props.mask&&(this._handlMask=clickOutside(this.root.children[1],t=>{t.target===this&&(this.props["mask-close"]?(!1===this.wrapped&&this.reject(null),this.close()):UNIQUE_TYPES.includes(this.props.type)&&(this.root.children[1].classList.toggle("scale",!0),setTimeout(t=>{this.root.children[1].classList.remove("scale")},100)))}),this.props["mask-color"]&&(this.style.backgroundColor=this.props["mask-color"])),this.props.blur&&this.root.children[1].classList.toggle("blur",!0);let t=this.props.from?"":"opacity:1;";if(this.props.background&&(t+=`background: ${this.props.background};`),(this.props.radius||0===this.props.radius)&&(t+=`border-radius: ${this.props.radius};`),this.props.size)for(let e in this.props.size)t+=`${e}:${this.props.size[e]};`;if(this.props.from){for(let e in this.props.from)t+=`${e}:${this.props.from[e]};`;setTimeout(t=>{let e="opacity:1;";for(let t in this.props.to)e+=`${t}:${this.props.to[t]};`;this.root.children[1].style.cssText+=e},50)}t&&(this.root.children[1].style.cssText+=t),"toast"===this.props.type&&(this.timer=setTimeout(()=>{toastInstance=null,this.close()},3e3)),"notify"===this.props.type&&(this._handleClose=bind(this.__TITLE__,"click",t=>{"WC-ICON"===t.target.tagName&&this.close()}))}disconnectedCallback(){unbind(document,"mousedown",this._handlMask),unbind(this.__TITLE__,"click",this._handleClose)}attributeChangedCallback(t,e,s){if(null!==s&&e!==s)switch(t){case"title":case"type":this[t]=s;break;case"mask-color":case"background":this.props[t]=s;break;case"mask":case"mask-close":case"blur":this.props[t]=!0;break;case"left":case"right":case"top":case"bottom":null!==s&&(this.props.from[t]=s,this.props.to=this.props.from,this.removeAttribute(t));break;case"fixed":this.fixed=!0}}}function _layer(t){var e=document.createElement("wc-layer");if(t.type||(t.type="common"),"toast"===t.type){var{type:s,content:o}=t;t={type:s,content:o,from:{top:0},to:{top:"30px"}},toastInstance&&toastInstance.close(!0),toastInstance=e}else e.props.mask=t.mask,!1===t.btns?e.props.btns=[]:t.btns&&t.btns.length?e.props.btns=t.btns:e.props.btns=lang.BTNS.concat(),t.intercept&&"function"==typeof t.intercept&&(e.props.intercept=t.intercept),e.props.mask=t.mask,e.props["mask-close"]=t["mask-close"],t.hasOwnProperty("overflow")&&(e.props.overflow=t.overflow),e.props["mask-color"]=t["mask-color"],e.props.blur=t.blur,e.props.radius=t.radius,e.props.background=t.background,t.size&&"object"==typeof t.size&&(e.props.size=t.size),UNIQUE_TYPES.includes(t.type)&&(uniqueInstance&&uniqueInstance.close(!0),uniqueInstance=e);return t.to&&"object"==typeof t.to&&(e.props.to=t.to,t.from&&"object"==typeof t.from?e.props.from=t.from:e.props.from=t.to),e.props.type=t.type,e.props.title=t.title,t.hasOwnProperty("fixed")&&(e.props.fixed=t.fixed),e.innerHTML=t.content,e.wrapped=!1,document.body.appendChild(e),e.promise}Object.assign(_layer,{alert(t,e=lang.TITLE){return this({type:"alert",title:e,content:t,mask:!0})},confirm(t,e=lang.TITLE,s){return"function"==typeof e&&(s=e,e=lang.TITLE),this({type:"confirm",title:e,content:t,mask:!0,intercept:s})},prompt(t=lang.TITLE,e){return this({type:"prompt",title:t,content:'',mask:!0,intercept:e})},frame(t,e={}){return this({...e,type:"frame",content:``,mask:!0,"mask-close":!0})},notify(t){return this({type:"notify",title:"通知",content:t,blur:!0,from:{right:"-300px",top:0},to:{right:0}})},toast(t,e="info"){switch(e){case"info":case"warn":case"error":break;default:e="info"}return this({content:`\n
      \n \n ${t}\n
      `,type:"toast"})}}),window.layer=_layer;export default _layer; if(!customElements.get('wc-layer')){ customElements.define('wc-layer', Layer) diff --git a/src/lib/scroll/index.js b/src/lib/scroll/index.js index f25f74d..679b938 100644 --- a/src/lib/scroll/index.js +++ b/src/lib/scroll/index.js @@ -1,14 +1,14 @@ /** * * @authors yutent (yutent@doui.cc) - * @date 2019-09-16 20:52:26 + * @date 2019-09-27 11:36:21 * @version v2.0.1 * */ 'use strict' -import{bind,ebind,unbind}from"../utils.js";const IS_FF=!!window.sidebar;export default class Scroll extends HTMLElement{static get observedAttributes(){return[]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
      ',this.__BOX__=this.root.children[1],this.__X__=this.root.children[2].children[0],this.__Y__=this.root.children[3].children[0]}get scrollTop(){return this.__BOX__.scrollTop}set scrollTop(t){if((t=+t)==t){var{sh:s,oh:i,yh:e}=this.props;this.__BOX__.scrollTop=t;var o=this.__BOX__.scrollTop/(s-i)*(i-e);this.props.thumbY=o,this.__Y__.style.transform=`translateY(${o}px)`}}get scrollLeft(){return this.__BOX__.scrollLeft}set scrollLeft(t){if(n=+n,n==n){var{sw:s,ow:i,xw:e}=this.props;this.__BOX__.scrollLeft=n;var o=this.__BOX__.scrollLeft/(s-i)*(i-e);this.props.thumbX=o,this.__X__.style.transform=`translateX(${o}px)`}}get scrollHeight(){return this.__BOX__.scrollHeight}_fetchScrollX(t){var{sw:s,ow:i,xw:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollLeft=t/(i-e)*(s-i),this.__X__.style.transform=`translateX(${t}px)`,t}_fetchScrollY(t){var{sh:s,oh:i,yh:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollTop=t/(i-e)*(s-i),this.__Y__.style.transform=`translateY(${t}px)`,t}connectedCallback(){this._initFn=bind(this.__BOX__,"mouseenter",t=>{var s=this.__BOX__.offsetWidth,i=this.__BOX__.scrollWidth,e=this.__BOX__.offsetHeight,o=this.__BOX__.scrollHeight,r=e*e/o>>0,h=s*s/i>>0;r<50&&(r=50),h<50&&(h=50),h===s&&(h=0),r===e&&(r=0),this.props.oh=e,this.props.sh=o,this.props.ow=s,this.props.sw=i,this.props.yh=r,this.props.xw=h,this.__X__.style.width=h+"px",this.__Y__.style.height=r+"px"}),this._wheelFn=ebind(this.__BOX__,"wheel",t=>{t.preventDefault();var{sh:s,oh:i,yh:e,sw:o,ow:r,xw:h}=this.props;if(h||e){var l,_;if(IS_FF)l=t.deltaMode?10*t.deltaX:t.deltaX,_=t.deltaMode?10*t.deltaY:t.deltaY;else{var n=Math.abs(t.wheelDelta);n<120?(l=t.deltaX,_=t.deltaY):(l=t.deltaX/(n/120),_=t.deltaY/(n/120))}if(this.__BOX__.scrollTop+=_,this.__BOX__.scrollLeft+=l,h){var a=this.__BOX__.scrollLeft/(o-r)*(r-h);this.props.thumbX=a,this.__X__.style.transform=`translateX(${a}px)`}if(e){var p=this.__BOX__.scrollTop/(s-i)*(i-e);this.props.thumbY=p,this.__Y__.style.transform=`translateY(${p}px)`}}});var t,s,i,e,o=o=>{var{thumbY:r,thumbX:h}=this.props;null!==t&&(i=this._fetchScrollX(h+o.pageX-t)),null!==s&&(e=this._fetchScrollY(r+o.pageY-s))},r=h=>{t=null,s=null,this.props.thumbX=i,this.props.thumbY=e,unbind(document,"mousemove",o),unbind(document,"mouseup",r)};bind(this.__Y__,"mousedown",t=>{s=t.pageY,this.props.thumbY||(this.props.thumbY=0),bind(document,"mousemove",o),bind(document,"mouseup",r)}),bind(this.__X__,"mousedown",s=>{t=s.pageX,this.props.thumbX||(this.props.thumbX=0),bind(document,"mousemove",o),bind(document,"mouseup",r)})}disconnectedCallback(){unbind(this.__BOX__,"mouseenter",this._initFn),unbind(this.__BOX__,"wheel",this._wheelFn)}}; +import{bind,ebind,unbind}from"../utils.js";const IS_FF=!!window.sidebar;export default class Scroll extends HTMLElement{static get observedAttributes(){return[]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{},writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='
      ',this.__BOX__=this.root.children[1],this.__X__=this.root.children[2].children[0],this.__Y__=this.root.children[3].children[0]}get scrollTop(){return this.__BOX__.scrollTop}set scrollTop(t){if((t=+t)==t){var{sh:s,oh:i,yh:e}=this.props;this.__BOX__.scrollTop=t;var o=this.__BOX__.scrollTop/(s-i)*(i-e);this.props.thumbY=o,this.__Y__.style.transform=`translateY(${o}px)`}}get scrollLeft(){return this.__BOX__.scrollLeft}set scrollLeft(t){if(n=+n,n==n){var{sw:s,ow:i,xw:e}=this.props;this.__BOX__.scrollLeft=n;var o=this.__BOX__.scrollLeft/(s-i)*(i-e);this.props.thumbX=o,this.__X__.style.transform=`translateX(${o}px)`}}get scrollHeight(){return this.__BOX__.scrollHeight}_fetchScrollX(t){var{sw:s,ow:i,xw:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollLeft=t/(i-e)*(s-i),this.__X__.style.transform=`translateX(${t}px)`,t}_fetchScrollY(t){var{sh:s,oh:i,yh:e}=this.props;return t<0?t=0:t>i-e&&(t=i-e),this.__BOX__.scrollTop=t/(i-e)*(s-i),this.__Y__.style.transform=`translateY(${t}px)`,t}connectedCallback(){this._initFn=bind(this.__BOX__,"mouseenter",t=>{var s=this.__BOX__.offsetWidth,i=this.__BOX__.scrollWidth,e=this.__BOX__.offsetHeight,o=this.__BOX__.scrollHeight,r=e*e/o>>0,h=s*s/i>>0;r<50&&(r=50),h<50&&(h=50),h===s&&(h=0),r===e&&(r=0),this.props.oh=e,this.props.sh=o,this.props.ow=s,this.props.sw=i,this.props.yh=r,this.props.xw=h,this.__X__.style.width=h+"px",this.__Y__.style.height=r+"px"}),this._wheelFn=ebind(this.__BOX__,"wheel",t=>{t.preventDefault();var{sh:s,oh:i,yh:e,sw:o,ow:r,xw:h}=this.props;if(h||e){var _,l;if(IS_FF)_=t.deltaMode?10*t.deltaX:t.deltaX,l=t.deltaMode?10*t.deltaY:t.deltaY;else{var n=Math.abs(t.wheelDelta);n<120?(_=t.deltaX,l=t.deltaY):(_=t.deltaX/(n/120),l=t.deltaY/(n/120))}if(this.__BOX__.scrollTop+=l,this.__BOX__.scrollLeft+=_,h){var a=this.__BOX__.scrollLeft/(o-r)*(r-h);this.props.thumbX=a,this.__X__.style.transform=`translateX(${a}px)`}if(e){var p=this.__BOX__.scrollTop/(s-i)*(i-e);this.props.thumbY=p,this.__Y__.style.transform=`translateY(${p}px)`}}});var t,s,i,e,o=o=>{var{thumbY:r,thumbX:h}=this.props;null!==t&&(i=this._fetchScrollX(h+o.pageX-t)),null!==s&&(e=this._fetchScrollY(r+o.pageY-s))},r=h=>{t=null,s=null,this.props.thumbX=i,this.props.thumbY=e,unbind(document,"mousemove",o),unbind(document,"mouseup",r)};bind(this.__Y__,"mousedown",t=>{s=t.pageY,this.props.thumbY||(this.props.thumbY=0),bind(document,"mousemove",o),bind(document,"mouseup",r)}),bind(this.__X__,"mousedown",s=>{t=s.pageX,this.props.thumbX||(this.props.thumbX=0),bind(document,"mousemove",o),bind(document,"mouseup",r)}),this.__observer=new MutationObserver(this._initFn),this.__observer.observe(this,{childList:!0,subtree:!0,characterData:!0})}disconnectedCallback(){this.__observer.disconnect(),unbind(this.__BOX__,"mouseenter",this._initFn),unbind(this.__BOX__,"wheel",this._wheelFn)}}; if(!customElements.get('wc-scroll')){ customElements.define('wc-scroll', Scroll) diff --git a/src/main.js b/src/main.js index 672d595..186d86d 100644 --- a/src/main.js +++ b/src/main.js @@ -4,4 +4,74 @@ * @date 2019/09/16 20:51:19 */ -const { app } = require('electron') +const { app, BrowserWindow, protocol, Menu } = require('electron') +const path = require('path') +const fs = require('iofs') +require('./tools/init') +const createMenu = require('./tools/menu') +const log = console.log +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 + +/* ----------------------------------------------------- */ +app.commandLine.appendSwitch('--lang', 'zh-CN') +app.commandLine.appendSwitch('--autoplay-policy', 'no-user-gesture-required') + +protocol.registerSchemesAsPrivileged([ + { scheme: 'app', privileges: { secure: true, standard: true } } +]) + +/* ----------------------------------------------------- */ + +// 初始化应用 +app.once('ready', () => { + // 注册协议 + protocol.registerBufferProtocol('app', (req, cb) => { + let file = req.url.replace(/^app:\/\/local\//, '') + let ext = path.extname(req.url) + let buff = fs.cat(path.resolve(ROOT, file)) + cb({ data: buff, mimeType: MIME_TYPES[ext] }) + }) + + Menu.setApplicationMenu(null) + + // 创建浏览器窗口 + let win = new BrowserWindow({ + title: '伪域名解析', + width: 1000, + height: 640, + resizable: false, + maximizable: false, + icon: path.resolve(ROOT, './images/app.png'), + webPreferences: { + webSecurity: false, + experimentalFeatures: true, + nodeIntegration: true + } + }) + + win.on('closed', () => { + app.exit() + win = null + }) + + win.openDevTools() + + // 然后加载应用的 index.html + win.loadURL('app://local/index.html') + + if (process.platform === 'darwin') { + createMenu(win) + } +}) diff --git a/src/tools/init.js b/src/tools/init.js new file mode 100644 index 0000000..cb7ca5c --- /dev/null +++ b/src/tools/init.js @@ -0,0 +1,77 @@ +/** + * 配置/DB通讯 + * @author yutent + * @date 2019/01/26 18:11:26 + */ + +'use strict' + +const { app, ipcMain } = require('electron') +const fs = require('iofs') +const path = require('path') + +const HOST_FILE = path.resolve(app.getPath('userData'), 'host.cache') + +if (!fs.exists(HOST_FILE)) { + fs.echo('{}', HOST_FILE) +} + +/* ********** 修复环境变量 start *********** */ +let PATH_SET = new Set() +process.env.PATH.split(':').forEach(_ => { + PATH_SET.add(_) +}) +PATH_SET.add('/usr/local/bin') +PATH_SET.add('/usr/local/sbin') + +process.env.PATH = Array.from(PATH_SET).join(':') +PATH_SET = null + +/* ********** 修复环境变量 end *********** */ + +var timer = null + +ipcMain.on('dns-host', (ev, conn) => { + switch (conn.type) { + // 获取指定目录下的文件和目录 + case 'get': + var cache = fs.cat(HOST_FILE) + ev.returnValue = JSON.parse(cache) + break + // 设置应用配置 + case 'set': + clearTimeout(timer) + timer = setTimeout(() => { + fs.echo(JSON.stringify(conn.data), HOST_FILE) + }, 2000) + break + + case 'check': + try { + var stat = fs.echo('', '/etc/hosts', true) + ev.returnValue = true + } catch (e) { + ev.returnValue = false + } + break + + case 'history': + var cache = fs.cat('/etc/hosts').toString() + var records = cache.split(/[\n\r]+/) + var list = [] + var dict = {} + var tmp = {} + records.forEach(str => { + str = str.trim() + if (/^(#*?)\s*(\d+\.\d+\.\d+\.\d+)\s+(.*)/.test(str)) { + list.push({ + ip: RegExp.$2, + domains: RegExp.$3, + enabled: !RegExp.$1 + }) + } + }) + records = null + list.forEach(it => {}) + } +}) diff --git a/src/tools/menu.js b/src/tools/menu.js new file mode 100644 index 0000000..869262c --- /dev/null +++ b/src/tools/menu.js @@ -0,0 +1,67 @@ +/** + * 菜单项 + * @author yutent + * @date 2019/01/21 20:34:04 + */ + +'use strict' + +const { Menu } = require('electron') + +module.exports = function(win) { + let menuList = Menu.buildFromTemplate([ + { + label: '伪域名解析', + submenu: [ + { role: 'about', label: '关于 伪域名解析' }, + { 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: '伪域名解析' }, + { + type: 'separator' + }, + { label: '伪域名解析' } + ] + }, + { + label: '窗口', + submenu: [ + { + role: 'minimize', + label: '最小化', + click() { + win.minimize() + } + } + ] + }, + { + role: 'help', + label: '帮助', + submenu: [ + { + label: '官网', + click() {} + } + ] + } + ]) + Menu.setApplicationMenu(menuList) +}