Compare commits
No commits in common. "48536d29e8f56fc580db5545a84f8a8a02a5311c" and "5435bc6482f00bcec1cee883eab03d2323825191" have entirely different histories.
48536d29e8
...
5435bc6482
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "org.bytedo.epub",
|
||||
"version": "1.2.1",
|
||||
"version": "2.1.2",
|
||||
"description": "E-pub Reader",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -1 +1 @@
|
|||
html{width:100%;height:100vh}body{overflow:hidden;display:flex;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app{position:relative;display:flex;width:100%;height:100%}.app .category{width:200px;height:100%;background:#fff}.app .category .item{display:flex;justify-content:space-between;align-items:center;height:54px;padding:8px;border-bottom:1px solid var(--color-plain-1);background:#fff;transition:background 0.2s ease-in-out, color 0.2s ease-in-out;cursor:pointer}.app .category .item strong{max-width:150px}.app .category .item .num{display:flex;justify-content:center;align-items:center;min-width:16px;height:16px;padding:2px;line-height:1;border-radius:50%;font-size:12px;background:var(--color-grey-1);color:#fff}.app .category .item:last-child{border-bottom:0}.app .category .item:hover{color:var(--color-blue-1);background:var(--color-plain-1)}.app .category .item.active{color:var(--color-plain-1);background:var(--color-blue-1)}.app .category .item.active .num{background:#fff;color:var(--color-blue-1)}.app .books-scroll{flex:1;height:100%;border-left:1px solid var(--color-plain-2)}.app .books{display:flex;flex-wrap:wrap}.app .books .book{display:flex;flex-direction:column;width:128px;margin:24px;background:#fff;box-shadow:0 0 12px rgba(0,0,0,0.15);transition:box-shadow 0.1s ease-in;cursor:pointer}.app .books .book img{width:100%;height:160px;-o-object-fit:fill;object-fit:fill}.app .books .book:hover{box-shadow:0 0 12px rgba(0,0,0,0.35)}.app .drag-mask{display:flex;align-items:center;position:fixed;left:0;top:0;z-index:9999;width:100%;height:100%;background:linear-gradient(to right, transparent, transparent 200px, rgba(252,232,207,0.6) 200px)}.app .drag-mask::after{font-size:46px;text-indent:360px;content:'Drop epub file here...';color:var(--color-grey-1)}.app .book-loading{display:flex;align-items:center;justify-content:center;position:fixed;left:0;top:0;z-index:9999;width:100%;height:100%;font-size:20px;background:rgba(255,255,255,0.01);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.app .book-loading .loading{display:flex;flex-direction:column;align-items:center;justify-content:center}.app .book-loading .loading::before{content:'🌑';font-size:36px;-webkit-animation:loading 1s infinite;animation:loading 1s infinite}.app .context-menu{display:flex;flex-direction:column;width:100px;padding:5px 0;background:#fff}.app .context-menu .item{height:30px;line-height:30px;padding:0 15px;cursor:pointer}.app .context-menu .item:hover{background:#f2f5fc}.app .context-menu .item.diabled{color:var(--color-plain-2);background:#fff;cursor:default}@-webkit-keyframes loading{1%,100%{content:'🌑'}12.5%{content:'🌒'}25%{content:'🌓'}37.5%{content:'🌔'}50%{content:'🌕'}62.5%{content:'🌖'}75%{content:'🌗'}87.5%{content:'🌘'}}@keyframes loading{1%,100%{content:'🌑'}12.5%{content:'🌒'}25%{content:'🌓'}37.5%{content:'🌔'}50%{content:'🌕'}62.5%{content:'🌖'}75%{content:'🌗'}87.5%{content:'🌘'}}
|
||||
html{font-size:12.8px;width:100%;height:100vh}body{overflow:hidden;display:flex;flex-direction:column;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app-drag{-webkit-app-region:drag;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.app-nodrag{-webkit-app-region:no-drag}.app{position:relative;display:flex;height:100%}.app .category{width:200px;height:100%;background:#fff}.app .category .item{display:flex;justify-content:space-between;align-items:center;height:54px;padding:8px;border-bottom:1px solid var(--color-plain-1);background:#fff;transition:background 0.2s ease-in-out, color 0.2s ease-in-out;cursor:pointer}.app .category .item strong{max-width:150px}.app .category .item .num{display:flex;justify-content:center;align-items:center;min-width:16px;height:16px;padding:2px;line-height:1;border-radius:50%;font-size:12px;background:var(--color-grey-1);color:#fff}.app .category .item:last-child{border-bottom:0}.app .category .item:hover{color:var(--color-blue-1);background:var(--color-plain-1)}.app .category .item.active{color:var(--color-plain-1);background:var(--color-blue-1)}.app .category .item.active .num{background:#fff;color:var(--color-blue-1)}.app .detail{position:relative;flex:1;height:100%;border-left:1px solid var(--color-plain-2);background:rgba(255,255,255,0.5)}.app .detail .title{display:flex;justify-content:space-between;align-items:center;width:100%;height:35px;padding:0 16px;font-size:16px;font-weight:bold}.app .detail .title span{display:inline-flex}.app .detail .title wc-button{margin:0 6px}.app .detail .card{width:96%;padding:12px 12px 16px;margin:12px 2% 24px;border:0;background:#fff;box-shadow:0 0 8px rgba(0,0,0,0.075)}.app .detail .card legend{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#64b5f6}.app .drag-mask{display:flex;align-items:center;position:fixed;left:0;top:0;z-index:9999;width:100%;height:100%;background:linear-gradient(to right, transparent, transparent 200px, #fff3e3 200px)}.app .drag-mask::after{font-size:46px;text-indent:300px;content:'Drop epub file here...';color:var(--color-grey-1)}.app .book-loading{display:flex;align-items:center;justify-content:center;position:fixed;left:0;top:0;z-index:9999;width:100%;height:100%;font-size:20px;background:rgba(255,255,255,0.01);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.app .book-loading .loading{display:flex;flex-direction:column;align-items:center;justify-content:center}.app .book-loading .loading::before{content:'🌑';font-size:36px;-webkit-animation:loading 1s infinite;animation:loading 1s infinite}@-webkit-keyframes loading{1%,100%{content:'🌑'}12.5%{content:'🌒'}25%{content:'🌓'}37.5%{content:'🌔'}50%{content:'🌕'}62.5%{content:'🌖'}75%{content:'🌗'}87.5%{content:'🌘'}}@keyframes loading{1%,100%{content:'🌑'}12.5%{content:'🌒'}25%{content:'🌓'}37.5%{content:'🌔'}50%{content:'🌕'}62.5%{content:'🌖'}75%{content:'🌗'}87.5%{content:'🌘'}}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
html {
|
||||
font-size: 12.8px;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
@ -13,6 +14,7 @@ html {
|
|||
body {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 1.25;
|
||||
|
@ -21,10 +23,17 @@ body {
|
|||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.app-drag {
|
||||
-webkit-app-region: drag;
|
||||
user-select: none;
|
||||
}
|
||||
.app-nodrag {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.app {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.category {
|
||||
|
@ -81,34 +90,43 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.books-scroll {
|
||||
.detail {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border-left: 1px solid var(--color-plain-2);
|
||||
}
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
|
||||
.books {
|
||||
.title {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.book {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 128px;
|
||||
margin: 24px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 12px rgba(0, 0, 0, 0.15);
|
||||
transition: box-shadow 0.1s ease-in;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
object-fit: fill;
|
||||
height: 35px;
|
||||
padding: 0 16px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
|
||||
span {
|
||||
display: inline-flex;
|
||||
}
|
||||
wc-button {
|
||||
margin: 0 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0 12px rgba(0, 0, 0, 0.35);
|
||||
.card {
|
||||
width: 96%;
|
||||
padding: 12px 12px 16px;
|
||||
margin: 12px 2% 24px;
|
||||
border: 0;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.075);
|
||||
|
||||
legend {
|
||||
-webkit-touch-callout: none;
|
||||
user-select: none;
|
||||
color: #64b5f6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,12 +144,12 @@ body {
|
|||
to right,
|
||||
transparent,
|
||||
transparent 200px,
|
||||
rgba(252, 232, 207, 0.6) 200px
|
||||
#fff3e3 200px
|
||||
);
|
||||
|
||||
&::after {
|
||||
font-size: 46px;
|
||||
text-indent: 360px;
|
||||
text-indent: 300px;
|
||||
content: 'Drop epub file here...';
|
||||
color: var(--color-grey-1);
|
||||
}
|
||||
|
@ -164,31 +182,6 @@ body {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100px;
|
||||
padding: 5px 0;
|
||||
background: #fff;
|
||||
|
||||
.item {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 15px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: #f2f5fc;
|
||||
}
|
||||
|
||||
&.diabled {
|
||||
color: var(--color-plain-2);
|
||||
background: #fff;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
html{font-size:12.8px;width:100%;height:100vh}body{display:flex;flex-direction:column;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app-drag{-webkit-app-region:drag;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.app-nodrag{-webkit-app-region:no-drag}.app{position:relative;display:flex;flex-direction:column;height:100%;padding:6px 0}.app .list{flex:1}.app .list .item{display:flex;align-items:center;height:54px;padding:10px 12px;line-height:15px;border-bottom:1px solid rgba(155,155,155,0.3)}.app .list .item:last-child{border-bottom:0}.app .list .item .info{overflow:hidden;flex:1}.app .list .item .info h3{font-size:14px}.app .list .item .info cite{color:var(--color-grey-2)}.app .list .item .last-days{display:flex;width:64px;height:30px;margin:0 6px}.app .list .item .today{width:52px;font-size:12px;text-align:right}.app .list .item .today span{display:block;padding:0 4px}.app .list .item .today .percent{border-radius:2px;color:#fff}.app .list .item .today .percent.red{background:var(--color-red-1)}.app .list .item .today .percent.green{background:var(--color-green-3)}
|
|
@ -0,0 +1,97 @@
|
|||
@charset "UTF-8";
|
||||
/**
|
||||
* 浮窗样式
|
||||
* @authors yutent<yutent@doui.cc>
|
||||
* @date 2018/12/16 17:15:07
|
||||
*/
|
||||
|
||||
html {
|
||||
font-size: 12.8px;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 1.25;
|
||||
font-size: 14px;
|
||||
color: var(--color-dark-1);
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.app-drag {
|
||||
-webkit-app-region: drag;
|
||||
user-select: none;
|
||||
}
|
||||
.app-nodrag {
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.app {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 6px 0;
|
||||
|
||||
.list {
|
||||
flex: 1;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 54px;
|
||||
padding: 10px 12px;
|
||||
line-height: 15px;
|
||||
border-bottom: 1px solid rgba(155, 155, 155, 0.3);
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.info {
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
}
|
||||
cite {
|
||||
color: var(--color-grey-2);
|
||||
}
|
||||
}
|
||||
|
||||
.last-days {
|
||||
display: flex;
|
||||
width: 64px;
|
||||
height: 30px;
|
||||
margin: 0 6px;
|
||||
}
|
||||
|
||||
.today {
|
||||
width: 52px;
|
||||
font-size: 12px;
|
||||
text-align: right;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
padding: 0 4px;
|
||||
}
|
||||
.percent {
|
||||
border-radius: 2px;
|
||||
color: #fff;
|
||||
|
||||
&.red {
|
||||
background: var(--color-red-1);
|
||||
}
|
||||
&.green {
|
||||
background: var(--color-green-3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
html{width:100%;height:100vh}body{display:flex;width:100%;height:100%;line-height:1.25;font-size:14px;color:var(--color-dark-1);background:rgba(255,255,255,0.3)}.app{position:relative;display:flex;width:100%;height:100%}.app .toc{width:260px;height:100%}.app .toc item{display:flex;align-items:center;height:36px;padding:0 12px;border-bottom:1px solid var(--color-plain-1);cursor:pointer}.app .toc item.lev-0{font-weight:bold}.app .toc item.lev-1{padding-left:24px;font-weight:bold}.app .toc item.lev-2{padding-left:36px}.app .toc item.lev-3{padding-left:48px}.app .toc item:hover{color:var(--color-blue-1)}.app .toc item.active{color:#fff;background:var(--color-blue-1)}.app .toc item:last-child{border-bottom:0}.app .chapter-box{flex:1;height:100%;border-left:1px solid var(--color-plain-2)}.app .chapter{display:flex;justify-content:center;padding:8px 24px}.app .chapter .detail{width:768px;line-height:1.5;font-size:14px}.app .chapter .detail .cover{display:block;width:100%;height:calc(100vh - 16px);-o-object-fit:contain;object-fit:contain}.app .chapter .detail a{text-decoration:underline;color:var(--color-teal-2)}.app .chapter .detail a:hover{color:var(--color-teal-1);text-decoration:none}.app .chapter .detail em,.app .chapter .detail del{color:var(--color-grey-2)}.app .chapter .detail strong,.app .chapter .detail strong em,.app .chapter .detail strong{color:var(--color-dark-3)}.app .chapter .detail a strong,.app .chapter .detail a em{color:inherit}.app .chapter .detail em,.app .chapter .detail strong,.app .chapter .detail del{padding:0 2px}.app .chapter .detail img{max-width:100%}.app .chapter .detail blockquote{margin:10px 0;padding:5px 10px;line-height:1.5;border-left:5px solid var(--color-teal-1);background:#f2faf7;color:var(--color-grey-2)}.app .chapter .detail blockquote p{margin:0}.app .chapter .detail code{display:inline;margin:0 2px;padding:0 2px;color:var(--color-orange-3);background:var(--color-plain-1);border-radius:2px;font-family:Menlo, Monaco, Consolas, 'Courier New', monospace}.app .chapter .detail>p{margin:12px 0}.app .chapter .detail ol{margin-left:1em;list-style:decimal outside none}.app .chapter .detail ul{margin-left:1em;list-style:disc outside none}.app .chapter .detail li{margin:0.5em 0}.app .chapter .detail li ol{margin-left:1em}.app .chapter .detail li ul{margin-left:1em;list-style-type:circle}.app .chapter .detail li ol ul,.app .chapter .detail li ul ul{list-style-type:square}.app .chapter .detail h1,.app .chapter .detail h2,.app .chapter .detail h3,.app .chapter .detail h4,.app .chapter .detail h5,.app .chapter .detail h6{margin:15px 0;line-height:2;font-weight:bold;font-size:16px}.app .chapter .detail h1 code,.app .chapter .detail h2 code,.app .chapter .detail h3 code,.app .chapter .detail h4 code,.app .chapter .detail h5 code,.app .chapter .detail h6 code{background:none}.app .chapter .detail h1 a,.app .chapter .detail h2 a,.app .chapter .detail h3 a,.app .chapter .detail h4 a,.app .chapter .detail h5 a,.app .chapter .detail h6 a{text-decoration:none;color:#333}.app .chapter .detail h3 a::before,.app .chapter .detail h4 a::before,.app .chapter .detail h5 a::before,.app .chapter .detail h6 a::before{content:'∮ ';color:var(--color-teal-1);font-weight:normal}.app .chapter .detail h1{margin:0 0 30px;font-size:24px;text-align:center}.app .chapter .detail h2{margin:20px 0;font-size:22px;border-bottom:1px solid var(--color-plain-2)}.app .chapter .detail h3{margin:20px 0 15px;font-size:20px}.app .chapter .detail h4{font-size:18px}.app .chapter .detail table{width:100%;border-spacing:0;border-collapse:collapse}.app .chapter .detail table tr{background-color:#fff}.app .chapter .detail table thead tr{background:var(--color-plain-1)}.app .chapter .detail table th,.app .chapter .detail table td{padding:6px 13px;border:1px solid var(--color-plain-2)}.app .chapter .detail table th{font-weight:bold}.app .chapter .detail table tr:nth-child(2n){background-color:#fcfdff}
|
|
@ -1,250 +0,0 @@
|
|||
@charset "UTF-8";
|
||||
/**
|
||||
* 阅读样式
|
||||
* @authors yutent<yutent@doui.cc>
|
||||
* @date 2018/12/16 17:15:07
|
||||
*/
|
||||
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 1.25;
|
||||
font-size: 14px;
|
||||
color: var(--color-dark-1);
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.app {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.toc {
|
||||
width: 260px;
|
||||
height: 100%;
|
||||
|
||||
item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 36px;
|
||||
padding: 0 12px;
|
||||
border-bottom: 1px solid var(--color-plain-1);
|
||||
cursor: pointer;
|
||||
|
||||
&.lev-0 {
|
||||
font-weight: bold;
|
||||
}
|
||||
&.lev-1 {
|
||||
padding-left: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
&.lev-2 {
|
||||
padding-left: 36px;
|
||||
}
|
||||
&.lev-3 {
|
||||
padding-left: 48px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: var(--color-blue-1);
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #fff;
|
||||
background: var(--color-blue-1);
|
||||
}
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chapter-box {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
border-left: 1px solid var(--color-plain-2);
|
||||
}
|
||||
|
||||
.chapter {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 8px 24px;
|
||||
|
||||
.detail {
|
||||
width: 768px;
|
||||
line-height: 1.5;
|
||||
font-size: 14px;
|
||||
|
||||
.cover {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: calc(100vh - 16px);
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: var(--color-teal-2);
|
||||
}
|
||||
a:hover {
|
||||
color: var(--color-teal-1);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
em,
|
||||
del {
|
||||
color: var(--color-grey-2);
|
||||
}
|
||||
strong,
|
||||
strong em,
|
||||
strong {
|
||||
color: var(--color-dark-3);
|
||||
}
|
||||
a {
|
||||
strong,
|
||||
em {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
em,
|
||||
strong,
|
||||
del {
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 10px 0;
|
||||
padding: 5px 10px;
|
||||
line-height: 1.5;
|
||||
border-left: 5px solid var(--color-teal-1);
|
||||
background: #f2faf7;
|
||||
color: var(--color-grey-2);
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
code {
|
||||
display: inline;
|
||||
margin: 0 2px;
|
||||
padding: 0 2px;
|
||||
color: var(--color-orange-3);
|
||||
background: var(--color-plain-1);
|
||||
border-radius: 2px;
|
||||
font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
|
||||
}
|
||||
|
||||
> p {
|
||||
margin: 12px 0;
|
||||
// text-indent: 2em;
|
||||
}
|
||||
|
||||
ol {
|
||||
margin-left: 1em;
|
||||
list-style: decimal outside none;
|
||||
}
|
||||
ul {
|
||||
margin-left: 1em;
|
||||
list-style: disc outside none;
|
||||
}
|
||||
li {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
li ol {
|
||||
margin-left: 1em;
|
||||
}
|
||||
li ul {
|
||||
margin-left: 1em;
|
||||
list-style-type: circle;
|
||||
}
|
||||
li ol ul,
|
||||
li ul ul {
|
||||
list-style-type: square;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin: 15px 0;
|
||||
line-height: 2;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
|
||||
code {
|
||||
background: none;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
a {
|
||||
&::before {
|
||||
content: '∮ ';
|
||||
color: var(--color-teal-1);
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
h1 {
|
||||
margin: 0 0 30px;
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
h2 {
|
||||
margin: 20px 0;
|
||||
font-size: 22px;
|
||||
border-bottom: 1px solid var(--color-plain-2);
|
||||
}
|
||||
h3 {
|
||||
margin: 20px 0 15px;
|
||||
font-size: 20px;
|
||||
}
|
||||
h4 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
|
||||
tr {
|
||||
background-color: #fff;
|
||||
}
|
||||
thead tr {
|
||||
background: var(--color-plain-1);
|
||||
}
|
||||
th,
|
||||
td {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid var(--color-plain-2);
|
||||
}
|
||||
th {
|
||||
font-weight: bold;
|
||||
}
|
||||
tr:nth-child(2n) {
|
||||
background-color: #fcfdff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,8 +16,6 @@
|
|||
<wc-scroll class="category">
|
||||
<item
|
||||
class="item"
|
||||
@contextmenu="pickCtx1(it, $event)"
|
||||
@click="view(it)"
|
||||
:class="{active: curr === it.name}"
|
||||
:for="it in cates">
|
||||
<strong :text="it.name"></strong>
|
||||
|
@ -27,49 +25,26 @@
|
|||
|
||||
|
||||
|
||||
<div class="detail" :class="{blur: !curr.code}">
|
||||
|
||||
<wc-scroll class="books-scroll">
|
||||
<list class="books">
|
||||
<book
|
||||
class="book"
|
||||
:for="it in books"
|
||||
@dblclick="read(it)"
|
||||
@contextmenu="pickCtx2(it, $event)"
|
||||
>
|
||||
<img
|
||||
:attr-alt="it.title"
|
||||
:src="it.c ? it.c : 'book://cache/' + it.title + '/' + it.cover"
|
||||
>
|
||||
<book :for="it in books">
|
||||
<img :src="'book://cache/' + it.title + '/' + it.cover">
|
||||
{{it.title}}
|
||||
</book>
|
||||
</list>
|
||||
</wc-scroll>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="drag-mask" ref="mask" :visible="isDragIn"></div>
|
||||
|
||||
<div class="book-loading" :visible="loading">
|
||||
<div class="book-loading" ref="books" :visible="loading">
|
||||
<div class="loading">
|
||||
<span>共 {{load.num}} 本书</span>
|
||||
<span>当前正在解析第 {{load.curr}} 本</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<wc-layer ref="ctx1" left="100px" top="0" radius="0">
|
||||
<ul class="context-menu noselect">
|
||||
<li class="item" @click="deleteCate">删除</li>
|
||||
<li class="item" @click="renameCate">重命名</li>
|
||||
<li class="item" @click="createCate">新建分类</li>
|
||||
</ul>
|
||||
</wc-layer>
|
||||
|
||||
<wc-layer ref="ctx2" left="100px" top="0" radius="0">
|
||||
<ul class="context-menu noselect">
|
||||
<li class="item" @click="deleteBook">删除</li>
|
||||
<li class="item diabled">移动到</li>
|
||||
</ul>
|
||||
</wc-layer>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
|
274
src/js/app.js
274
src/js/app.js
|
@ -7,11 +7,14 @@
|
|||
*/
|
||||
|
||||
import '/lib/anot.js'
|
||||
import '/lib/form/button.js'
|
||||
import '/lib/form/switch.js'
|
||||
import '/lib/scroll/index.js'
|
||||
import '/lib/chart/rank.js'
|
||||
import '/lib/chart/line.js'
|
||||
|
||||
import '/lib/layer/index.js'
|
||||
import layer from '/lib/layer/index.js'
|
||||
import Utils from '/lib/utils.js'
|
||||
import { md5 } from '/lib/md5.js'
|
||||
|
||||
import app from '/lib/socket.js'
|
||||
|
||||
|
@ -27,30 +30,21 @@ Anot({
|
|||
state: {
|
||||
input: '',
|
||||
curr: '默认分类',
|
||||
cates: [],
|
||||
cates: [{ name: '默认分类', num: 12 }],
|
||||
books: [],
|
||||
loading: false,
|
||||
isDragIn: false,
|
||||
load: {
|
||||
num: 0,
|
||||
curr: 0
|
||||
}
|
||||
},
|
||||
$db: {},
|
||||
$ctx1: null,
|
||||
$ctx2: null
|
||||
},
|
||||
|
||||
watch: {},
|
||||
|
||||
mounted() {
|
||||
Utils.outside(this.$refs.ctx1, ev => {
|
||||
this.$refs.ctx1.close()
|
||||
})
|
||||
|
||||
Utils.outside(this.$refs.ctx2, ev => {
|
||||
this.$refs.ctx2.close()
|
||||
})
|
||||
|
||||
/* --------------------- */
|
||||
$doc.bind('dragover', ev => {
|
||||
ev.stopPropagation()
|
||||
ev.preventDefault()
|
||||
|
||||
this.isDragIn = true
|
||||
|
@ -61,9 +55,10 @@ Anot({
|
|||
this.isDragIn = false
|
||||
})
|
||||
|
||||
$doc.bind('drop', async ev => {
|
||||
$doc.bind('drop', ev => {
|
||||
ev.stopPropagation()
|
||||
ev.preventDefault()
|
||||
|
||||
// clearTimeout(this.timer)
|
||||
this.isDragIn = false
|
||||
|
||||
let files = Array.from(ev.dataTransfer.files)
|
||||
|
@ -78,255 +73,20 @@ Anot({
|
|||
this.load.curr = 0
|
||||
this.loading = true
|
||||
|
||||
console.time(1)
|
||||
while (this.load.curr < this.load.num) {
|
||||
this.load.curr++
|
||||
let book = files.pop()
|
||||
let res = app.dispatch('parse-book', { book, cate: this.curr })
|
||||
|
||||
await sleep(500)
|
||||
|
||||
console.log(res)
|
||||
if (res) {
|
||||
this.books.push(res)
|
||||
}
|
||||
}
|
||||
console.timeEnd(1)
|
||||
|
||||
for (let it of this.cates) {
|
||||
if (it.name === this.curr) {
|
||||
it.num = this.books.length
|
||||
break
|
||||
}
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
|
||||
/* --------------------- */
|
||||
|
||||
let db = app.dispatch('get-books')
|
||||
let cates = [],
|
||||
books
|
||||
|
||||
if (Object.keys(db).length < 1) {
|
||||
db = { 默认分类: [] }
|
||||
}
|
||||
|
||||
for (let k in db) {
|
||||
cates.push({ name: k, num: db[k].length })
|
||||
// 默认选中第一个
|
||||
if (!books) {
|
||||
this.curr = k
|
||||
books = db[k]
|
||||
}
|
||||
}
|
||||
|
||||
this.$db = db
|
||||
this.cates = cates
|
||||
this.books = books || []
|
||||
|
||||
app.on('draw-cover', title => {
|
||||
this.drawCover(title)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
view(item) {
|
||||
this.books = this.$db[item.name]
|
||||
},
|
||||
read(item) {
|
||||
var params = { title: item.title }
|
||||
var readCache = Anot.ls(md5(item.title))
|
||||
|
||||
if (readCache) {
|
||||
params.chapter = readCache
|
||||
}
|
||||
|
||||
app.dispatch(
|
||||
'read',
|
||||
Buffer.from(JSON.stringify(params)).toString('base64')
|
||||
)
|
||||
},
|
||||
|
||||
pickCtx1(item, ev) {
|
||||
this.$ctx1 = item
|
||||
ev.stopPropagation()
|
||||
|
||||
let { pageX, pageY } = ev
|
||||
if (pageY + 70 > 600) {
|
||||
pageY -= 70
|
||||
}
|
||||
|
||||
this.$refs.ctx1.close()
|
||||
|
||||
Anot.nextTick(_ => {
|
||||
this.$refs.ctx1.moveTo({ left: pageX + 'px', top: pageY + 'px' })
|
||||
this.$refs.ctx1.show()
|
||||
})
|
||||
},
|
||||
|
||||
pickCtx2(item, ev) {
|
||||
this.$ctx2 = item
|
||||
|
||||
ev.stopPropagation()
|
||||
|
||||
let { pageX, pageY } = ev
|
||||
if (pageY + 70 > 600) {
|
||||
pageY -= 70
|
||||
}
|
||||
|
||||
this.$refs.ctx2.close()
|
||||
|
||||
Anot.nextTick(_ => {
|
||||
this.$refs.ctx2.moveTo({ left: pageX + 'px', top: pageY + 'px' })
|
||||
this.$refs.ctx2.show()
|
||||
})
|
||||
},
|
||||
|
||||
saveDB() {
|
||||
app.dispatch('save-books', Anot.deepCopy(this.$db))
|
||||
},
|
||||
|
||||
drawCover(name) {
|
||||
var canvas = document.createElement('canvas')
|
||||
var ctx = canvas.getContext('2d')
|
||||
var tmp = name.split('').map(s => (/[\w\s\(\)]/.test(s) ? 1 : 2))
|
||||
|
||||
canvas.width = 128
|
||||
canvas.height = 160
|
||||
|
||||
ctx.fillStyle =
|
||||
'#' +
|
||||
Buffer.from(name)
|
||||
.toString('hex')
|
||||
.slice(-6)
|
||||
|
||||
ctx.fillRect(0, 0, 128, 160)
|
||||
|
||||
ctx.fillStyle = '#fff'
|
||||
ctx.font = '14px menlo,Hiragino Sans GB'
|
||||
ctx.textAlign = 'center'
|
||||
|
||||
let row = 0
|
||||
let last = 0
|
||||
tmp.reduce((sum, c, i) => {
|
||||
sum += c
|
||||
|
||||
if (sum >= 14 && row === 0) {
|
||||
ctx.fillText(name.slice(0, i + 1), 64, 60, 100)
|
||||
last = i
|
||||
row = 1
|
||||
} else if (sum >= 28 && row === 1) {
|
||||
ctx.fillText(name.slice(last, i + 1), 64, 60 + row * 26, 100)
|
||||
row = 2
|
||||
last = i
|
||||
} else if (sum >= 42 && row === 2) {
|
||||
ctx.fillText(name.slice(last, i + 1), 64, 60 + row * 26, 100)
|
||||
}
|
||||
return sum
|
||||
}, 0)
|
||||
|
||||
if (last === 0) {
|
||||
ctx.fillText(name, 64, 76, 100)
|
||||
} else {
|
||||
if (last < tmp.length) {
|
||||
ctx.fillText(name.slice(last + 1), 64, 60 + row * 26, 100)
|
||||
}
|
||||
}
|
||||
let base64 = canvas.toDataURL('image/webp', 1).split(',')[1]
|
||||
app.dispatch('save-cover', { base64, name })
|
||||
},
|
||||
|
||||
deleteCate() {
|
||||
//
|
||||
this.$refs.ctx1.close()
|
||||
if (this.$ctx1) {
|
||||
let { name, num } = this.$ctx1
|
||||
|
||||
if (num > 0) {
|
||||
return layer.toast(`${name} 下有书籍, 不可删除!`, 'error')
|
||||
}
|
||||
delete this.$db[name]
|
||||
this.cates.remove(this.$ctx1)
|
||||
this.saveDB()
|
||||
}
|
||||
},
|
||||
|
||||
createCate() {
|
||||
this.$ctx1 = null
|
||||
this.$refs.ctx1.close()
|
||||
|
||||
layer
|
||||
.prompt('请输入分类名', (val, done) => {
|
||||
if (val.trim()) {
|
||||
if (this.$db[val.trim()]) {
|
||||
return layer.toast('分类已存在, 请换个名字', 'error')
|
||||
}
|
||||
done()
|
||||
}
|
||||
})
|
||||
.then(v => {
|
||||
v = v.trim()
|
||||
this.$db[v] = []
|
||||
this.cates.push({ name: v, num: 0 })
|
||||
this.saveDB()
|
||||
})
|
||||
.catch(Anot.noop)
|
||||
},
|
||||
|
||||
renameCate() {
|
||||
//
|
||||
this.$refs.ctx1.close()
|
||||
if (this.$ctx1) {
|
||||
let { name } = this.$ctx1
|
||||
|
||||
layer
|
||||
.prompt(`请输入新的分类名(${name})`, (val, done) => {
|
||||
val = val.trim()
|
||||
if (val) {
|
||||
if (this.$db[val] || val === name) {
|
||||
return layer.toast('分类已存在, 请换个名字', 'error')
|
||||
}
|
||||
done()
|
||||
}
|
||||
})
|
||||
.then(v => {
|
||||
v = v.trim()
|
||||
this.$db[v] = this.$db[name]
|
||||
delete this.$db[name]
|
||||
this.$ctx1.name = v
|
||||
this.$ctx1 = null
|
||||
this.saveDB()
|
||||
})
|
||||
.catch(Anot.noop)
|
||||
}
|
||||
},
|
||||
|
||||
deleteBook() {
|
||||
this.$refs.ctx2.close()
|
||||
if (this.$ctx2) {
|
||||
let { title } = this.$ctx2
|
||||
layer
|
||||
.confirm(`是否要删除[${title}]? 该操作不可逆!`)
|
||||
.then(r => {
|
||||
this.books.remove(this.$ctx2)
|
||||
this.$db[this.curr] = this.books
|
||||
|
||||
for (let it of this.cates) {
|
||||
if (it.name === this.curr) {
|
||||
it.num = this.books.length
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
this.saveDB()
|
||||
app.dispatch('delete-book', title)
|
||||
})
|
||||
.catch(Anot.noop)
|
||||
}
|
||||
}
|
||||
|
||||
// moveBook() {
|
||||
// this.$refs.ctx2.close()
|
||||
// if (this.$ctx2) {
|
||||
// let { title } = this.$ctx2
|
||||
// }
|
||||
// }
|
||||
}
|
||||
methods: {}
|
||||
})
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
*
|
||||
* @author yutent<yutent.io@gmail.com>
|
||||
* @date 2020/12/10 19:53:05
|
||||
*/
|
||||
|
||||
import '/lib/anot.js'
|
||||
|
||||
import '/lib/scroll/index.js'
|
||||
import layer from '/lib/layer/index.js'
|
||||
import app from '/lib/socket.js'
|
||||
|
||||
function getJsonp(str) {
|
||||
if (~str.indexOf('jsonpgz')) {
|
||||
return new Function(`function jsonpgz(d){return d}; return ${str}`)()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Anot({
|
||||
$id: 'app',
|
||||
state: {
|
||||
list: []
|
||||
},
|
||||
mounted() {
|
||||
this.reloadGays()
|
||||
|
||||
app.on('float-visible', data => {
|
||||
var time = +Anot.ss('last_update') || 0
|
||||
var now = Date.now()
|
||||
|
||||
// 有触发小窗口显示时, 更新通知提醒
|
||||
if (Anot.ls('notify') === '1') {
|
||||
app.dispatch('notify')
|
||||
}
|
||||
|
||||
this.reloadGays()
|
||||
setTimeout(() => {
|
||||
// 如果离上次更新超过15分钟, 则自动更新
|
||||
if (now - time > 15 * 60 * 1000) {
|
||||
this.updateGays()
|
||||
Anot.ss('last_update', now)
|
||||
}
|
||||
}, 500)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
reloadGays() {
|
||||
var gays = Anot.ls('gays') || '{}'
|
||||
var list = []
|
||||
|
||||
gays = JSON.parse(gays)
|
||||
|
||||
for (let code in gays) {
|
||||
let { name, cm, cp, t } = gays[code]
|
||||
list.push({ code, name, cm, cp, t })
|
||||
}
|
||||
list.sort((a, b) => b.cp - a.cp)
|
||||
|
||||
this.list = list
|
||||
},
|
||||
|
||||
getGayStat(id) {
|
||||
var res = app.dispatch(
|
||||
'fetch',
|
||||
`https://fundgz.1234567.com.cn/js/${id}.js`
|
||||
)
|
||||
return getJsonp(res)
|
||||
},
|
||||
|
||||
updateGay(item) {
|
||||
var info = this.getGayStat(item.code)
|
||||
item.cm = +info.gsz
|
||||
item.cp = +info.gszzl
|
||||
},
|
||||
|
||||
updateGays() {
|
||||
for (let it of this.list) {
|
||||
this.updateGay(it)
|
||||
}
|
||||
this.list.sort((a, b) => b.cp - a.cp)
|
||||
this.saveCache()
|
||||
app.dispatch('data-reload')
|
||||
},
|
||||
saveCache() {
|
||||
var dict = {}
|
||||
for (let it of this.list) {
|
||||
var { code, name, cm, cp, t } = it
|
||||
dict[code] = { name, cm, cp, t }
|
||||
}
|
||||
Anot.ls('gays', dict)
|
||||
}
|
||||
}
|
||||
})
|
116
src/js/view.js
116
src/js/view.js
|
@ -1,116 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* @author yutent<yutent.io@gmail.com>
|
||||
* @date 2020/12/10 19:53:05
|
||||
*/
|
||||
|
||||
import '/lib/anot.js'
|
||||
|
||||
import '/lib/scroll/index.js'
|
||||
import '/lib/code/index.js'
|
||||
import { md5 } from '/lib/md5.js'
|
||||
import fetch from '/lib/fetch/index.js'
|
||||
import app from '/lib/socket.js'
|
||||
|
||||
const { dirname, join } = require('path')
|
||||
|
||||
Anot({
|
||||
$id: 'app',
|
||||
state: {
|
||||
toc: [],
|
||||
book: '', // 当前阅读的书名
|
||||
curr: '', // 当前选中的章节名
|
||||
file: '', // 章节所属的文件名
|
||||
chapter: '' // 章节渲染html文本
|
||||
},
|
||||
mounted() {
|
||||
var search = location.search
|
||||
|
||||
if (search) {
|
||||
search = JSON.parse(Buffer.from(search.slice(1), 'base64'))
|
||||
|
||||
document.title = this.book = search.title
|
||||
this.curr = search.chapter || ''
|
||||
|
||||
this.getToc()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getToc() {
|
||||
fetch(`book://cache/${this.book}/toc.json`)
|
||||
.then(r => r.json())
|
||||
.then(list => {
|
||||
let chapter, idx
|
||||
for (let i = -1, it; (it = list[++i]); ) {
|
||||
delete it.id
|
||||
delete it.order
|
||||
|
||||
it.href = it.href.replace('.xhtml', '.html')
|
||||
|
||||
if (it.title === this.curr) {
|
||||
chapter = it
|
||||
idx = i
|
||||
}
|
||||
}
|
||||
|
||||
if (!chapter) {
|
||||
chapter = list[0]
|
||||
idx = 0
|
||||
}
|
||||
|
||||
this.toc = list
|
||||
this.viewChapter(chapter)
|
||||
|
||||
setTimeout(() => {
|
||||
this.$refs.toc.scrollTop = 36 * (idx - 10)
|
||||
}, 100)
|
||||
})
|
||||
},
|
||||
|
||||
viewChapter(item) {
|
||||
let pathes = item.href.split('#')
|
||||
let file = pathes.shift()
|
||||
let hash = pathes.shift()
|
||||
|
||||
this.curr = item.title
|
||||
|
||||
Anot.ls(md5(this.book), item.title)
|
||||
|
||||
if (this.file === file) {
|
||||
if (hash) {
|
||||
location.hash = hash
|
||||
} else {
|
||||
location.hash = ''
|
||||
this.$refs.chapter.scrollTop = 0
|
||||
}
|
||||
} else {
|
||||
this.file = file
|
||||
fetch(`book://cache/${this.book}/${file}`)
|
||||
.then(r => r.text())
|
||||
.then(txt => {
|
||||
this.chapter = txt
|
||||
.replace(/<img[^>]*?src="(.*?)"[^>]*?\/?>/g, (m, s1) => {
|
||||
s1 = join(dirname(file), s1)
|
||||
return `<img src="book://cache/${this.book}/${s1}">`
|
||||
})
|
||||
.replace(/<image[^>]*?xlink:href="(.*?)"[^>]*?\/?>/g, (m, s1) => {
|
||||
s1 = join(dirname(file), s1)
|
||||
return `<img class="cover" src="book://cache/${
|
||||
this.book
|
||||
}/${s1}">`
|
||||
})
|
||||
.replace(/<\/?svg>/g, '')
|
||||
|
||||
setTimeout(() => {
|
||||
if (hash) {
|
||||
location.hash = hash
|
||||
} else {
|
||||
location.hash = ''
|
||||
this.$refs.chapter.scrollTop = 0
|
||||
}
|
||||
}, 100)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,253 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
import $ from '../utils.js'
|
||||
import '../form/button.js'
|
||||
|
||||
const DARK = '#62778d'
|
||||
const BLUE = '#64b5f6'
|
||||
const PLAIN = '#f2f5fc'
|
||||
|
||||
export default class Line extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ['list']
|
||||
}
|
||||
|
||||
props = {
|
||||
list: []
|
||||
}
|
||||
|
||||
state = {
|
||||
key: 1,
|
||||
list: []
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
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: flex;
|
||||
width: 680px; }
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
padding: 24px 0 0; }
|
||||
|
||||
canvas {
|
||||
width: 680px;
|
||||
height: 230px; }
|
||||
|
||||
section {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0; }
|
||||
</style>
|
||||
<div class="container">
|
||||
<canvas></canvas>
|
||||
<section>
|
||||
<wc-button color="blue" data-key="1" size="mini">1月</wc-button>
|
||||
<wc-button data-key="3" size="mini">3月</wc-button>
|
||||
<wc-button data-key="6" size="mini">半年</wc-button>
|
||||
<wc-button data-key="12" size="mini">1年</wc-button>
|
||||
<wc-button data-key="36" size="mini">3年</wc-button>
|
||||
<wc-button data-key="999" size="mini">所有</wc-button>
|
||||
</section>
|
||||
</div>
|
||||
`
|
||||
|
||||
var elem = this.root.children[1]
|
||||
this.__SCENE__ = elem.firstElementChild
|
||||
this.__FILTER__ = elem.lastElementChild
|
||||
this.__CTX__ = this.__SCENE__.getContext('2d')
|
||||
this.__SCENE__.width = 680
|
||||
this.__SCENE__.height = 230
|
||||
}
|
||||
|
||||
_getTime(n) {
|
||||
var now = new Date()
|
||||
var time = { getTime: _ => 0 }
|
||||
var Y = now.getFullYear()
|
||||
var m = now.getMonth()
|
||||
var d = now.getDate()
|
||||
|
||||
switch (n) {
|
||||
case 1:
|
||||
time = new Date(Y, m - 1, d, 0, 0, 0)
|
||||
break
|
||||
case 3:
|
||||
time = new Date(Y, m - 3, d, 0, 0, 0)
|
||||
break
|
||||
case 6:
|
||||
time = new Date(Y, m - 6, d, 0, 0, 0)
|
||||
break
|
||||
case 12:
|
||||
time = new Date(Y - 1, m, d, 0, 0, 0)
|
||||
break
|
||||
case 36:
|
||||
time = new Date(Y - 3, m, d, 0, 0, 0)
|
||||
break
|
||||
}
|
||||
return time.getTime()
|
||||
}
|
||||
|
||||
_filter(n) {
|
||||
if (n < 999) {
|
||||
var time = this._getTime(n)
|
||||
this.state.list = this.props.list.filter(it => it.x >= time)
|
||||
} else {
|
||||
this.state.list = this.props.list.concat()
|
||||
}
|
||||
}
|
||||
|
||||
draw() {
|
||||
var { list, key } = this.state
|
||||
var ctx = this.__CTX__
|
||||
var x = 36
|
||||
var max = 0
|
||||
var min = Number.MAX_SAFE_INTEGER
|
||||
var step = 0 // 纵坐标间隔
|
||||
var dis = +(640 / list.length).toFixed(2) || 1 // 横坐标间隔
|
||||
var point
|
||||
var p1, p2, p3, p4
|
||||
var format = key > 12 ? 'Y/m' : 'm/d'
|
||||
|
||||
for (let it of list) {
|
||||
if (max < it.y) {
|
||||
max = it.y
|
||||
}
|
||||
if (min > it.y) {
|
||||
min = it.y
|
||||
}
|
||||
}
|
||||
|
||||
min = ~~(min / 100)
|
||||
max = Math.ceil(max / 100)
|
||||
step = ~~((max - min) / 3)
|
||||
|
||||
p1 = Math.floor(list.length / 4)
|
||||
p2 = Math.floor(list.length / 2)
|
||||
p3 = Math.floor((list.length * 3) / 4)
|
||||
p4 = list.length - 1
|
||||
|
||||
ctx.clearRect(0, 0, 680, 230)
|
||||
|
||||
// 纵坐标数值
|
||||
ctx.font = '12px Arial'
|
||||
ctx.textAlign = 'right'
|
||||
ctx.fillStyle = DARK
|
||||
ctx.fillText(min / 100, 32, 205)
|
||||
ctx.fillText((min + step) / 100, 32, 155)
|
||||
ctx.fillText((min + step + step) / 100, 32, 105)
|
||||
ctx.fillText((min + step + step + step) / 100, 32, 55)
|
||||
|
||||
ctx.font = '10px Arial'
|
||||
ctx.textAlign = 'left'
|
||||
ctx.fillText(new Date(list[0].x).format(format), x - 12, 225)
|
||||
ctx.fillText(new Date(list[p1].x).format(format), x + dis * p1 - 12, 225)
|
||||
ctx.fillText(new Date(list[p2].x).format(format), x + dis * p2 - 12, 225)
|
||||
ctx.fillText(new Date(list[p3].x).format(format), x + dis * p3 - 12, 225)
|
||||
ctx.fillText(
|
||||
new Date(list[p4].x).format(format),
|
||||
x + dis * p4 - 12 - (key > 12 ? 24 : 4),
|
||||
225
|
||||
)
|
||||
|
||||
// x轴参考线
|
||||
ctx.fillStyle = PLAIN
|
||||
ctx.fillRect(x, 50, 648, 1)
|
||||
ctx.fillRect(x, 100, 648, 1)
|
||||
ctx.fillRect(x, 150, 648, 1)
|
||||
ctx.fillRect(x, 200, 648, 1)
|
||||
|
||||
// y轴参考 线
|
||||
ctx.fillRect(x, 0, 1, 210)
|
||||
ctx.fillRect(x + dis * p1, 0, 1, 210)
|
||||
ctx.fillRect(x + dis * p2, 0, 1, 210)
|
||||
ctx.fillRect(x + dis * p3, 0, 1, 210)
|
||||
ctx.fillRect(x + dis * p4, 0, 1, 210)
|
||||
|
||||
point = list.shift()
|
||||
|
||||
// 曲线
|
||||
ctx.beginPath()
|
||||
ctx.strokeStyle = BLUE
|
||||
ctx.lineWidth = 1
|
||||
ctx.moveTo(x, 200 - (((point.y / 100 - min) / step) * 50).toFixed(0))
|
||||
|
||||
while (list.length) {
|
||||
let y
|
||||
|
||||
point = list.shift()
|
||||
|
||||
y = 200 - (((point.y / 100 - min) / step) * 50).toFixed(0)
|
||||
x += dis
|
||||
|
||||
ctx.lineTo(x, y)
|
||||
}
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
$.bind(this.__FILTER__, 'click', ev => {
|
||||
var el = ev.target
|
||||
if (this.props.list.length < 1) {
|
||||
return
|
||||
}
|
||||
if (el.tagName === 'WC-BUTTON') {
|
||||
var k = +el.dataset.key
|
||||
|
||||
$.each(this.__FILTER__.children, function(it) {
|
||||
it.removeAttribute('color')
|
||||
})
|
||||
el.setAttribute('color', 'blue')
|
||||
|
||||
this.state.key = k
|
||||
this._filter(k)
|
||||
this.draw()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {
|
||||
return
|
||||
}
|
||||
switch (name) {
|
||||
case 'list':
|
||||
try {
|
||||
var list = JSON.parse(val)
|
||||
list.forEach(it => (it.x = it.x * 1000))
|
||||
this.props.list = list
|
||||
this._filter(this.state.key)
|
||||
this.removeAttribute('list')
|
||||
this.draw()
|
||||
} catch (e) {}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!customElements.get('wc-line')) {
|
||||
customElements.define('wc-line', Line)
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
const RED = '#ff5061'
|
||||
const GREEN = '#4caf50'
|
||||
const BLUE = '#64b5f6'
|
||||
const GREY = '#bdbdbd'
|
||||
const PLAIN = '#f2f5fc'
|
||||
const DARK = '#62778d'
|
||||
|
||||
export default class Rank extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ['stat']
|
||||
}
|
||||
|
||||
props = {
|
||||
stat: {}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
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: flex; }
|
||||
|
||||
canvas {
|
||||
width: 680px;
|
||||
height: 100px; }
|
||||
</style>
|
||||
<canvas></canvas>
|
||||
`
|
||||
|
||||
this.__SCENE__ = this.root.children[1]
|
||||
this.__CTX__ = this.__SCENE__.getContext('2d')
|
||||
this.__SCENE__.width = 680
|
||||
this.__SCENE__.height = 100
|
||||
}
|
||||
|
||||
draw() {
|
||||
var { rank, e1, e3, e6, e12, cm, cp } = this.props.stat
|
||||
var ctx = this.__CTX__
|
||||
var x = 32
|
||||
|
||||
while (rank.length < 60) {
|
||||
rank.unshift(0)
|
||||
}
|
||||
|
||||
ctx.clearRect(0, 0, 680, 101)
|
||||
|
||||
ctx.font = '10px Arial'
|
||||
ctx.textAlign = 'right'
|
||||
ctx.fillStyle = RED
|
||||
ctx.fillText('10%', 28, 10)
|
||||
ctx.fillText('5%', 28, 30)
|
||||
ctx.fillStyle = GREEN
|
||||
ctx.fillText('-5%', 28, 80)
|
||||
ctx.fillText('-10%', 28, 100)
|
||||
|
||||
ctx.font = '10px menlo,Hiragino Sans GB'
|
||||
ctx.textAlign = 'left'
|
||||
ctx.fillStyle = DARK
|
||||
ctx.fillText('60天红绿榜', 160, 10)
|
||||
|
||||
ctx.font = '12px menlo,Hiragino Sans GB'
|
||||
ctx.fillText(`最近1个月收益: ${e1}%`, 360, 25)
|
||||
ctx.fillText(`最近3个月收益: ${e3}%`, 360, 45)
|
||||
ctx.fillText(`最近半年收益: ${e6}%`, 528, 25)
|
||||
ctx.fillText(`最近一年收益: ${e12}%`, 528, 45)
|
||||
|
||||
ctx.fillStyle = cp > 0 ? RED : cp === 0 ? GREY : GREEN
|
||||
ctx.fillRect(360, 65, 140, 20)
|
||||
ctx.fillRect(526, 65, 140, 20)
|
||||
ctx.fillStyle = '#fff'
|
||||
ctx.font = 'bold 14px menlo,Hiragino Sans GB'
|
||||
ctx.fillText(`实时净值: ¥${cm}`, 364, 80)
|
||||
ctx.fillText(`实时涨跌: ${cp}%`, 532, 80)
|
||||
|
||||
ctx.fillStyle = PLAIN
|
||||
ctx.fillRect(28, 25, 320, 1)
|
||||
ctx.fillRect(28, 75, 320, 1)
|
||||
ctx.fillStyle = GREY
|
||||
ctx.fillRect(28, 0, 1, 140)
|
||||
ctx.fillRect(0, 50, 348, 1)
|
||||
|
||||
while (rank.length) {
|
||||
var n = rank.shift()
|
||||
var y = Math.ceil(50 - (n / 10) * 50)
|
||||
|
||||
ctx.fillStyle = n > 0 ? RED : GREEN
|
||||
|
||||
if (y > 50) {
|
||||
ctx.fillRect(x, 50, 3, y - 50)
|
||||
} else {
|
||||
ctx.fillRect(x, y, 3, 50 - y)
|
||||
}
|
||||
|
||||
x += 5
|
||||
}
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {
|
||||
return
|
||||
}
|
||||
switch (name) {
|
||||
case 'stat':
|
||||
try {
|
||||
var stat = JSON.parse(val)
|
||||
this.props.stat = stat
|
||||
this.removeAttribute('stat')
|
||||
this.draw()
|
||||
} catch (e) {}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!customElements.get('wc-rank')) {
|
||||
customElements.define('wc-rank', Rank)
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
const DOCTYPE_EXP=/<\!DOCTYPE html>/,TAG_START_EXP=/<([\w\-]+)([\w\W]*?)>/g,TAG_END_EXP=/<\/([\w\-]+)>/g,TAG_ATTR_EXP=/[@a-zA-Z\-.]+=(["'])[^"]+\1|[@a-zA-Z\-.]+=[a-zA-Z0-9]+|[@a-zA-Z\-.]+/g,TAG_CM_EXP=/<!--([\w\W]*?)-->/g;export function colorHtml(t){return(t=t.replace(DOCTYPE_EXP,"[tag]<!DOCTYPE [attr]html[/attr]>[/tag]").replace(TAG_START_EXP,(t,a,r)=>(r&&(r=r.replace(TAG_ATTR_EXP,(function(t){if(~t.indexOf("=")){return`[attr]${(t=t.split("=")).shift()}[/attr]=[str]${t.join("=")}[/str]`}return`[attr]${t}[/attr]`}))),`[tag]<${a+r}>[/tag]`)).replace(TAG_END_EXP,(t,a)=>`[tag]</${a}>[/tag]`).replace(TAG_CM_EXP,'<i class="gr"><!--$1--></i>')).replace(/\[(\/?)tag\]/g,(t,a)=>a?"</i>":'<i class="r">').replace(/\[(\/?)attr\]/g,(t,a)=>a?"</i>":'<i class="b">').replace(/\[(\/?)str\]/g,(t,a)=>a?"</i>":'<i class="g">')}export function colorCss(t){return t=t.replace(/:(hover|after|active|last\-child|first\-child)/g,'<i class="o">:$1</i>').replace(/([\.#])([\w\-]+)/g,'<i class="gr">$1</i><i class="o">$2</i>').replace(/([a-zA-Z\-]+):\s?([^;\n]+);?/g,'<b class="gr">$1: </b><i class="b">$2</i><i class="gr">;</i>').replace(/([,\{\}])/g,'<i class="gr">$1</i>').replace(/&/g,'<i class="r">&</i>')}
|
|
@ -1,13 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
*
|
||||
*/
|
||||
|
||||
import"../scroll/index.js";import"../layer/index.js";import $ from"../utils.js";import{colorHtml,colorCss}from"./colorful.js";export default class Code extends HTMLElement{static get observedAttributes(){return["dark","lang"]}props={dark:"",lang:""};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:flex}.code-box{overflow:hidden;display:flex;flex-direction:column;position:relative;width:100%;max-height:610px;margin:10px 0;padding-bottom:8px;border-radius:6px;background:#f7f8fb;color:var(--color-dark-1);box-shadow:0 0 8px rgba(0,0,0,.15)}.code-box .title{display:flex;justify-content:space-between;align-items:center;width:100%;height:32px;padding:0 12px;line-height:1;font-size:14px;user-select:none}.code-box .title i{display:inline-block;width:12px;height:12px;margin-right:6px;border-radius:50%;background:var(--color-red-1)}.code-box .title i:nth-child(2){background:var(--color-orange-1)}.code-box .title i:nth-child(3){background:var(--color-green-1)}.code-box .title .act{--size: 18px;margin:0 6px;color:var(--color-grey-2);cursor:pointer}.code-box .title .act:hover{color:var(--color-grey-3)}.code-box .title .act.run{display:none}.code-box .scoll{flex:1;padding:5px 0;line-height:20px;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:14px;color:var(--color-dark-1);cursor:text;counter-reset:code}.code-box .scoll code{display:block;position:relative;min-height:20px;padding:0 8px 0 45px;white-space:pre-wrap;word-break:break-word}.code-box .scoll code::before{position:absolute;left:0;width:40px;height:100%;padding-right:5px;text-align:right;color:var(--color-grey-1);content:counter(code);counter-increment:code}.code-box .scoll code i{font-style:normal}.code-box .scoll code .r{color:var(--color-red-1)}.code-box .scoll code .b{color:var(--color-blue-1)}.code-box .scoll code .g{color:var(--color-green-1)}.code-box .scoll code .gr{color:var(--color-grey-2)}.code-box .scoll code .o{color:var(--color-orange-2)}:host([exec]) .title .run{display:inline-block}:host([dark]) .code-box{border-color:var(--color-dark-2);background:var(--color-dark-1);color:var(--color-plain-3)}:host([dark]) .code-box .code{color:var(--color-plain-2)}:host([dark]) .code-box .code p::before{color:var(--color-grey-3)}</style> <div class="code-box"> <header class="title"> <span><i></i><i></i><i></i></span> <span></span> <span> <wc-icon title="运行" class="act run" is="live"></wc-icon> <wc-icon title="复制" class="act cp" is="doc"></wc-icon> </span> </header> <wc-scroll axis="y" class="scoll"></wc-scroll> </div> ';var o=this.root.children[1],e=o.children[0];this.__CODE__=o.children[1],this.__LANG__=e.children[1],this.__RUN__=e.children[2].firstElementChild,this.__CP__=e.children[2].lastElementChild}get value(){return this.props.content}set value(o){switch(o=o.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),this.props.content=o,this.props.lang){case"html":o=colorHtml(o);break;case"css":case"scss":case"less":o=colorCss(o);break;default:o=o.replace(/</g,"<").replace(/>/g,">")}o=o.split("\n").map(o=>`<code>${o}</code>`).join(""),this.__CODE__.innerHTML=o}connectedCallback(){var o=this.innerHTML||this.textContent;(o=o.trim().replace(/^[\r\n]|\s{2,}$/g,"")).startsWith("<xmp>")&&o.endsWith("</xmp>")&&(o=o.slice(5,-6).trim()),this.value=o,this.textContent="",this._cpFN=$.bind(this.__CP__,"click",o=>{try{navigator.clipboard.writeText(this.value),layer.toast("复制到粘贴板成功","success")}catch(o){layer.toast("复制到粘贴板失败","error")}}),this._runFN=$.bind(this.__RUN__,"click",o=>{this.dispatchEvent(new CustomEvent("run",{detail:this.value}))})}unmounted(){$.unbind(this.__CP__,"click",this._cpFN),$.unbind(this.__RUN__,"click",this._runFN)}attributeChangedCallback(o,e,r){if(e!==r)switch(o){case"lang":this.props.lang=r.toLowerCase(),this.__LANG__.textContent=this.props.lang;break;case"value":this.value=r,this.removeAttribute("value")}}}
|
||||
|
||||
if(!customElements.get('wc-code')){
|
||||
customElements.define('wc-code', Code)
|
||||
}
|
|
@ -4,9 +4,14 @@
|
|||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2014-10-10 00:45:09
|
||||
*
|
||||
* CSS规范
|
||||
* doui的CSS规范
|
||||
*
|
||||
* 不能出现大写,以连字符风格命名
|
||||
* 表示状态的应该用do-st-*命名
|
||||
* 表示功能的应该用do-fn-*命名
|
||||
* 表示页面模块的应该用do-mod-modname 命名
|
||||
* 表示UI组件的应该用do-uiname命名, 它的子元素应该全部包在 .do-uiname这个根类下
|
||||
* 如 .do-layer .body { ... }
|
||||
*
|
||||
* 样式规则的出现顺序
|
||||
* 1 display float position overflow z-index 表示定位/布局的属性
|
||||
|
@ -17,66 +22,57 @@
|
|||
*
|
||||
*/
|
||||
|
||||
* {margin: 0;padding: 0;vertical-align: baseline;box-sizing: border-box;}
|
||||
::before, ::after {box-sizing: border-box;}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section,content {display: block;}
|
||||
img {border: 0;display: inline-block;}
|
||||
ol,ul {list-style: none;}
|
||||
blockquote, q {quotes: none;}
|
||||
blockquote::before, blockquote::after, q::before, q::after {content: '';content: none;}
|
||||
table {border-collapse: collapse;border-spacing: 0;}
|
||||
a:focus,input,textarea,button:focus,input:focus,textarea:focus {outline: none;}
|
||||
::-moz-focus-inner {border: none;outline: none;}
|
||||
|
||||
body {font-family: 'Helvetica Neue', Arial, 'WenQuanYi Micro Hei', 'PingFang SC', 'Hiragino Sans GB', 'Segoe UI', 'Microsoft Yahei', sans-serif;-webkit-font-smoothing: antialiased;text-size-adjust: 100%;-webkit-tap-highlight-color: transparent;}
|
||||
code, pre, samp {font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;}
|
||||
[anot],[\:repeat],[\:if] {visibility: hidden;}
|
||||
* {margin: 0;padding: 0;vertical-align: baseline;box-sizing:border-box;}
|
||||
::before,::after {box-sizing:border-box;}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section,content {display: block;}
|
||||
img {border:0;display:inline-block;}
|
||||
ol, ul {list-style: none;}
|
||||
blockquote, q {quotes: none;}
|
||||
blockquote::before, blockquote::after,
|
||||
q::before, q::after {content: '';content: none;}
|
||||
table {border-collapse: collapse;border-spacing: 0;}
|
||||
a:focus,input,textarea,button:focus,input:focus,textarea:focus {outline:none;}
|
||||
::-moz-focus-inner {
|
||||
border:none;outline:none;
|
||||
}
|
||||
body {font-family:"Helvetica Neue", Arial,"WenQuanYi Micro Hei","PingFang SC","Hiragino Sans GB","Segoe UI", "Microsoft Yahei", sans-serif;-webkit-font-smoothing: antialiased;text-size-adjust: 100%;-webkit-tap-highlight-color: transparent;}
|
||||
code,pre,samp {font-family:Menlo,Monaco,Consolas,"Courier New",monospace;}
|
||||
[anot],[\:repeat],[\:if] {visibility:hidden;}
|
||||
|
||||
|
||||
.noselect {-webkit-touch-callout: none;-webkit-user-select: none;-moz-user-select: none;user-select: none;}
|
||||
.noselect img, .noselect a {-webkit-user-drag: none;}
|
||||
.text-ell {overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
|
||||
.text-thin {-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}
|
||||
.noselect img, .noselect a {-webkit-user-drag:none;}
|
||||
.text-ell {overflow:hidden; white-space:nowrap; text-overflow:ellipsis }
|
||||
.osx-thin {-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}
|
||||
|
||||
:root {
|
||||
/* primary */
|
||||
--color-teal-a: rgba(72, 201, 176, 0.5);
|
||||
--color-teal-1: rgb(72, 201, 176);
|
||||
--color-teal-2: rgb(26, 188, 156);
|
||||
--color-teal-3: rgb(22, 160, 133);
|
||||
/* success */
|
||||
--color-green-a: rgba(88, 214, 141, 0.5);
|
||||
--color-green-1: rgb(88, 214, 141);
|
||||
--color-green-2: rgb(46, 204, 113);
|
||||
--color-green-3: rgb(39, 173, 96);
|
||||
/* info */
|
||||
--color-blue-a: rgba(100, 181, 246, 0.5);
|
||||
--color-blue-1: rgb(100, 181, 246);
|
||||
--color-blue-2: rgb(66, 165, 245);
|
||||
--color-blue-3: rgb(33, 150, 243);
|
||||
/* danger */
|
||||
--color-red-a: rgba(255, 107, 129, 0.5);
|
||||
--color-red-1: rgb(255, 107, 129);
|
||||
--color-red-2: rgb(255, 71, 87);
|
||||
--color-red-3: rgb(230, 52, 67);
|
||||
/* warning */
|
||||
--color-orange-a: rgba(244, 211, 19, 0.5);
|
||||
--color-orange-1: rgb(244, 211, 19);
|
||||
--color-orange-2: rgb(241, 196, 15);
|
||||
--color-orange-3: rgb(205, 167, 13);
|
||||
/* default1 */
|
||||
--color-plain-a: rgba(150, 204, 248, 0.5);
|
||||
--color-plain-1: rgb(242, 245, 252);
|
||||
--color-plain-2: rgb(232, 235, 244);
|
||||
--color-plain-3: rgb(218, 225, 233);
|
||||
/* default2 */
|
||||
--color-grey-a: rgba(206, 214, 224, 0.5);
|
||||
--color-grey-1: rgb(206, 214, 224);
|
||||
--color-grey-2: rgb(164, 176, 190);
|
||||
--color-grey-3: rgb(134, 144, 155);
|
||||
/* inverse */
|
||||
--color-dark-a: rgba(87, 96, 111, 0.5);
|
||||
--color-dark-1: rgb(87, 96, 111);
|
||||
--color-dark-2: rgb(52, 73, 94);
|
||||
--color-dark-3: rgb(44, 62, 80);
|
||||
--color-teal-1: #4db6ac;
|
||||
--color-teal-2: #26a69a;
|
||||
--color-teal-3: #009688;
|
||||
--color-green-1: #81c784;
|
||||
--color-green-2: #66bb6a;
|
||||
--color-green-3: #4caf50;
|
||||
--color-purple-1: #9575cd;
|
||||
--color-purple-2: #9575cd;
|
||||
--color-purple-3: #673ab7;
|
||||
--color-blue-1: #64b5f6;
|
||||
--color-blue-2: #42a5f5;
|
||||
--color-blue-3: #2196f3;
|
||||
--color-red-1: #ff5061;
|
||||
--color-red-2: #eb3b48;
|
||||
--color-red-3: #ce3742;
|
||||
--color-orange-1: #ffb618;
|
||||
--color-orange-2: #f39c12;
|
||||
--color-orange-3: #e67e22;
|
||||
--color-plain-1: #f2f5fc;
|
||||
--color-plain-2: #e8ebf4;
|
||||
--color-plain-3: #dae1e9;
|
||||
--color-grey-1: #bdbdbd;
|
||||
--color-grey-2: #9e9e9e;
|
||||
--color-grey-3: #757575;
|
||||
--color-dark-1: #62778d;
|
||||
--color-dark-2: #526273;
|
||||
--color-dark-3: #425064;
|
||||
}
|
|
@ -1 +1 @@
|
|||
import $ from"../utils.js";const DEF_OPT={axis:"",limit:!1,overflow:!0};export default class Drag{constructor(t){this.$elem=t,this._init()}_init(){this.$elem.style.transform="";var{x:t,y:s}=this.$elem.getBoundingClientRect();this.pos={x:t,y:s,_x:0,_y:0}}by(t,s={}){return this.$drag=t,this.opt=Object.assign(Object.create(null),DEF_OPT,s),!1!==this.opt.limit&&(this.opt.overflow=!1),t.style.cursor="move",this._handleResize=$.bind(window,"resize",this._init.bind(this)),this._handleMousedown=$.bind(t,"mousedown",t=>{if(this.disabled)return;var s=this.$elem.getBoundingClientRect();s.x-this.pos._x!==this.pos.x&&(this.pos.x=s.x-this.pos._x),s.y-this.pos._y!==this.pos.y&&(this.pos.y=s.y-this.pos._y);let e=t.pageX,i=t.pageY,o=document.documentElement.clientWidth,n=document.documentElement.clientHeight,h=s.width,p=s.height,d=[0,o-h,n-p,0];if("parent"===this.opt.limit){let t=this.$elem.parentNode.getBoundingClientRect();d=[t.top,t.right-h,t.bottom-p,t.left]}let l=$.bind(document,"mousemove",t=>{t.preventDefault();let o=t.pageX-e+(s.x-this.pos.x),n=t.pageY-i+(s.y-this.pos.y);"x"===this.opt.axis&&(n=0),"y"===this.opt.axis&&(o=0),!1===this.opt.overflow&&(o<d[3]-this.pos.x?o=d[3]-this.pos.x:o>d[1]-this.pos.x&&(o=d[1]-this.pos.x),n<d[0]-this.pos.y?n=d[0]-this.pos.y:n>d[2]-this.pos.y&&(n=d[2]-this.pos.y)),this.pos._x=o,this.pos._y=n,this.$elem.dispatchEvent(new CustomEvent("dragging",{detail:{offset:{x:this.pos.x+o,y:this.pos.y+n},move:{x:o,y:n}}})),this.$elem.style.transform=`translate(${o}px, ${n}px)`}),m=$.bind(document,"mouseup",t=>{this.$elem.dispatchEvent(new CustomEvent("dragged",{detail:{offset:{x:this.pos.x+this.pos._x,y:this.pos.y+this.pos._y},move:{x:this.pos._x,y:this.pos._y}}})),$.unbind(document,"mousemove",l),$.unbind(document,"mouseup",m)})}),this}on(t,s){if(t&&"function"==typeof s)return $.bind(this,t,s)}off(t,s){$.unbind(this,t,s)}destroy(){$.unbind(window,"resize",this._handleResize),$.unbind(this.$drag,"mousedown",this._handleMousedown),delete this.$elem,delete this.$drag}}
|
||||
"use strict";import $ from"../utils.js";const DEF_OPT={axis:"",limit:!1,overflow:!0};export default class Drag{constructor(t){this.$elem=t,this._init()}_init(){this.$elem.style.transform="";var{x:t,y:s}=this.$elem.getBoundingClientRect();this.pos={x:t,y:s,_x:0,_y:0}}by(t,s={}){return this.$drag=t,this.opt=Object.assign(Object.create(null),DEF_OPT,s),!1!==this.opt.limit&&(this.opt.overflow=!1),t.style.cursor="move",this._handleResize=$.bind(window,"resize",this._init.bind(this)),this._handleMousedown=$.bind(t,"mousedown",t=>{if(this.disabled)return;var s=this.$elem.getBoundingClientRect();s.x-this.pos._x!==this.pos.x&&(this.pos.x=s.x-this.pos._x),s.y-this.pos._y!==this.pos.y&&(this.pos.y=s.y-this.pos._y);let e=t.pageX,i=t.pageY,o=document.documentElement.clientWidth,n=document.documentElement.clientHeight,h=s.width,p=s.height,d=[0,o-h,n-p,0];if("parent"===this.opt.limit){let t=this.$elem.parentNode.getBoundingClientRect();d=[t.top,t.right-h,t.bottom-p,t.left]}let l=$.bind(document,"mousemove",t=>{t.preventDefault();let o=t.pageX-e+(s.x-this.pos.x),n=t.pageY-i+(s.y-this.pos.y);"x"===this.opt.axis&&(n=0),"y"===this.opt.axis&&(o=0),!1===this.opt.overflow&&(o<d[3]-this.pos.x?o=d[3]-this.pos.x:o>d[1]-this.pos.x&&(o=d[1]-this.pos.x),n<d[0]-this.pos.y?n=d[0]-this.pos.y:n>d[2]-this.pos.y&&(n=d[2]-this.pos.y)),this.pos._x=o,this.pos._y=n,this.$elem.dispatchEvent(new CustomEvent("dragging",{detail:{offset:{x:this.pos.x+o,y:this.pos.y+n},move:{x:o,y:n}}})),this.$elem.style.transform=`translate(${o}px, ${n}px)`}),m=$.bind(document,"mouseup",t=>{this.$elem.dispatchEvent(new CustomEvent("dragged",{detail:{offset:{x:this.pos.x+this.pos._x,y:this.pos.y+this.pos._y},move:{x:this.pos._x,y:this.pos._y}}})),$.unbind(document,"mousemove",l),$.unbind(document,"mouseup",m)})}),this}on(t,s){if(t&&"function"==typeof s)return $.bind(this,t,s)}off(t,s){$.unbind(this,t,s)}destroy(){$.unbind(window,"resize",this._handleResize),$.unbind(this.$drag,"mousedown",this._handleMousedown),delete this.$elem,delete this.$drag}};
|
|
@ -1 +1 @@
|
|||
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})}});
|
||||
"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 +0,0 @@
|
|||
import{Format,toS}from"./lib/format.js";const noop=function(e,t){this.defer.resolve(t)},NOBODY_METHODS=["GET","HEAD"],FORM_TYPES={form:"application/x-www-form-urlencoded; charset=UTF-8",json:"application/json; charset=UTF-8",text:"text/plain; charset=UTF-8"},ERRORS={10001:"Argument url is required",10012:"Parse error",10100:"Request canceled",10104:"Request pending...",10200:"Ok",10204:"No content",10304:"Not modified",10500:"Internal Server Error",10504:"Connected timeout"};Promise.defer=function(){var e={};return e.promise=new Promise(function(t,s){e.resolve=t,e.reject=s}),e};class _Request{constructor(e="",t={},{BASE_URL:s,__INIT__:r}){if(!e)throw new Error(ERRORS[10001]);if(e=e.replace(/#.*$/,""),s&&(/^([a-z]+:|\/\/)/.test(e)||(e=s+e)),t.method=(t.method||"get").toUpperCase(),this.xhr=new XMLHttpRequest,this.defer=Promise.defer(),this.options={headers:{"X-Requested-With":"XMLHttpRequest","content-type":FORM_TYPES.form},body:null,cache:"default",credentials:!1,signal:null,timeout:3e4},!t.signal){var o=new AbortController;t.signal=o.signal}this.defer.promise.abort=function(){o.abort()};var i=this.options.headers;return r.headers&&Object.assign(i,r.headers),t.headers&&(Object.assign(i,t.headers),delete t.headers),Object.assign(this.options,r,t,{url:e,headers:i}),this.__next__(),this.defer.promise}__next__(){var e=this.options,t=null,s=!1,r=!1,o=NOBODY_METHODS.includes(e.method);if(e.signal.onabort=(e=>{this.cancel=!0,this.xhr.abort()}),e.body)switch(typeof e.body){case"number":case"string":this.__type__("text"),t=e.body;break;case"object":if("FORM"===e.body.nodeName)e.method=e.body.method.toUpperCase()||"POST",s=(t=Format.parseForm(e.body)).constructor===FormData;else if(e.body.constructor===FormData)s=!0,o&&(e.method="POST"),t=e.body;else{for(let t in e.body)if("[object File]"===toS.call(e.body[t])){s=!0;break}s?(o&&(e.method="POST"),t=Format.mkFormData(e.body)):t=e.body}}s&&delete e.headers["content-type"];try{let t=document.createElement("a");t.href=e.url,r=location.protocol!==t.protocol||location.host!==t.host}catch(e){}r&&(e.credentials?this.xhr.withCredentials=!0:delete e.headers["X-Requested-With"]),o?((t=Format.param(t))&&(e.url+=(~e.url.indexOf("?")?"&":"?")+t),"no-store"===e.cache&&(e.url+=(~e.url.indexOf("?")?"&":"?")+"_t_="+Date.now())):s||(t=~e.headers["content-type"].indexOf("json")?JSON.stringify(t):Format.param(t)),this.xhr.responseType="blob",this.xhr.onreadystatechange=(t=>{e.timeout>0&&(e["time"+this.xhr.readyState]=t.timeStamp,4===this.xhr.readyState&&(e.isTimeout=e.time4-e.time1>e.timeout)),4===this.xhr.readyState&&this.__dispatch__(e.isTimeout)}),this.xhr.open(e.method,e.url);for(let t in e.headers)this.xhr.setRequestHeader(t,e.headers[t]);this.xhr.send(t),e.timeout&&e.timeout>0&&(this.xhr.timeout=e.timeout)}__type__(e){this.options.headers["content-type"]=FORM_TYPES[e]}__dispatch__(e){let t={status:200,statusText:"ok",body:"",headers:Object.create(null)};if(this.cancel)return this.__cancel__();if(e)return this.__timeout__();let s=this.xhr.status>=200&&this.xhr.status<400,r=this.xhr.getAllResponseHeaders().split("\n")||[];for(let e of r)if(e=e.trim()){let s=(e=e.split(":")).shift().toLowerCase();e=e.join(":").trim(),t.headers[s]=e}s?(t.status=this.xhr.status,204===t.status?t.statusText=ERRORS[10204]:304===t.status&&(t.statusText=ERRORS[10304])):(t.status=this.xhr.status||500,t.statusText=this.xhr.statusText||ERRORS[10500]),t.body=this.xhr.response,this.__success__(s,t)}__success__(e,t){var s=new _Response(t.status,t.statusText,t.body,t.headers);e?this.defer.resolve(s):this.defer.reject(s),delete this.xhr,delete this.options,delete this.defer}__cancel__(e){var t=new _Response(0,ERRORS[10100],Object.create(null));this.defer.reject(t),delete this.xhr,delete this.options,delete this.defer}__timeout__(e){var t=new _Response(504,ERRORS[10504],Object.create(null));this.defer.reject(t),delete this.xhr,delete this.options,delete this.defer}}class _Response{constructor(e=200,t="OK",s=null,r={}){this.status=e,this.statusText=t,this.ok=e>=200&&e<400,this.headers=r,Object.defineProperty(this,"__R__",{value:s,writable:!0,enumerable:!1,configurable:!0})}text(){return this.__R__.text()}json(){return this.__R__.text().then(e=>JSON.parse(e))}blob(){return this.__R__}arrayBuffer(){return this.__R__.arrayBuffer()}}const _fetch=function(e,t){return new _Request(e,t,{BASE_URL:_fetch.BASE_URL,__INIT__:_fetch.__INIT__||Object.create(null)})};_fetch.create=function(e,t=Object.create(null)){return function(s,r){return new _Request(s,r,{BASE_URL:e,__INIT__:t})}};export default _fetch;
|
|
@ -1 +0,0 @@
|
|||
export const toS=Object.prototype.toString;export const encode=encodeURIComponent;export const decode=decodeURIComponent;function serialize(e,t,o){var a;if(Array.isArray(t))t.forEach(function(t,r){a=e?`${e}[${Array.isArray(t)?r:""}]`:r,"object"==typeof t?serialize(a,t,o):o(a,t)});else for(let r in t)a=e?`${e}[${r}]`:r,"object"==typeof t[r]?serialize(a,t[r],o):o(a,t[r])}export const Format={parseForm(e){let t={},o=!1;for(let a,r=0;a=e.elements[r++];)switch(a.type){case"select-one":case"select-multiple":if(a.name.length&&!a.disabled)for(let e,o=0;e=a.options[o++];)e.selected&&(t[a.name]=e.value||e.text);break;case"file":a.name.length&&!a.disabled&&(t[a.name]=a.files[0],o=!0);break;case void 0:case"submit":case"reset":case"button":break;case"radio":case"checkbox":if(!a.checked)break;default:a.name.length&&!a.disabled&&(t[a.name]=a.value)}return o?this.mkFormData(t):t},mkFormData(e){let t=new FormData;for(let o in e){let a=e[o];Array.isArray(a)?a.forEach(function(e){t.append(o+"[]",e)}):t.append(o,e[o])}return t},param(e){if(!e||"string"==typeof e||"number"==typeof e)return e;let t=[];return"object"==typeof e&&serialize("",e,function(e,o){/native code/.test(o)||(o="function"==typeof o?o():o,o="[object File]"===toS.call(o)?o:encode(o),t.push(encode(e)+"="+o))}),t.join("&")}};
|
File diff suppressed because one or more lines are too long
|
@ -1,13 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
if(!customElements.get('wc-')){
|
||||
customElements.define('wc-', )
|
||||
}
|
|
@ -1,12 +1,310 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
import"../icon/index.js";import $ from"../utils.js";export default class CheckboxItem extends HTMLElement{static get observedAttributes(){return["color","value","checked","readonly","disabled"]}props={color:"",value:"",checked:!1,readonly:!1,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;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:1;-moz-user-select:none;user-select:none;white-space:nowrap;cursor:inherit;color:var(--color-grey-3)}:host .dot{--size: 18px;padding:2px;margin-right:3px}:host([readonly]){opacity:.8}:host([disabled]){cursor:not-allowed;opacity:.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([type=danger]) label.checked{color:var(--color-red-1)}:host([type=danger]) label.checked .dot{border-color:var(--color-red-1)}:host([type=danger]) label.checked .dot::after{background:var(--color-red-1)}:host([type=info]) label.checked{color:var(--color-blue-1)}:host([type=info]) label.checked .dot{border-color:var(--color-blue-1)}:host([type=info]) label.checked .dot::after{background:var(--color-blue-1)}:host([type=success]) label.checked{color:var(--color-green-1)}:host([type=success]) label.checked .dot{border-color:var(--color-green-1)}:host([type=success]) label.checked .dot::after{background:var(--color-green-1)}:host([type=primary]) label.checked{color:var(--color-teal-1)}:host([type=primary]) label.checked .dot{border-color:var(--color-teal-1)}:host([type=primary]) label.checked .dot::after{background:var(--color-teal-1)}:host([type=warning]) label.checked{color:var(--color-orange-1)}:host([type=warning]) label.checked .dot{border-color:var(--color-orange-1)}:host([type=warning]) label.checked .dot::after{background:var(--color-orange-1)}:host([type=inverse]) label.checked{color:var(--color-dark-1)}:host([type=inverse]) label.checked .dot{border-color:var(--color-dark-1)}:host([type=inverse]) label.checked .dot::after{background:var(--color-dark-1)}:host([color=purple]) label.checked{color:var(--color-purple-1)}:host([color=purple]) label.checked .dot{border-color:var(--color-purple-1)}:host([color=purple]) label.checked .dot::after{background:var(--color-purple-1)}</style> <label> <wc-icon class="dot" is="checkbox-off"></wc-icon> <slot /> </label> ',this.__SWITCH__=this.root.lastElementChild,this.__ICO__=this.__SWITCH__.children[0],this._isInGroup=!1}_checkGroup(){this._isInGroup="WC-CHECKBOX"===this.parentNode.tagName,this._isInGroup&&this.parentNode.root&&this.parentNode.value.includes(this.value)&&(this.checked=!0)}get value(){return this.props.value}set value(e){this.props.value=e}get checked(){return this.props.checked}set checked(e){this.props.checked=!!e;var{checked:o,color:t}=this.props;this.__SWITCH__.classList.toggle("checked",o),this.__ICO__.setAttribute("is","checkbox-"+(o?"on":"off")),o?this.__ICO__.setAttribute("color",t):this.__ICO__.removeAttribute("color")}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._checkGroup(),this._handlClick=$.bind(this,"click",e=>{e.preventDefault(),this.disabled||this.readOnly||(this.checked=!this.checked,this._isInGroup?this.parentNode.dispatchEvent(new CustomEvent("child-picked",{detail:{value:this.value,checked:this.checked}})):this.dispatchEvent(new CustomEvent("input")))})}disconnectedCallback(){$.unbind(this,"click",this._handlClick)}attributeChangedCallback(e,o,t){if(o!==t)switch(e){case"value":case"color":this.props[e]=t;break;case"checked":case"readonly":case"disabled":var r=e;"readonly"===r&&(r="readOnly"),this[r]=!0}}}
|
||||
|
||||
import "../icon/index.js"
|
||||
import $ from "../utils.js"
|
||||
|
||||
export default class CheckboxItem extends HTMLElement {
|
||||
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["color","value","checked","readonly","disabled"]
|
||||
}
|
||||
|
||||
props = {
|
||||
color: '',
|
||||
value: '',
|
||||
checked: false,
|
||||
readonly: false,
|
||||
disabled: false
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
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 {
|
||||
--color-teal-1: #4db6ac;
|
||||
--color-teal-2: #26a69a;
|
||||
--color-teal-3: #009688;
|
||||
--color-green-1: #81c784;
|
||||
--color-green-2: #66bb6a;
|
||||
--color-green-3: #4caf50;
|
||||
--color-purple-1: #9575cd;
|
||||
--color-purple-2: #9575cd;
|
||||
--color-purple-3: #673ab7;
|
||||
--color-blue-1: #64b5f6;
|
||||
--color-blue-2: #42a5f5;
|
||||
--color-blue-3: #2196f3;
|
||||
--color-red-1: #ff5061;
|
||||
--color-red-2: #eb3b48;
|
||||
--color-red-3: #ce3742;
|
||||
--color-orange-1: #ffb618;
|
||||
--color-orange-2: #f39c12;
|
||||
--color-orange-3: #e67e22;
|
||||
--color-plain-1: #f2f5fc;
|
||||
--color-plain-2: #e8ebf4;
|
||||
--color-plain-3: #dae1e9;
|
||||
--color-grey-1: #bdbdbd;
|
||||
--color-grey-2: #9e9e9e;
|
||||
--color-grey-3: #757575;
|
||||
--color-dark-1: #62778d;
|
||||
--color-dark-2: #526273;
|
||||
--color-dark-3: #425064; }
|
||||
|
||||
:host {
|
||||
display: inline-flex;
|
||||
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: var(--color-grey-3); }
|
||||
: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: var(--color-red-1); }
|
||||
:host([color='red']) label.checked .dot {
|
||||
border-color: var(--color-red-1); }
|
||||
:host([color='red']) label.checked .dot::after {
|
||||
background: var(--color-red-1); }
|
||||
|
||||
:host([color='blue']) label.checked {
|
||||
color: var(--color-blue-1); }
|
||||
:host([color='blue']) label.checked .dot {
|
||||
border-color: var(--color-blue-1); }
|
||||
:host([color='blue']) label.checked .dot::after {
|
||||
background: var(--color-blue-1); }
|
||||
|
||||
:host([color='green']) label.checked {
|
||||
color: var(--color-green-1); }
|
||||
:host([color='green']) label.checked .dot {
|
||||
border-color: var(--color-green-1); }
|
||||
:host([color='green']) label.checked .dot::after {
|
||||
background: var(--color-green-1); }
|
||||
|
||||
:host([color='teal']) label.checked {
|
||||
color: var(--color-teal-1); }
|
||||
:host([color='teal']) label.checked .dot {
|
||||
border-color: var(--color-teal-1); }
|
||||
:host([color='teal']) label.checked .dot::after {
|
||||
background: var(--color-teal-1); }
|
||||
|
||||
:host([color='orange']) label.checked {
|
||||
color: var(--color-orange-1); }
|
||||
:host([color='orange']) label.checked .dot {
|
||||
border-color: var(--color-orange-1); }
|
||||
:host([color='orange']) label.checked .dot::after {
|
||||
background: var(--color-orange-1); }
|
||||
|
||||
:host([color='dark']) label.checked {
|
||||
color: var(--color-dark-1); }
|
||||
:host([color='dark']) label.checked .dot {
|
||||
border-color: var(--color-dark-1); }
|
||||
:host([color='dark']) label.checked .dot::after {
|
||||
background: var(--color-dark-1); }
|
||||
|
||||
:host([color='purple']) label.checked {
|
||||
color: var(--color-purple-1); }
|
||||
:host([color='purple']) label.checked .dot {
|
||||
border-color: var(--color-purple-1); }
|
||||
:host([color='purple']) label.checked .dot::after {
|
||||
background: var(--color-purple-1); }
|
||||
</style>
|
||||
<label>
|
||||
<wc-icon class="dot" is="checkbox-off"></wc-icon>
|
||||
<slot />
|
||||
</label>
|
||||
`
|
||||
|
||||
|
||||
this.__SWITCH__ = this.root.lastElementChild
|
||||
this.__ICO__ = this.__SWITCH__.children[0]
|
||||
|
||||
this._isInGroup = false
|
||||
}
|
||||
|
||||
_checkGroup() {
|
||||
this._isInGroup = this.parentNode.tagName === 'WC-CHECKBOX'
|
||||
if (this._isInGroup && this.parentNode.root) {
|
||||
if (this.parentNode.value.includes(this.value)) {
|
||||
this.checked = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.props.value
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
this.props.value = val
|
||||
}
|
||||
|
||||
get checked() {
|
||||
return this.props.checked
|
||||
}
|
||||
|
||||
set checked(val) {
|
||||
this.props.checked = !!val
|
||||
var { checked, color } = this.props
|
||||
this.__SWITCH__.classList.toggle('checked', checked)
|
||||
this.__ICO__.setAttribute('is', 'checkbox-' + (checked ? 'on' : 'off'))
|
||||
|
||||
if (checked) {
|
||||
this.__ICO__.setAttribute('color', color)
|
||||
} else {
|
||||
this.__ICO__.removeAttribute('color')
|
||||
}
|
||||
}
|
||||
|
||||
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._checkGroup()
|
||||
|
||||
this._handlClick = $.bind(this, 'click', ev => {
|
||||
ev.preventDefault()
|
||||
|
||||
if (this.disabled || this.readOnly) {
|
||||
return
|
||||
}
|
||||
|
||||
this.checked = !this.checked
|
||||
|
||||
if (this._isInGroup) {
|
||||
this.parentNode.dispatchEvent(
|
||||
new CustomEvent('child-picked', {
|
||||
detail: { value: this.value, checked: this.checked }
|
||||
})
|
||||
)
|
||||
} else {
|
||||
this.dispatchEvent(new CustomEvent('input'))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
$.unbind(this, 'click', this._handlClick)
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {return}
|
||||
switch (name) {
|
||||
case 'value':
|
||||
case 'color':
|
||||
this.props[name] = val
|
||||
break
|
||||
|
||||
case 'checked':
|
||||
case 'readonly':
|
||||
case 'disabled':
|
||||
var k = name
|
||||
if (k === 'readonly') {
|
||||
k = 'readOnly'
|
||||
}
|
||||
this[k] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!customElements.get('wc-checkbox-item')){
|
||||
customElements.define('wc-checkbox-item', CheckboxItem)
|
||||
|
|
|
@ -1,12 +1,141 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
import $ from"../utils.js";import"./checkbox-item.js";export default class Checkbox extends HTMLElement{static get observedAttributes(){return["value"]}props={value:[]};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex}</style> <slot /> "}_updateChildrenStat(){Array.from(this.children).forEach(e=>{"WC-CHECKBOX-ITEM"===e.tagName&&e.root&&(this.value.includes(e.value)?e.checked=!0:e.checked=!1)})}get value(){return this.props.value}set value(e){e!==this.props.value&&(this.props.value=e,this._updateChildrenStat())}connectedCallback(){this._pickedFn=$.bind(this,"child-picked",e=>{var t=[...this.props.value],i=t.indexOf(e.detail.value);e.detail.checked?i<0&&t.push(e.detail.value):~i&&t.splice(i,1),this.props.value=t,this.dispatchEvent(new CustomEvent("input"))})}disconnectedCallback(){$.unbind(this,"child-picked",this._pickedFn)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"value":i&&(this.value=i.split(/,\s*?/))}}}
|
||||
|
||||
import $ from "../utils.js"
|
||||
import "./checkbox-item.js"
|
||||
|
||||
export default class Checkbox extends HTMLElement {
|
||||
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["value"]
|
||||
}
|
||||
|
||||
props = {
|
||||
value: []
|
||||
}
|
||||
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
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 {
|
||||
--color-teal-1: #4db6ac;
|
||||
--color-teal-2: #26a69a;
|
||||
--color-teal-3: #009688;
|
||||
--color-green-1: #81c784;
|
||||
--color-green-2: #66bb6a;
|
||||
--color-green-3: #4caf50;
|
||||
--color-purple-1: #9575cd;
|
||||
--color-purple-2: #9575cd;
|
||||
--color-purple-3: #673ab7;
|
||||
--color-blue-1: #64b5f6;
|
||||
--color-blue-2: #42a5f5;
|
||||
--color-blue-3: #2196f3;
|
||||
--color-red-1: #ff5061;
|
||||
--color-red-2: #eb3b48;
|
||||
--color-red-3: #ce3742;
|
||||
--color-orange-1: #ffb618;
|
||||
--color-orange-2: #f39c12;
|
||||
--color-orange-3: #e67e22;
|
||||
--color-plain-1: #f2f5fc;
|
||||
--color-plain-2: #e8ebf4;
|
||||
--color-plain-3: #dae1e9;
|
||||
--color-grey-1: #bdbdbd;
|
||||
--color-grey-2: #9e9e9e;
|
||||
--color-grey-3: #757575;
|
||||
--color-dark-1: #62778d;
|
||||
--color-dark-2: #526273;
|
||||
--color-dark-3: #425064; }
|
||||
|
||||
:host {
|
||||
display: inline-flex; }
|
||||
</style>
|
||||
<slot />
|
||||
`
|
||||
|
||||
}
|
||||
|
||||
_updateChildrenStat() {
|
||||
Array.from(this.children).forEach(it => {
|
||||
if (it.tagName === 'WC-CHECKBOX-ITEM' && it.root) {
|
||||
if (this.value.includes(it.value)) {
|
||||
it.checked = true
|
||||
} else {
|
||||
it.checked = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.props.value
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
if (val === this.props.value) {
|
||||
return
|
||||
}
|
||||
this.props.value = val
|
||||
this._updateChildrenStat()
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this._pickedFn = $.bind(this, 'child-picked', ev => {
|
||||
var tmp = [...this.props.value]
|
||||
var idx = tmp.indexOf(ev.detail.value)
|
||||
if (ev.detail.checked) {
|
||||
if (idx < 0) {
|
||||
tmp.push(ev.detail.value)
|
||||
}
|
||||
} else {
|
||||
if (~idx) {
|
||||
tmp.splice(idx, 1)
|
||||
}
|
||||
}
|
||||
this.props.value = tmp
|
||||
this.dispatchEvent(new CustomEvent('input'))
|
||||
})
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
$.unbind(this, 'child-picked', this._pickedFn)
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {return}
|
||||
switch (name) {
|
||||
case 'value':
|
||||
if (val) {
|
||||
this.value = val.split(/,\s*?/)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!customElements.get('wc-checkbox')){
|
||||
customElements.define('wc-checkbox', Checkbox)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
import"./button.js";import"./link.js";import"./input.js";import"./textarea.js";import"./number.js";import"./radio.js";import"./checkbox.js";import"./switch.js";import"./select.js";import"./star.js";
|
File diff suppressed because one or more lines are too long
|
@ -1,13 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
*
|
||||
*/
|
||||
|
||||
import"../icon/index.js";import $ from"../utils.js";const IS_FIREFOX=!!window.sidebar;export default class Link extends HTMLElement{static get observedAttributes(){return["to","autofocus","disabled","lazy"]}props={to:null,autofocus:"",disabled:!1,lazy:0};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{position:relative;display:inline-flex;user-select:none;-moz-user-select:none;font-size:14px;cursor:pointer}:host .link{display:flex;justify-content:center;align-items:center;width:100%;padding:var(--padding, 0 2px);line-height:1;font-size:inherit;font-family:inherit;outline:none;color:inherit;cursor:inherit;text-decoration:none;transition:color .15s linear}:host .link::-moz-focus-inner{border:none}:host::after{position:absolute;bottom:-2px;left:0;width:100%;height:1px;border-bottom:1px dashed var(--color-plain-3);content:"";opacity:0;transition:opacity .15s linear}:host(:not([disabled]):focus-within)::after{height:2px;border-width:2px;opacity:1}:host(:not([disabled]):hover)::after,:host([underline])::after{opacity:1}:host([loading]),:host([disabled]){cursor:not-allowed;opacity:.6}:host([type=danger]){color:var(--color-red-2)}:host([type=danger])::after{border-color:var(--color-red-1)}:host([type=danger]:not([disabled]):hover){color:var(--color-red-1)}:host([type=danger]:not([disabled]):active){color:var(--color-red-3)}:host([type=info]){color:var(--color-blue-2)}:host([type=info])::after{border-color:var(--color-blue-1)}:host([type=info]:not([disabled]):hover){color:var(--color-blue-1)}:host([type=info]:not([disabled]):active){color:var(--color-blue-3)}:host([type=success]){color:var(--color-green-2)}:host([type=success])::after{border-color:var(--color-green-1)}:host([type=success]:not([disabled]):hover){color:var(--color-green-1)}:host([type=success]:not([disabled]):active){color:var(--color-green-3)}:host([type=primary]){color:var(--color-teal-2)}:host([type=primary])::after{border-color:var(--color-teal-1)}:host([type=primary]:not([disabled]):hover){color:var(--color-teal-1)}:host([type=primary]:not([disabled]):active){color:var(--color-teal-3)}:host([type=warning]){color:var(--color-orange-2)}:host([type=warning])::after{border-color:var(--color-orange-1)}:host([type=warning]:not([disabled]):hover){color:var(--color-orange-1)}:host([type=warning]:not([disabled]):active){color:var(--color-orange-3)}:host([type=inverse]){color:var(--color-dark-2)}:host([type=inverse])::after{border-color:var(--color-dark-1)}:host([type=inverse]:not([disabled]):hover){color:var(--color-dark-1)}:host([type=inverse]:not([disabled]):active){color:var(--color-dark-3)}:host([type=default]){color:var(--color-grey-2)}:host([type=default])::after{border-color:var(--color-grey-1)}:host([type=default]:not([disabled]):hover){color:var(--color-grey-1)}:host([type=default]:not([disabled]):active){color:var(--color-grey-3)}</style> <a tabindex="0" class="link"> <slot /> </a> ',this.__LINK__=this.root.children[1]}get disabled(){return this.props.disabled}set disabled(o){var e=typeof o;o!==this.props.disabled&&("boolean"===e&&o||"boolean"!==e?(this.props.disabled=!0,this.setAttribute("disabled",""),this.__LINK__.removeAttribute("tabindex")):(this.props.disabled=!1,this.removeAttribute("disabled"),this.__LINK__.setAttribute("tabindex",0)))}connectedCallback(){this.stamp=0,this._handleClick=$.bind(this.__LINK__,"click",o=>{var{disabled:e,lazy:t}=this.props,r=Date.now();return e?(o.stopPropagation(),void o.preventDefault()):t&&r-this.stamp<t?(o.preventDefault(),void o.stopPropagation()):void(this.stamp=r)})}disconnectedCallback(){$.unbind(this.__LINK__,"click",this._handleClick)}attributeChangedCallback(o,e,t){if(e!==t)switch(o){case"autofocus":this.__LINK__.setAttribute("autofocus",""),IS_FIREFOX&&setTimeout(o=>{this.__LINK__.focus()},10);break;case"to":null===t?this.__LINK__.removeAttribute("href"):this.__LINK__.setAttribute("href",t);break;case"lazy":this.props.lazy=t>>0;break;case"disabled":this[o]=null!==t}}}
|
||||
|
||||
if(!customElements.get('wc-link')){
|
||||
customElements.define('wc-link', Link)
|
||||
}
|
|
@ -1,12 +1,412 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
import"../scroll/index.js";import"../icon/index.js";import $ from"../utils.js";export default class Number extends HTMLElement{static get observedAttributes(){return["value","max","min","step","autofocus","readonly","disabled"]}props={value:0,max:null,min:null,step:1,autofocus:!1,readonly:!1,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>undefined</style> <div class="label"> <span data-act="-">-</span> \x3c!-- <wc-icon class="icon" is="minus"></wc-icon> --\x3e <input value="0" maxlength="9" /> <span data-act="+">+</span> \x3c!-- <wc-icon class="icon" is="plus"></wc-icon> --\x3e </div> ',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=e,this._checkActionEnable()}_checkActionEnable(){var{max:e,min:t,value:s}=this.props,i=s;null!==t&&(t>i&&(i=t),this.__OUTER__.children[0].classList.toggle("disabled",s<=t)),null!==e&&(e<i&&(i=e),this.__OUTER__.children[2].classList.toggle("disabled",s>=e)),i!==s&&(this.props.value=i,this.__INPUT__.value=i,this.dispatchEvent(new CustomEvent("input")))}_updateValue(e){var{max:t,min:s,value:i,step:a}=this.props;if("+"===e){if(null!==t&&t<i+a)return;i+=a}else{if(null!==s&&s>i-a)return;i-=a}this.props.value=+i.toFixed(2),this.__INPUT__.value=this.props.value,this._checkActionEnable(),this.dispatchEvent(new CustomEvent("input"))}connectedCallback(){this._handleSubmit=$.catch(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=$.catch(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 s=t.dataset.act||t.parentNode.dataset.act;this._updateValue(s)}}})}disconnectedCallback(){$.unbind(this.__INPUT__,"keydown",this._handleSubmit)}attributeChangedCallback(e,t,s){if(t!==s)switch(e){case"autofocus":this.__INPUT__.setAttribute("autofocus",""),setTimeout(e=>{this.__INPUT__.focus()},10);break;case"value":this.value=s>>0;break;case"step":case"max":case"min":var i=+s;i==i&&(this.props[e]=i),this._checkActionEnable();break;case"readonly":case"disabled":var a=e;"readonly"===a&&(a="readOnly"),this[a]=!0}}}
|
||||
|
||||
import "../scroll/index.js"
|
||||
import "../icon/index.js"
|
||||
import $ from "../utils.js"
|
||||
|
||||
export default class Number extends HTMLElement {
|
||||
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["value","max","min","step","autofocus","readonly","disabled"]
|
||||
}
|
||||
|
||||
props = {
|
||||
value: 0,
|
||||
max: null,
|
||||
min: null,
|
||||
step: 1,
|
||||
autofocus: false,
|
||||
readonly: false,
|
||||
disabled: false
|
||||
}
|
||||
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
writable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
})
|
||||
|
||||
this.root.innerHTML = `<style>@charset "UTF-8";
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box; }
|
||||
|
||||
:host {
|
||||
--color-teal-1: #4db6ac;
|
||||
--color-teal-2: #26a69a;
|
||||
--color-teal-3: #009688;
|
||||
--color-green-1: #81c784;
|
||||
--color-green-2: #66bb6a;
|
||||
--color-green-3: #4caf50;
|
||||
--color-purple-1: #9575cd;
|
||||
--color-purple-2: #9575cd;
|
||||
--color-purple-3: #673ab7;
|
||||
--color-blue-1: #64b5f6;
|
||||
--color-blue-2: #42a5f5;
|
||||
--color-blue-3: #2196f3;
|
||||
--color-red-1: #ff5061;
|
||||
--color-red-2: #eb3b48;
|
||||
--color-red-3: #ce3742;
|
||||
--color-orange-1: #ffb618;
|
||||
--color-orange-2: #f39c12;
|
||||
--color-orange-3: #e67e22;
|
||||
--color-plain-1: #f2f5fc;
|
||||
--color-plain-2: #e8ebf4;
|
||||
--color-plain-3: #dae1e9;
|
||||
--color-grey-1: #bdbdbd;
|
||||
--color-grey-2: #9e9e9e;
|
||||
--color-grey-3: #757575;
|
||||
--color-dark-1: #62778d;
|
||||
--color-dark-2: #526273;
|
||||
--color-dark-3: #425064; }
|
||||
|
||||
:host {
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
width: 128px;
|
||||
height: 32px;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
color: var(--color-dark-2);
|
||||
border-radius: 2px; }
|
||||
|
||||
.label {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
line-height: 0;
|
||||
font-size: 14px;
|
||||
border: 1px solid var(--color-plain-3);
|
||||
border-radius: inherit;
|
||||
background: var(--bg-color, #fff);
|
||||
color: inherit;
|
||||
cursor: text;
|
||||
/* ----- */ }
|
||||
.label span {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 32px;
|
||||
height: 100%;
|
||||
background: var(--bg-color, --color-plain-1);
|
||||
font-size: 18px;
|
||||
cursor: pointer; }
|
||||
.label span:first-child {
|
||||
border-radius: 2px 0 0 2px;
|
||||
border-right: 1px solid var(--color-plain-3); }
|
||||
.label span:last-child {
|
||||
border-radius: 0 2px 2px 0;
|
||||
border-left: 1px solid var(--color-plain-3); }
|
||||
.label span.disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6; }
|
||||
.label input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
padding: 0 5px;
|
||||
border: 0;
|
||||
border-radius: inherit;
|
||||
color: inherit;
|
||||
text-align: center;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
background: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
cursor: inherit; }
|
||||
.label input::placeholder {
|
||||
color: var(--color-grey-1); }
|
||||
.label .icon {
|
||||
padding: 0 5px;
|
||||
--size: 20px; }
|
||||
|
||||
/* --- */
|
||||
:host([readonly]) .label {
|
||||
cursor: default;
|
||||
opacity: 0.8; }
|
||||
:host([readonly]) .label span {
|
||||
cursor: inherit; }
|
||||
|
||||
:host([disabled]) .label {
|
||||
background: var(--color-plain-1);
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6; }
|
||||
:host([disabled]) .label span {
|
||||
cursor: inherit; }
|
||||
|
||||
:host(:focus-within) {
|
||||
box-shadow: 0 0 2px #88f7df; }
|
||||
|
||||
:host(:focus-within[readonly]) {
|
||||
box-shadow: 0 0 2px #f3be4d; }
|
||||
|
||||
/* 额外样式 */
|
||||
:host([round]) {
|
||||
border-radius: 21px; }
|
||||
:host([round]) .label span:first-child {
|
||||
border-radius: 21px 0 0 21px; }
|
||||
:host([round]) .label span:last-child {
|
||||
border-radius: 0 21px 21px 0; }
|
||||
|
||||
:host([size='large']) {
|
||||
width: 192px;
|
||||
height: 42px; }
|
||||
:host([size='large']) .label {
|
||||
font-size: 16px; }
|
||||
:host([size='large']) .label span {
|
||||
width: 48px; }
|
||||
:host([size='large']) .prepend,
|
||||
:host([size='large']) .append {
|
||||
height: 40px; }
|
||||
|
||||
:host([size='medium']) {
|
||||
width: 144px;
|
||||
height: 36px; }
|
||||
:host([size='medium']) .label span {
|
||||
width: 36px; }
|
||||
:host([size='medium']) .prepend,
|
||||
:host([size='medium']) .append {
|
||||
height: 34px; }
|
||||
|
||||
:host([size='mini']) {
|
||||
width: 96px;
|
||||
height: 24px; }
|
||||
:host([size='mini']) .label {
|
||||
font-size: 12px; }
|
||||
:host([size='mini']) .label span {
|
||||
width: 28px; }
|
||||
:host([size='mini']) .icon {
|
||||
--size: 16px; }
|
||||
:host([size='mini']) .prepend,
|
||||
:host([size='mini']) .append {
|
||||
height: 18px; }
|
||||
</style>
|
||||
<div class="label">
|
||||
<span data-act="-">-</span>
|
||||
<!-- <wc-icon class="icon" is="minus"></wc-icon> -->
|
||||
<input value="0" maxlength="9" />
|
||||
<span data-act="+">+</span>
|
||||
<!-- <wc-icon class="icon" is="plus"></wc-icon> -->
|
||||
</div>
|
||||
`
|
||||
|
||||
|
||||
this.__OUTER__ = this.root.children[1]
|
||||
this.__INPUT__ = this.__OUTER__.children[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', '')
|
||||
this.__INPUT__.setAttribute('readonly', '')
|
||||
} else {
|
||||
this.props.readonly = false
|
||||
this.removeAttribute('readonly')
|
||||
this.__INPUT__.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', '')
|
||||
this.__INPUT__.setAttribute('disabled', '')
|
||||
} else {
|
||||
this.props.disabled = false
|
||||
this.removeAttribute('disabled')
|
||||
this.__INPUT__.removeAttribute('disabled')
|
||||
}
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.props.value
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
var n = +val
|
||||
if (n === n) {
|
||||
val = n
|
||||
} else {
|
||||
val = 0
|
||||
}
|
||||
this.props.value = val
|
||||
this.__INPUT__.value = val
|
||||
|
||||
this._checkActionEnable()
|
||||
}
|
||||
|
||||
_checkActionEnable() {
|
||||
var { max, min, value } = this.props
|
||||
var n = value
|
||||
|
||||
if (min !== null) {
|
||||
if (min > n) {
|
||||
n = min
|
||||
}
|
||||
this.__OUTER__.children[0].classList.toggle('disabled', value <= min)
|
||||
}
|
||||
if (max !== null) {
|
||||
if (max < n) {
|
||||
n = max
|
||||
}
|
||||
this.__OUTER__.children[2].classList.toggle('disabled', value >= max)
|
||||
}
|
||||
if (n !== value) {
|
||||
this.props.value = n
|
||||
this.__INPUT__.value = n
|
||||
this.dispatchEvent(new CustomEvent('input'))
|
||||
}
|
||||
}
|
||||
|
||||
_updateValue(act) {
|
||||
var { max, min, value, step } = this.props
|
||||
if (act === '+') {
|
||||
if (max !== null && max < value + step) {
|
||||
return
|
||||
}
|
||||
value += step
|
||||
} else {
|
||||
if (min !== null && min > value - step) {
|
||||
return
|
||||
}
|
||||
value -= step
|
||||
}
|
||||
this.props.value = +value.toFixed(2)
|
||||
this.__INPUT__.value = this.props.value
|
||||
this._checkActionEnable()
|
||||
this.dispatchEvent(new CustomEvent('input'))
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
// 键盘事件
|
||||
this._handleSubmit = $.catch(this.__INPUT__, 'keydown', ev => {
|
||||
if (this.disabled || this.readOnly) {
|
||||
return
|
||||
}
|
||||
|
||||
// up: 38, down: 40
|
||||
if (ev.keyCode === 38 || ev.keyCode === 40) {
|
||||
ev.preventDefault()
|
||||
return this._updateValue(ev.keyCode === 38 ? '+' : '-')
|
||||
}
|
||||
// 回车触发submit事件
|
||||
if (ev.keyCode === 13) {
|
||||
ev.preventDefault()
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('submit', {
|
||||
detail: this.value
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
this._handleChange = $.catch(this.__INPUT__, 'change', ev => {
|
||||
if (isFinite(this.__INPUT__.value)) {
|
||||
this.props.value = +this.__INPUT__.value
|
||||
if (!this.__INPUT__.value.endsWith('.')) {
|
||||
this.__INPUT__.value = this.props.value
|
||||
}
|
||||
} else {
|
||||
this.__INPUT__.value = this.props.value = 0
|
||||
}
|
||||
this.dispatchEvent(new CustomEvent('input'))
|
||||
})
|
||||
|
||||
this._handleAction = $.bind(this.__OUTER__, 'click', ev => {
|
||||
if (this.disabled || this.readOnly) {
|
||||
return
|
||||
}
|
||||
var target = ev.target
|
||||
|
||||
if (target.tagName === 'SPAN' || target.parentNode === 'SPAN') {
|
||||
var act = target.dataset.act || target.parentNode.dataset.act
|
||||
|
||||
this._updateValue(act)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
$.unbind(this.__INPUT__, 'keydown', this._handleSubmit)
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {return}
|
||||
switch (name) {
|
||||
case 'autofocus':
|
||||
this.__INPUT__.setAttribute('autofocus', '')
|
||||
// 辣鸡火狐, 要触发一下focus, 才能聚焦
|
||||
setTimeout(_ => {
|
||||
this.__INPUT__.focus()
|
||||
}, 10)
|
||||
break
|
||||
|
||||
case 'value':
|
||||
this.value = val >> 0
|
||||
break
|
||||
|
||||
case 'step':
|
||||
case 'max':
|
||||
case 'min':
|
||||
var n = +val
|
||||
if (n === n) {
|
||||
this.props[name] = n
|
||||
}
|
||||
this._checkActionEnable()
|
||||
break
|
||||
|
||||
case 'readonly':
|
||||
case 'disabled':
|
||||
var k = name
|
||||
if (k === 'readonly') {
|
||||
k = 'readOnly'
|
||||
}
|
||||
this[k] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!customElements.get('wc-number')){
|
||||
customElements.define('wc-number', Number)
|
||||
|
|
|
@ -1,12 +1,162 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
export default class Progress extends HTMLElement{static get observedAttributes(){return["value","max"]}props={value:0,max:1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:flex;align-items:center}:host label{flex:1;height:var(--size, 10px);border-radius:9px;background:var(--color-plain-2)}:host label span{display:block;width:0;height:100%;border-radius:9px;background:var(--color-teal-1)}:host([size=large]) label{height:18px}:host([size=medium]) label{height:14px}:host([size=mini]) label{height:6px}:host([type=danger]) label span{background:var(--color-red-1)}:host([type=info]) label span{background:var(--color-blue-1)}:host([type=success]) label span{background:var(--color-green-1)}:host([type=warning]) label span{background:var(--color-orange-1)}:host([type=inverse]) label span{background:var(--color-dark-1)}:host([color=purple]) label span{background:var(--color-purple-1)}</style> <label><span></span></label> ",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(a!==l)switch(e){case"max":var r=+l;(r!=r||r<1)&&(r=1),this.props.max=r,this.calculate();break;case"value":var t=+l;t==t&&(this.props.value=t,this.calculate())}}}
|
||||
|
||||
export default class Progress extends HTMLElement {
|
||||
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["value","max"]
|
||||
}
|
||||
|
||||
props = {
|
||||
value: 0,
|
||||
max: 1
|
||||
}
|
||||
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
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 {
|
||||
--color-teal-1: #4db6ac;
|
||||
--color-teal-2: #26a69a;
|
||||
--color-teal-3: #009688;
|
||||
--color-green-1: #81c784;
|
||||
--color-green-2: #66bb6a;
|
||||
--color-green-3: #4caf50;
|
||||
--color-purple-1: #9575cd;
|
||||
--color-purple-2: #9575cd;
|
||||
--color-purple-3: #673ab7;
|
||||
--color-blue-1: #64b5f6;
|
||||
--color-blue-2: #42a5f5;
|
||||
--color-blue-3: #2196f3;
|
||||
--color-red-1: #ff5061;
|
||||
--color-red-2: #eb3b48;
|
||||
--color-red-3: #ce3742;
|
||||
--color-orange-1: #ffb618;
|
||||
--color-orange-2: #f39c12;
|
||||
--color-orange-3: #e67e22;
|
||||
--color-plain-1: #f2f5fc;
|
||||
--color-plain-2: #e8ebf4;
|
||||
--color-plain-3: #dae1e9;
|
||||
--color-grey-1: #bdbdbd;
|
||||
--color-grey-2: #9e9e9e;
|
||||
--color-grey-3: #757575;
|
||||
--color-dark-1: #62778d;
|
||||
--color-dark-2: #526273;
|
||||
--color-dark-3: #425064; }
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
align-items: center; }
|
||||
:host label {
|
||||
flex: 1;
|
||||
height: var(--size, 10px);
|
||||
border-radius: 9px;
|
||||
background: var(--color-plain-2); }
|
||||
:host label span {
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
border-radius: 9px;
|
||||
background: var(--color-teal-1); }
|
||||
|
||||
:host([size='large']) label {
|
||||
height: 18px; }
|
||||
|
||||
:host([size='medium']) label {
|
||||
height: 14px; }
|
||||
|
||||
:host([size='mini']) label {
|
||||
height: 6px; }
|
||||
|
||||
:host([color='red']) label span {
|
||||
background: var(--color-red-1); }
|
||||
|
||||
:host([color='blue']) label span {
|
||||
background: var(--color-blue-1); }
|
||||
|
||||
:host([color='green']) label span {
|
||||
background: var(--color-green-1); }
|
||||
|
||||
:host([color='orange']) label span {
|
||||
background: var(--color-orange-1); }
|
||||
|
||||
:host([color='dark']) label span {
|
||||
background: var(--color-dark-1); }
|
||||
|
||||
:host([color='purple']) label span {
|
||||
background: var(--color-purple-1); }
|
||||
</style>
|
||||
<label><span></span></label>
|
||||
`
|
||||
|
||||
this.__THUMB__ = this.root.children[1].lastElementChild
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.props.value
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
this.props.value = +val
|
||||
this.calculate()
|
||||
}
|
||||
|
||||
calculate() {
|
||||
var { max, value } = this.props
|
||||
this.__THUMB__.style.width = `${(100 * value) / max}%`
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.calculate()
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {return}
|
||||
switch (name) {
|
||||
case 'max':
|
||||
var max = +val
|
||||
if (max !== max || max < 1) {
|
||||
max = 1
|
||||
}
|
||||
this.props.max = max
|
||||
this.calculate()
|
||||
break
|
||||
|
||||
case 'value':
|
||||
var v = +val
|
||||
if (v === v) {
|
||||
this.props.value = v
|
||||
this.calculate()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!customElements.get('wc-progress')){
|
||||
customElements.define('wc-progress', Progress)
|
||||
|
|
|
@ -1,12 +1,307 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
import $ from"../utils.js";export default class RadioItem extends HTMLElement{static get observedAttributes(){return["value","checked","readonly","disabled"]}props={value:"",checked:!1,readonly:!1,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;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:1;-moz-user-select:none;user-select:none;white-space:nowrap;cursor:inherit;color:var(--color-grey-3)}:host label.checked .dot::after{visibility:visible}:host .dot{display:flex;justify-content:center;align-items:center;width:18px;height:18px;margin-right:3px;border:1px solid var(--color-grey-1);border-radius:50%;background:#fff}:host .dot::after{display:block;visibility:hidden;width:12px;height:12px;border-radius:50%;background:var(--color-grey-1);content:""}:host([readonly]){opacity:.8}:host([disabled]){cursor:not-allowed;opacity:.6}:host([size=large]) label{min-width:58px;height:32px}:host([size=large]) .dot{width:26px;height:26px}:host([size=large]) .dot::after{width:18px;height:18px}:host([size=medium]) label{min-width:50px;height:28px}:host([size=medium]) .dot{width:22px;height:22px}:host([size=medium]) .dot::after{width:14px;height:14px}:host([size=mini]) label{height:14px}:host([size=mini]) .dot{width:14px;height:14px}:host([size=mini]) .dot::after{width:8px;height:8px}:host([type=danger]) label.checked{color:var(--color-red-1)}:host([type=danger]) label.checked .dot{border-color:var(--color-red-1)}:host([type=danger]) label.checked .dot::after{background:var(--color-red-1)}:host([type=info]) label.checked{color:var(--color-blue-1)}:host([type=info]) label.checked .dot{border-color:var(--color-blue-1)}:host([type=info]) label.checked .dot::after{background:var(--color-blue-1)}:host([type=success]) label.checked{color:var(--color-green-1)}:host([type=success]) label.checked .dot{border-color:var(--color-green-1)}:host([type=success]) label.checked .dot::after{background:var(--color-green-1)}:host([type=primary]) label.checked{color:var(--color-teal-1)}:host([type=primary]) label.checked .dot{border-color:var(--color-teal-1)}:host([type=primary]) label.checked .dot::after{background:var(--color-teal-1)}:host([type=warning]) label.checked{color:var(--color-orange-1)}:host([type=warning]) label.checked .dot{border-color:var(--color-orange-1)}:host([type=warning]) label.checked .dot::after{background:var(--color-orange-1)}:host([type=inverse]) label.checked{color:var(--color-dark-1)}:host([type=inverse]) label.checked .dot{border-color:var(--color-dark-1)}:host([type=inverse]) label.checked .dot::after{background:var(--color-dark-1)}:host([color=purple]) label.checked{color:var(--color-purple-1)}:host([color=purple]) label.checked .dot{border-color:var(--color-purple-1)}:host([color=purple]) label.checked .dot::after{background:var(--color-purple-1)}</style> <label> <span class="dot"></span> <slot /> </label> ',this.__SWITCH__=this.root.lastElementChild}get value(){return this.props.value}set value(e){this.props.value=e}get checked(){return this.props.checked}set checked(e){this.props.checked=!!e,this.__SWITCH__.classList.toggle("checked",this.props.checked)}get readOnly(){return this.props.readonly}set readOnly(e){var 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.value===this.parentNode.value&&(this.checked=!0),this._handleClick=$.catch(this,"click",e=>{this.disabled||this.readOnly||this.checked||this.parentNode.dispatchEvent(new CustomEvent("child-picked",{detail:this.value}))})}disconnectedCallback(){$.unbind(this,"click",this._handleClick)}attributeChangedCallback(e,o,t){if(o!==t)switch(e){case"value":this.value=t;break;case"checked":case"readonly":case"disabled":var r=e;"readonly"===r&&(r="readOnly"),this[r]=!0}}}
|
||||
|
||||
import $ from "../utils.js"
|
||||
|
||||
export default class RadioItem extends HTMLElement {
|
||||
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["value","checked","readonly","disabled"]
|
||||
}
|
||||
|
||||
props = {
|
||||
value: '',
|
||||
checked: false,
|
||||
readonly: false,
|
||||
disabled: false
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
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 {
|
||||
--color-teal-1: #4db6ac;
|
||||
--color-teal-2: #26a69a;
|
||||
--color-teal-3: #009688;
|
||||
--color-green-1: #81c784;
|
||||
--color-green-2: #66bb6a;
|
||||
--color-green-3: #4caf50;
|
||||
--color-purple-1: #9575cd;
|
||||
--color-purple-2: #9575cd;
|
||||
--color-purple-3: #673ab7;
|
||||
--color-blue-1: #64b5f6;
|
||||
--color-blue-2: #42a5f5;
|
||||
--color-blue-3: #2196f3;
|
||||
--color-red-1: #ff5061;
|
||||
--color-red-2: #eb3b48;
|
||||
--color-red-3: #ce3742;
|
||||
--color-orange-1: #ffb618;
|
||||
--color-orange-2: #f39c12;
|
||||
--color-orange-3: #e67e22;
|
||||
--color-plain-1: #f2f5fc;
|
||||
--color-plain-2: #e8ebf4;
|
||||
--color-plain-3: #dae1e9;
|
||||
--color-grey-1: #bdbdbd;
|
||||
--color-grey-2: #9e9e9e;
|
||||
--color-grey-3: #757575;
|
||||
--color-dark-1: #62778d;
|
||||
--color-dark-2: #526273;
|
||||
--color-dark-3: #425064; }
|
||||
|
||||
:host {
|
||||
display: inline-flex;
|
||||
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: 1;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
cursor: inherit;
|
||||
color: var(--color-grey-3); }
|
||||
:host label.checked .dot::after {
|
||||
visibility: visible; }
|
||||
:host .dot {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 3px;
|
||||
border: 1px solid var(--color-grey-1);
|
||||
border-radius: 50%;
|
||||
background: #fff; }
|
||||
:host .dot::after {
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: var(--color-grey-1);
|
||||
content: ''; }
|
||||
|
||||
:host([readonly]) {
|
||||
opacity: 0.8; }
|
||||
|
||||
:host([disabled]) {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6; }
|
||||
|
||||
:host([size='large']) label {
|
||||
min-width: 58px;
|
||||
height: 32px; }
|
||||
|
||||
:host([size='large']) .dot {
|
||||
width: 26px;
|
||||
height: 26px; }
|
||||
:host([size='large']) .dot::after {
|
||||
width: 18px;
|
||||
height: 18px; }
|
||||
|
||||
:host([size='medium']) label {
|
||||
min-width: 50px;
|
||||
height: 28px; }
|
||||
|
||||
:host([size='medium']) .dot {
|
||||
width: 22px;
|
||||
height: 22px; }
|
||||
:host([size='medium']) .dot::after {
|
||||
width: 14px;
|
||||
height: 14px; }
|
||||
|
||||
:host([size='mini']) label {
|
||||
height: 14px; }
|
||||
|
||||
:host([size='mini']) .dot {
|
||||
width: 14px;
|
||||
height: 14px; }
|
||||
:host([size='mini']) .dot::after {
|
||||
width: 8px;
|
||||
height: 8px; }
|
||||
|
||||
:host([color='red']) label.checked {
|
||||
color: var(--color-red-1); }
|
||||
:host([color='red']) label.checked .dot {
|
||||
border-color: var(--color-red-1); }
|
||||
:host([color='red']) label.checked .dot::after {
|
||||
background: var(--color-red-1); }
|
||||
|
||||
:host([color='blue']) label.checked {
|
||||
color: var(--color-blue-1); }
|
||||
:host([color='blue']) label.checked .dot {
|
||||
border-color: var(--color-blue-1); }
|
||||
:host([color='blue']) label.checked .dot::after {
|
||||
background: var(--color-blue-1); }
|
||||
|
||||
:host([color='green']) label.checked {
|
||||
color: var(--color-green-1); }
|
||||
:host([color='green']) label.checked .dot {
|
||||
border-color: var(--color-green-1); }
|
||||
:host([color='green']) label.checked .dot::after {
|
||||
background: var(--color-green-1); }
|
||||
|
||||
:host([color='teal']) label.checked {
|
||||
color: var(--color-teal-1); }
|
||||
:host([color='teal']) label.checked .dot {
|
||||
border-color: var(--color-teal-1); }
|
||||
:host([color='teal']) label.checked .dot::after {
|
||||
background: var(--color-teal-1); }
|
||||
|
||||
:host([color='orange']) label.checked {
|
||||
color: var(--color-orange-1); }
|
||||
:host([color='orange']) label.checked .dot {
|
||||
border-color: var(--color-orange-1); }
|
||||
:host([color='orange']) label.checked .dot::after {
|
||||
background: var(--color-orange-1); }
|
||||
|
||||
:host([color='dark']) label.checked {
|
||||
color: var(--color-dark-1); }
|
||||
:host([color='dark']) label.checked .dot {
|
||||
border-color: var(--color-dark-1); }
|
||||
:host([color='dark']) label.checked .dot::after {
|
||||
background: var(--color-dark-1); }
|
||||
|
||||
:host([color='purple']) label.checked {
|
||||
color: var(--color-purple-1); }
|
||||
:host([color='purple']) label.checked .dot {
|
||||
border-color: var(--color-purple-1); }
|
||||
:host([color='purple']) label.checked .dot::after {
|
||||
background: var(--color-purple-1); }
|
||||
</style>
|
||||
<label>
|
||||
<span class="dot"></span>
|
||||
<slot />
|
||||
</label>
|
||||
`
|
||||
|
||||
|
||||
this.__SWITCH__ = this.root.lastElementChild
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.props.value
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
this.props.value = val
|
||||
}
|
||||
|
||||
get checked() {
|
||||
return this.props.checked
|
||||
}
|
||||
|
||||
set checked(val) {
|
||||
this.props.checked = !!val
|
||||
this.__SWITCH__.classList.toggle('checked', this.props.checked)
|
||||
}
|
||||
|
||||
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() {
|
||||
if (this.value === this.parentNode.value) {
|
||||
this.checked = true
|
||||
}
|
||||
|
||||
this._handleClick = $.catch(this, 'click', ev => {
|
||||
if (this.disabled || this.readOnly || this.checked) {
|
||||
return
|
||||
}
|
||||
|
||||
this.parentNode.dispatchEvent(
|
||||
new CustomEvent('child-picked', { detail: this.value })
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
$.unbind(this, 'click', this._handleClick)
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {return}
|
||||
switch (name) {
|
||||
case 'value':
|
||||
this.value = val
|
||||
break
|
||||
|
||||
case 'checked':
|
||||
case 'readonly':
|
||||
case 'disabled':
|
||||
var k = name
|
||||
if (k === 'readonly') {
|
||||
k = 'readOnly'
|
||||
}
|
||||
this[k] = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!customElements.get('wc-radio-item')){
|
||||
customElements.define('wc-radio-item', RadioItem)
|
||||
|
|
|
@ -1,12 +1,129 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
import $ from"../utils.js";import"./radio-item.js";export default class Radio extends HTMLElement{static get observedAttributes(){return["value"]}props={value:null};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML="<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex}</style> <slot /> "}_updateChildrenStat(){Array.from(this.children).forEach(e=>{"WC-RADIO-ITEM"===e.tagName&&e.root&&(e.value===this.props.value?e.checked=!0:e.checked=!1)})}get value(){return this.props.value}set value(e){e!==this.props.value&&(this.props.value=e,this._updateChildrenStat())}connectedCallback(){this._pickedFn=$.bind(this,"child-picked",e=>{log("radio picked: ",e.detail),this.value=e.detail,this.dispatchEvent(new CustomEvent("input"))})}disconnectedCallback(){$.unbind(this,"child-picked",this._pickedFn)}attributeChangedCallback(e,t,i){if(t!==i)switch(e){case"value":this.value=i}}}
|
||||
|
||||
import $ from "../utils.js"
|
||||
import "./radio-item.js"
|
||||
|
||||
export default class Radio extends HTMLElement {
|
||||
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["value"]
|
||||
}
|
||||
|
||||
props = {
|
||||
value: null
|
||||
}
|
||||
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
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 {
|
||||
--color-teal-1: #4db6ac;
|
||||
--color-teal-2: #26a69a;
|
||||
--color-teal-3: #009688;
|
||||
--color-green-1: #81c784;
|
||||
--color-green-2: #66bb6a;
|
||||
--color-green-3: #4caf50;
|
||||
--color-purple-1: #9575cd;
|
||||
--color-purple-2: #9575cd;
|
||||
--color-purple-3: #673ab7;
|
||||
--color-blue-1: #64b5f6;
|
||||
--color-blue-2: #42a5f5;
|
||||
--color-blue-3: #2196f3;
|
||||
--color-red-1: #ff5061;
|
||||
--color-red-2: #eb3b48;
|
||||
--color-red-3: #ce3742;
|
||||
--color-orange-1: #ffb618;
|
||||
--color-orange-2: #f39c12;
|
||||
--color-orange-3: #e67e22;
|
||||
--color-plain-1: #f2f5fc;
|
||||
--color-plain-2: #e8ebf4;
|
||||
--color-plain-3: #dae1e9;
|
||||
--color-grey-1: #bdbdbd;
|
||||
--color-grey-2: #9e9e9e;
|
||||
--color-grey-3: #757575;
|
||||
--color-dark-1: #62778d;
|
||||
--color-dark-2: #526273;
|
||||
--color-dark-3: #425064; }
|
||||
|
||||
:host {
|
||||
display: inline-flex; }
|
||||
</style>
|
||||
<slot />
|
||||
`
|
||||
|
||||
}
|
||||
|
||||
_updateChildrenStat() {
|
||||
Array.from(this.children).forEach(it => {
|
||||
if (it.tagName === 'WC-RADIO-ITEM' && it.root) {
|
||||
if (it.value === this.props.value) {
|
||||
it.checked = true
|
||||
} else {
|
||||
it.checked = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.props.value
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
if (val === this.props.value) {
|
||||
return
|
||||
}
|
||||
this.props.value = val
|
||||
this._updateChildrenStat()
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this._pickedFn = $.bind(this, 'child-picked', ev => {
|
||||
log('radio picked: ', ev.detail)
|
||||
this.value = ev.detail
|
||||
this.dispatchEvent(new CustomEvent('input'))
|
||||
})
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
$.unbind(this, 'child-picked', this._pickedFn)
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {return}
|
||||
switch (name) {
|
||||
case 'value':
|
||||
this.value = val
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!customElements.get('wc-radio')){
|
||||
customElements.define('wc-radio', Radio)
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,12 +1,300 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
import $ from"../utils.js";export default class Star extends HTMLElement{static get observedAttributes(){return["value","text","size","color","'allow-half'","'show-value'","starSize","disabled"]}props={value:0,text:[],size:"",color:"","allow-half":!1,"show-value":!1,starSize:32,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:flex;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;cursor:pointer;font-size:14px;--size: 24px}label{display:flex;align-items:center;line-height:1;cursor:inherit}label wc-icon{margin:0 3px;transition:transform .1s easein-out}label wc-icon:hover{transform:scale(1.05)}label span{padding:0 8px;margin:0 3px}:host([size=large]){font-size:16px;--size: 36px}:host([size=medium]){--size: 30px}:host([size=mini]){font-size:12px;--size: 20px}:host([type=danger]) label span{color:var(--color-red-1)}:host([type=primary]) label span{color:var(--color-teal-1)}:host([type=success]) label span{color:var(--color-green-1)}:host([type=default]) label span{color:var(--color-grey-1)}:host([type=info]) label span{color:var(--color-blue-1)}:host([color=purple]) label span{color:var(--color-purple-1)}:host([type=warning]) label span{color:var(--color-orange-1)}:host([disabled]){cursor:default;opacity:.6}:host([disabled]) label wc-icon:hover{transform:none}</style> <label> <wc-icon data-idx="0" is="star" color="grey"></wc-icon> <wc-icon data-idx="1" is="star" color="grey"></wc-icon> <wc-icon data-idx="2" is="star" color="grey"></wc-icon> <wc-icon data-idx="3" is="star" color="grey"></wc-icon> <wc-icon data-idx="4" is="star" color="grey"></wc-icon> <span class="text"></span> </label> ',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(t){var e=+t;(t=e==e&&e>0?e:0)>5&&(t=5),this.props.value=t,this._updateDraw(-1)}_updateDraw(t,e=0){var s="star-half",{value:o,tmp:a={i:0,f:0}}=this.props;-1===t&&(t=Math.floor(o),e=+(o%1).toFixed(1),t>0&&t===o&&(t--,e=1)),this.props["allow-half"]||(e=e>0?1:0),t===a.i&&e===a.f||(e>.5&&(s="star-full"),this.__STARS__.forEach((e,s)=>{e.setAttribute("is",s<t?"star-full":"star"),e.setAttribute("color",s<t?this.props.color:"grey")}),e>0&&(this.__STARS__[t].setAttribute("is",s),this.__STARS__[t].setAttribute("color",this.props.color)),this.props.tmp={i:t,f:e},0===t&&0===e?this.__TEXT__.textContent="":5===this.props.text.length?this.__TEXT__.textContent=this.props.text[t]:this.props["show-value"]&&(this.__TEXT__.textContent=t+e))}connectedCallback(){$.catch(this.__BOX__,"mousemove",t=>{if(!this.props.disabled&&"WC-ICON"===t.target.tagName){let e=+t.target.dataset.idx;this._updateDraw(e,+(t.offsetX/this.props.starSize).toFixed(1))}}),$.catch(this.__BOX__,"click",t=>{var{tmp:e,disabled:s}=this.props;s||"WC-ICON"===t.target.tagName&&(this.props.value=e.i+e.f,this.dispatchEvent(new CustomEvent("input")))}),$.catch(this.__BOX__,"mouseleave",t=>{this.props.disabled||this._updateDraw(-1)})}attributeChangedCallback(t,e,s){if(e!==s)switch(t){case"size":this.props.starSize=this.__STARS__[0].clientWidth;break;case"allow-half":case"show-value":case"disabled":this.props[t]=!0;break;case"color":s&&(this.props.color=s);break;case"text":s&&5===(s=s.split("|")).length&&(this.props.text=s.map(t=>t.trim()));break;case"value":this.value=s}}}
|
||||
|
||||
import $ from "../utils.js"
|
||||
|
||||
export default class Star extends HTMLElement {
|
||||
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["value","text","size","color","'allow-half'","'show-value'","starSize","disabled"]
|
||||
}
|
||||
|
||||
props = {
|
||||
value: 0,
|
||||
text: [],
|
||||
size: '',
|
||||
color: '',
|
||||
'allow-half': false,
|
||||
'show-value': false,
|
||||
starSize: 32, // 星星的宽度, 用于实现半星
|
||||
disabled: false
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
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 {
|
||||
--color-teal-1: #4db6ac;
|
||||
--color-teal-2: #26a69a;
|
||||
--color-teal-3: #009688;
|
||||
--color-green-1: #81c784;
|
||||
--color-green-2: #66bb6a;
|
||||
--color-green-3: #4caf50;
|
||||
--color-purple-1: #9575cd;
|
||||
--color-purple-2: #9575cd;
|
||||
--color-purple-3: #673ab7;
|
||||
--color-blue-1: #64b5f6;
|
||||
--color-blue-2: #42a5f5;
|
||||
--color-blue-3: #2196f3;
|
||||
--color-red-1: #ff5061;
|
||||
--color-red-2: #eb3b48;
|
||||
--color-red-3: #ce3742;
|
||||
--color-orange-1: #ffb618;
|
||||
--color-orange-2: #f39c12;
|
||||
--color-orange-3: #e67e22;
|
||||
--color-plain-1: #f2f5fc;
|
||||
--color-plain-2: #e8ebf4;
|
||||
--color-plain-3: #dae1e9;
|
||||
--color-grey-1: #bdbdbd;
|
||||
--color-grey-2: #9e9e9e;
|
||||
--color-grey-3: #757575;
|
||||
--color-dark-1: #62778d;
|
||||
--color-dark-2: #526273;
|
||||
--color-dark-3: #425064; }
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
--size: 24px; }
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 0;
|
||||
cursor: inherit; }
|
||||
label wc-icon {
|
||||
margin: 0 3px;
|
||||
transition: transform 0.1s easein-out; }
|
||||
label wc-icon:hover {
|
||||
transform: scale(1.05); }
|
||||
label span {
|
||||
padding: 0 8px;
|
||||
margin: 0 3px; }
|
||||
|
||||
:host([size='large']) {
|
||||
font-size: 16px;
|
||||
--size: 36px; }
|
||||
|
||||
:host([size='medium']) {
|
||||
--size: 30px; }
|
||||
|
||||
:host([size='mini']) {
|
||||
font-size: 12px;
|
||||
--size: 20px; }
|
||||
|
||||
:host([color='red']) label span {
|
||||
color: var(--color-red-1); }
|
||||
|
||||
:host([color='teal']) label span {
|
||||
color: var(--color-teal-1); }
|
||||
|
||||
:host([color='green']) label span {
|
||||
color: var(--color-green-1); }
|
||||
|
||||
:host([color='grey']) label span {
|
||||
color: var(--color-grey-1); }
|
||||
|
||||
:host([color='blue']) label span {
|
||||
color: var(--color-blue-1); }
|
||||
|
||||
:host([color='purple']) label span {
|
||||
color: var(--color-purple-1); }
|
||||
|
||||
:host([color='orange']) label span {
|
||||
color: var(--color-orange-1); }
|
||||
|
||||
:host([disabled]) {
|
||||
cursor: default;
|
||||
opacity: 0.6; }
|
||||
:host([disabled]) label wc-icon:hover {
|
||||
transform: none; }
|
||||
</style>
|
||||
<label>
|
||||
<wc-icon data-idx="0" is="star" color="grey"></wc-icon>
|
||||
<wc-icon data-idx="1" is="star" color="grey"></wc-icon>
|
||||
<wc-icon data-idx="2" is="star" color="grey"></wc-icon>
|
||||
<wc-icon data-idx="3" is="star" color="grey"></wc-icon>
|
||||
<wc-icon data-idx="4" is="star" color="grey"></wc-icon>
|
||||
<span class="text"></span>
|
||||
</label>
|
||||
`
|
||||
|
||||
|
||||
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(val) {
|
||||
var v = +val
|
||||
var tmp = val >> 0
|
||||
if (v === v && v > 0) {
|
||||
val = v
|
||||
} else {
|
||||
val = 0
|
||||
}
|
||||
|
||||
if (val > 5) {
|
||||
val = 5
|
||||
}
|
||||
|
||||
this.props.value = val
|
||||
this._updateDraw(-1)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新图标渲染
|
||||
* i: int
|
||||
* f: float
|
||||
*/
|
||||
_updateDraw(i, f = 0) {
|
||||
var _last = 'star-half'
|
||||
var { value, tmp = { i: 0, f: 0 } } = this.props
|
||||
|
||||
if (i === -1) {
|
||||
i = Math.floor(value)
|
||||
f = +(value % 1).toFixed(1)
|
||||
if (i > 0 && i === value) {
|
||||
i--
|
||||
f = 1
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.props['allow-half']) {
|
||||
f = f > 0 ? 1 : 0
|
||||
}
|
||||
// 减少DOM操作
|
||||
if (i === tmp.i && f === tmp.f) {
|
||||
return
|
||||
}
|
||||
|
||||
if (f > 0.5) {
|
||||
_last = 'star-full'
|
||||
}
|
||||
|
||||
this.__STARS__.forEach((it, k) => {
|
||||
it.setAttribute('is', k < i ? 'star-full' : 'star')
|
||||
it.setAttribute('color', k < i ? this.props.color : 'grey')
|
||||
})
|
||||
|
||||
if (f > 0) {
|
||||
this.__STARS__[i].setAttribute('is', _last)
|
||||
this.__STARS__[i].setAttribute('color', this.props.color)
|
||||
}
|
||||
|
||||
// 缓存结果
|
||||
this.props.tmp = { i, f }
|
||||
|
||||
if (i === 0 && f === 0) {
|
||||
this.__TEXT__.textContent = ''
|
||||
} else {
|
||||
if (this.props.text.length === 5) {
|
||||
this.__TEXT__.textContent = this.props.text[i]
|
||||
} else {
|
||||
if (this.props['show-value']) {
|
||||
this.__TEXT__.textContent = i + f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
$.catch(this.__BOX__, 'mousemove', ev => {
|
||||
if (this.props.disabled) {
|
||||
return
|
||||
}
|
||||
if (ev.target.tagName === 'WC-ICON') {
|
||||
let idx = +ev.target.dataset.idx
|
||||
this._updateDraw(idx, +(ev.offsetX / this.props.starSize).toFixed(1))
|
||||
}
|
||||
})
|
||||
|
||||
$.catch(this.__BOX__, 'click', ev => {
|
||||
var { tmp, disabled } = this.props
|
||||
if (disabled) {
|
||||
return
|
||||
}
|
||||
if (ev.target.tagName === 'WC-ICON') {
|
||||
this.props.value = tmp.i + tmp.f
|
||||
this.dispatchEvent(new CustomEvent('input'))
|
||||
}
|
||||
})
|
||||
|
||||
$.catch(this.__BOX__, 'mouseleave', ev => {
|
||||
if (this.props.disabled) {
|
||||
return
|
||||
}
|
||||
this._updateDraw(-1)
|
||||
})
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {return}
|
||||
switch (name) {
|
||||
case 'size':
|
||||
this.props.starSize = this.__STARS__[0].clientWidth
|
||||
break
|
||||
|
||||
case 'allow-half':
|
||||
case 'show-value':
|
||||
case 'disabled':
|
||||
this.props[name] = true
|
||||
break
|
||||
|
||||
case 'color':
|
||||
if (val) {
|
||||
this.props.color = val
|
||||
}
|
||||
break
|
||||
|
||||
case 'text':
|
||||
if (val) {
|
||||
val = val.split('|')
|
||||
if (val.length === 5) {
|
||||
this.props.text = val.map(it => it.trim())
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
case 'value':
|
||||
this.value = val
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!customElements.get('wc-star')){
|
||||
customElements.define('wc-star', Star)
|
||||
|
|
|
@ -1,12 +1,240 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
* @date 2020-12-08 11:30:52
|
||||
* @version v1.0.0
|
||||
*
|
||||
*/
|
||||
|
||||
import $ from"../utils.js";export default class Switch extends HTMLElement{static get observedAttributes(){return["'active-text'","'inactive-text'","checked","disabled"]}props={"active-text":null,"inactive-text":null,checked:!1,disabled:!1};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-block}:host section{display:flex;justify-content:center;align-items:center;line-height:1;white-space:nowrap}:host label{display:flex;align-items:center;width:32px;height:18px;padding:3px;margin:5px;border-radius:21px;background:var(--color-plain-3);cursor:inherit}:host label.checked{flex-direction:row-reverse;background:var(--color-grey-3)}:host .dot{width:12px;height:12px;border-radius:50%;background:#fff}:host([disabled]){cursor:not-allowed;opacity:.6}:host([size=large]) label{width:46px;height:26px;padding:3px 5px}:host([size=large]) .dot{width:18px;height:18px}:host([size=medium]) label{width:38px;height:22px;padding:3px 4px}:host([size=medium]) .dot{width:16px;height:16px}:host([size=mini]) label{width:22px;height:14px;padding:2px}:host([size=mini]) .dot{width:10px;height:10px}:host([type=danger]) label.checked{background:var(--color-red-1)}:host([type=info]) label.checked{background:var(--color-blue-1)}:host([type=success]) label.checked{background:var(--color-green-1)}:host([type=primary]) label.checked{background:var(--color-teal-1)}:host([type=warning]) label.checked{background:var(--color-orange-1)}:host([type=inverse]) label.checked{background:var(--color-dark-1)}:host([color=purple]) label.checked{background:var(--color-purple-1)}</style> <section> <label> <span class="dot"></span> </label> <slot></slot> </section> ',this.__SWITCH__=this.root.lastElementChild.firstElementChild}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(t!==i)switch(e){case"checked":case"disabled":this[e]=!0;break;case"active-text":case"inactive-text":this.props[e]=i+""}}}
|
||||
|
||||
import $ from "../utils.js"
|
||||
export default class Switch extends HTMLElement {
|
||||
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["'active-text'","'inactive-text'","checked","disabled"]
|
||||
}
|
||||
|
||||
props = {
|
||||
'active-text': null,
|
||||
'inactive-text': null,
|
||||
checked: false,
|
||||
disabled: false
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Object.defineProperty(this, 'root', {
|
||||
value: this.attachShadow({ mode: 'open' }),
|
||||
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 {
|
||||
--color-teal-1: #4db6ac;
|
||||
--color-teal-2: #26a69a;
|
||||
--color-teal-3: #009688;
|
||||
--color-green-1: #81c784;
|
||||
--color-green-2: #66bb6a;
|
||||
--color-green-3: #4caf50;
|
||||
--color-purple-1: #9575cd;
|
||||
--color-purple-2: #9575cd;
|
||||
--color-purple-3: #673ab7;
|
||||
--color-blue-1: #64b5f6;
|
||||
--color-blue-2: #42a5f5;
|
||||
--color-blue-3: #2196f3;
|
||||
--color-red-1: #ff5061;
|
||||
--color-red-2: #eb3b48;
|
||||
--color-red-3: #ce3742;
|
||||
--color-orange-1: #ffb618;
|
||||
--color-orange-2: #f39c12;
|
||||
--color-orange-3: #e67e22;
|
||||
--color-plain-1: #f2f5fc;
|
||||
--color-plain-2: #e8ebf4;
|
||||
--color-plain-3: #dae1e9;
|
||||
--color-grey-1: #bdbdbd;
|
||||
--color-grey-2: #9e9e9e;
|
||||
--color-grey-3: #757575;
|
||||
--color-dark-1: #62778d;
|
||||
--color-dark-2: #526273;
|
||||
--color-dark-3: #425064; }
|
||||
|
||||
:host {
|
||||
display: inline-block; }
|
||||
:host section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
line-height: 0;
|
||||
white-space: nowrap; }
|
||||
:host label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 32px;
|
||||
height: 18px;
|
||||
padding: 3px;
|
||||
margin: 5px;
|
||||
border-radius: 21px;
|
||||
background: var(--color-plain-3);
|
||||
cursor: inherit; }
|
||||
:host label.checked {
|
||||
flex-direction: row-reverse;
|
||||
background: var(--color-grey-3); }
|
||||
:host .dot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
background: #fff; }
|
||||
|
||||
:host([disabled]) {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6; }
|
||||
|
||||
:host([size='large']) label {
|
||||
width: 46px;
|
||||
height: 26px;
|
||||
padding: 3px 5px; }
|
||||
|
||||
:host([size='large']) .dot {
|
||||
width: 18px;
|
||||
height: 18px; }
|
||||
|
||||
:host([size='medium']) label {
|
||||
width: 38px;
|
||||
height: 22px;
|
||||
padding: 3px 4px; }
|
||||
|
||||
:host([size='medium']) .dot {
|
||||
width: 16px;
|
||||
height: 16px; }
|
||||
|
||||
:host([size='mini']) label {
|
||||
width: 22px;
|
||||
height: 14px;
|
||||
padding: 2px; }
|
||||
|
||||
:host([size='mini']) .dot {
|
||||
width: 10px;
|
||||
height: 10px; }
|
||||
|
||||
:host([color='red']) label.checked {
|
||||
background: var(--color-red-1); }
|
||||
|
||||
:host([color='blue']) label.checked {
|
||||
background: var(--color-blue-1); }
|
||||
|
||||
:host([color='green']) label.checked {
|
||||
background: var(--color-green-1); }
|
||||
|
||||
:host([color='teal']) label.checked {
|
||||
background: var(--color-teal-1); }
|
||||
|
||||
:host([color='orange']) label.checked {
|
||||
background: var(--color-orange-1); }
|
||||
|
||||
:host([color='dark']) label.checked {
|
||||
background: var(--color-dark-1); }
|
||||
|
||||
:host([color='purple']) label.checked {
|
||||
background: var(--color-purple-1); }
|
||||
</style>
|
||||
<section>
|
||||
<label>
|
||||
<span class="dot"></span>
|
||||
</label>
|
||||
<slot></slot>
|
||||
</section>
|
||||
`
|
||||
|
||||
|
||||
this.__SWITCH__ = this.root.lastElementChild.firstElementChild
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this.props.checked
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
this.checked = val
|
||||
}
|
||||
|
||||
get checked() {
|
||||
return this.props.checked
|
||||
}
|
||||
|
||||
set checked(val) {
|
||||
this.props.checked = !!val
|
||||
this.__SWITCH__.classList.toggle('checked', this.props.checked)
|
||||
}
|
||||
|
||||
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._handleClick = $.bind(this, 'click', ev => {
|
||||
if (this.disabled) {
|
||||
return
|
||||
}
|
||||
this.checked = !this.checked
|
||||
if (this.checked) {
|
||||
if (this.props['active-text'] !== null) {
|
||||
this.textContent = this.props['active-text']
|
||||
}
|
||||
} else {
|
||||
if (this.props['inactive-text'] !== null) {
|
||||
this.textContent = this.props['inactive-text']
|
||||
}
|
||||
}
|
||||
this.dispatchEvent(new CustomEvent('input'))
|
||||
})
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
$.unbind(this, 'click', this._handleClick)
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, old, val) {
|
||||
if (val === null || old === val) {return}
|
||||
switch (name) {
|
||||
case 'checked':
|
||||
case 'disabled':
|
||||
this[name] = true
|
||||
break
|
||||
case 'active-text':
|
||||
case 'inactive-text':
|
||||
this.props[name] = val + ''
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!customElements.get('wc-switch')){
|
||||
customElements.define('wc-switch', Switch)
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,12 +1,14 @@
|
|||
/**
|
||||
*
|
||||
* @authors yutent (yutent.io@gmail.com)
|
||||
* @date 2021-02-05 16:32:07
|
||||
* @version v1.0.3
|
||||
* @authors yutent (yutent@doui.cc)
|
||||
* @date 2020-07-07 16:27:17
|
||||
* @version v2.0.1
|
||||
*
|
||||
*/
|
||||
|
||||
import SVG_DICT from"./svg.js";let dict=SVG_DICT;window.EXT_SVG_DICT&&Object.assign(dict,EXT_SVG_DICT);export default class Icon extends HTMLElement{static get observedAttributes(){return["is"]}props={is:""};constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),this.root.innerHTML='<style>*{box-sizing:border-box;margin:0;padding:0}::before,::after{box-sizing:border-box}:host{display:inline-flex;width:var(--size, 32px);height:var(--size, 32px);color:inherit}:host(:not([is])){display:none}.icon{display:block;fill:currentColor}.icon.load{animation:load 1.5s linear infinite}.icon circle{stroke:currentColor;animation:circle 1.5s ease-in-out infinite}:host([size=large]){width:52px;height:52px}:host([size=medium]){width:36px;height:36px}:host([size=mini]){width:26px;height:26px}:host([red]){color:var(--color-red-1)}:host([blue]){color:var(--color-blue-1)}:host([green]){color:var(--color-green-1)}:host([orange]){color:var(--color-orange-1)}:host([grey]){color:var(--color-grey-1)}:host([dark]){color:var(--color-dark-1)}@keyframes circle{0%{stroke-dasharray:0,3812px;stroke-dashoffset:0}50%{stroke-dasharray:1906px,3812px;stroke-dashoffset:-287px}100%{stroke-dasharray:1906px,3812px;stroke-dashoffset:-2393px}}@keyframes load{to{transform:rotate(360deg)}}</style> <svg class="icon" viewBox="0 0 1024 1024"></svg> ',this.__ICO__=this.root.lastElementChild,this.drawPath()}get is(){return this.props.is}set is(t){t&&this.setAttribute("is",t)}drawPath(){var{is:t}=this.props,o=dict[t];this.__ICO__&&t&&o&&(this.__ICO__.innerHTML="loading"===t?o:`<path d="${o}" />`,this.__ICO__.classList.toggle("load","loading"===t))}attributeChangedCallback(t,o,e){if(o!==e)switch(t){case"is":this.props.is=e,e?this.drawPath():this.removeAttribute("is")}}}
|
||||
'use strict'
|
||||
|
||||
import SVG_DICT from"./svg.js";let dict=SVG_DICT;window.EXT_SVG_DICT&&Object.assign(dict,EXT_SVG_DICT);export default class Icon extends HTMLElement{static get observedAttributes(){return["is"]}constructor(){super(),Object.defineProperty(this,"root",{value:this.attachShadow({mode:"open"}),writable:!0,enumerable:!1,configurable:!0}),Object.defineProperty(this,"props",{value:{is:""},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;color:inherit}:host(:not([is])){display:none}.icon{display:block;width:var(--size, 32px);height:var(--size, 32px);margin:var(--pad, auto);fill:currentColor}.icon.load{animation:load 1.5s linear infinite}.icon circle{stroke:currentColor;animation:circle 1.5s ease-in-out infinite}:host([size='large']) .icon{width:42px;height:42px}:host([size='medium']) .icon{width:38px;height:38px}:host([size='mini']) .icon{width:20px;height:20px}:host([color='red']){color:#ff5061}:host([color='blue']){color:#64b5f6}:host([color='green']){color:#81c784}:host([color='teal']){color:#4db6ac}:host([color='orange']){color:#ffb618}:host([color='dark']){color:#62778d}:host([color='purple']){color:#9575cd}:host([color='grey']){color:#bdbdbd}@keyframes circle{0%{stroke-dasharray:0, 3812px;stroke-dashoffset:0}50%{stroke-dasharray:1906px, 3812px;stroke-dashoffset:-287px}100%{stroke-dasharray:1906px, 3812px;stroke-dashoffset:-2393px}}@keyframes load{to{transform:rotate(360deg)}}</style> <svg class=\"icon\" viewBox=\"0 0 1024 1024\"></svg> ",this.__ICO__=this.root.lastElementChild,this.drawPath()}get is(){return this.props.is}set is(o){o&&this.setAttribute("is",o)}drawPath(){var{is:o}=this.props,t=dict[o];this.__ICO__&&o&&t&&(this.__ICO__.innerHTML="loading"===o?t:`<path d="${t}" />`,this.__ICO__.classList.toggle("load","loading"===o))}attributeChangedCallback(o,t,e){if(null!==e&&t!==e)switch(o){case"is":this.props.is=e,e?this.drawPath():this.removeAttribute("is")}}};
|
||||
|
||||
if(!customElements.get('wc-icon')){
|
||||
customElements.define('wc-icon', Icon)
|
||||
|
|
File diff suppressed because one or more lines are too long
764
src/lib/md5.js
764
src/lib/md5.js
|
@ -1,764 +0,0 @@
|
|||
/*
|
||||
* Fastest md5 implementation around (JKM md5).
|
||||
* Credits: Joseph Myers
|
||||
*
|
||||
* @see http://www.myersdaily.org/joseph/javascript/md5-text.html
|
||||
* @see http://jsperf.com/md5-shootout/7
|
||||
*/
|
||||
|
||||
/* this function is much faster,
|
||||
so if possible we use it. Some IEs
|
||||
are the only ones I know of that
|
||||
need the idiotic second function,
|
||||
generated by an if clause. */
|
||||
var add32 = function(a, b) {
|
||||
return (a + b) & 0xffffffff
|
||||
},
|
||||
hex_chr = [
|
||||
'0',
|
||||
'1',
|
||||
'2',
|
||||
'3',
|
||||
'4',
|
||||
'5',
|
||||
'6',
|
||||
'7',
|
||||
'8',
|
||||
'9',
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
'd',
|
||||
'e',
|
||||
'f'
|
||||
]
|
||||
|
||||
function cmn(q, a, b, x, s, t) {
|
||||
a = add32(add32(a, q), add32(x, t))
|
||||
return add32((a << s) | (a >>> (32 - s)), b)
|
||||
}
|
||||
|
||||
function md5cycle(x, k) {
|
||||
var a = x[0],
|
||||
b = x[1],
|
||||
c = x[2],
|
||||
d = x[3]
|
||||
|
||||
a += (((b & c) | (~b & d)) + k[0] - 680876936) | 0
|
||||
a = (((a << 7) | (a >>> 25)) + b) | 0
|
||||
d += (((a & b) | (~a & c)) + k[1] - 389564586) | 0
|
||||
d = (((d << 12) | (d >>> 20)) + a) | 0
|
||||
c += (((d & a) | (~d & b)) + k[2] + 606105819) | 0
|
||||
c = (((c << 17) | (c >>> 15)) + d) | 0
|
||||
b += (((c & d) | (~c & a)) + k[3] - 1044525330) | 0
|
||||
b = (((b << 22) | (b >>> 10)) + c) | 0
|
||||
a += (((b & c) | (~b & d)) + k[4] - 176418897) | 0
|
||||
a = (((a << 7) | (a >>> 25)) + b) | 0
|
||||
d += (((a & b) | (~a & c)) + k[5] + 1200080426) | 0
|
||||
d = (((d << 12) | (d >>> 20)) + a) | 0
|
||||
c += (((d & a) | (~d & b)) + k[6] - 1473231341) | 0
|
||||
c = (((c << 17) | (c >>> 15)) + d) | 0
|
||||
b += (((c & d) | (~c & a)) + k[7] - 45705983) | 0
|
||||
b = (((b << 22) | (b >>> 10)) + c) | 0
|
||||
a += (((b & c) | (~b & d)) + k[8] + 1770035416) | 0
|
||||
a = (((a << 7) | (a >>> 25)) + b) | 0
|
||||
d += (((a & b) | (~a & c)) + k[9] - 1958414417) | 0
|
||||
d = (((d << 12) | (d >>> 20)) + a) | 0
|
||||
c += (((d & a) | (~d & b)) + k[10] - 42063) | 0
|
||||
c = (((c << 17) | (c >>> 15)) + d) | 0
|
||||
b += (((c & d) | (~c & a)) + k[11] - 1990404162) | 0
|
||||
b = (((b << 22) | (b >>> 10)) + c) | 0
|
||||
a += (((b & c) | (~b & d)) + k[12] + 1804603682) | 0
|
||||
a = (((a << 7) | (a >>> 25)) + b) | 0
|
||||
d += (((a & b) | (~a & c)) + k[13] - 40341101) | 0
|
||||
d = (((d << 12) | (d >>> 20)) + a) | 0
|
||||
c += (((d & a) | (~d & b)) + k[14] - 1502002290) | 0
|
||||
c = (((c << 17) | (c >>> 15)) + d) | 0
|
||||
b += (((c & d) | (~c & a)) + k[15] + 1236535329) | 0
|
||||
b = (((b << 22) | (b >>> 10)) + c) | 0
|
||||
|
||||
a += (((b & d) | (c & ~d)) + k[1] - 165796510) | 0
|
||||
a = (((a << 5) | (a >>> 27)) + b) | 0
|
||||
d += (((a & c) | (b & ~c)) + k[6] - 1069501632) | 0
|
||||
d = (((d << 9) | (d >>> 23)) + a) | 0
|
||||
c += (((d & b) | (a & ~b)) + k[11] + 643717713) | 0
|
||||
c = (((c << 14) | (c >>> 18)) + d) | 0
|
||||
b += (((c & a) | (d & ~a)) + k[0] - 373897302) | 0
|
||||
b = (((b << 20) | (b >>> 12)) + c) | 0
|
||||
a += (((b & d) | (c & ~d)) + k[5] - 701558691) | 0
|
||||
a = (((a << 5) | (a >>> 27)) + b) | 0
|
||||
d += (((a & c) | (b & ~c)) + k[10] + 38016083) | 0
|
||||
d = (((d << 9) | (d >>> 23)) + a) | 0
|
||||
c += (((d & b) | (a & ~b)) + k[15] - 660478335) | 0
|
||||
c = (((c << 14) | (c >>> 18)) + d) | 0
|
||||
b += (((c & a) | (d & ~a)) + k[4] - 405537848) | 0
|
||||
b = (((b << 20) | (b >>> 12)) + c) | 0
|
||||
a += (((b & d) | (c & ~d)) + k[9] + 568446438) | 0
|
||||
a = (((a << 5) | (a >>> 27)) + b) | 0
|
||||
d += (((a & c) | (b & ~c)) + k[14] - 1019803690) | 0
|
||||
d = (((d << 9) | (d >>> 23)) + a) | 0
|
||||
c += (((d & b) | (a & ~b)) + k[3] - 187363961) | 0
|
||||
c = (((c << 14) | (c >>> 18)) + d) | 0
|
||||
b += (((c & a) | (d & ~a)) + k[8] + 1163531501) | 0
|
||||
b = (((b << 20) | (b >>> 12)) + c) | 0
|
||||
a += (((b & d) | (c & ~d)) + k[13] - 1444681467) | 0
|
||||
a = (((a << 5) | (a >>> 27)) + b) | 0
|
||||
d += (((a & c) | (b & ~c)) + k[2] - 51403784) | 0
|
||||
d = (((d << 9) | (d >>> 23)) + a) | 0
|
||||
c += (((d & b) | (a & ~b)) + k[7] + 1735328473) | 0
|
||||
c = (((c << 14) | (c >>> 18)) + d) | 0
|
||||
b += (((c & a) | (d & ~a)) + k[12] - 1926607734) | 0
|
||||
b = (((b << 20) | (b >>> 12)) + c) | 0
|
||||
|
||||
a += ((b ^ c ^ d) + k[5] - 378558) | 0
|
||||
a = (((a << 4) | (a >>> 28)) + b) | 0
|
||||
d += ((a ^ b ^ c) + k[8] - 2022574463) | 0
|
||||
d = (((d << 11) | (d >>> 21)) + a) | 0
|
||||
c += ((d ^ a ^ b) + k[11] + 1839030562) | 0
|
||||
c = (((c << 16) | (c >>> 16)) + d) | 0
|
||||
b += ((c ^ d ^ a) + k[14] - 35309556) | 0
|
||||
b = (((b << 23) | (b >>> 9)) + c) | 0
|
||||
a += ((b ^ c ^ d) + k[1] - 1530992060) | 0
|
||||
a = (((a << 4) | (a >>> 28)) + b) | 0
|
||||
d += ((a ^ b ^ c) + k[4] + 1272893353) | 0
|
||||
d = (((d << 11) | (d >>> 21)) + a) | 0
|
||||
c += ((d ^ a ^ b) + k[7] - 155497632) | 0
|
||||
c = (((c << 16) | (c >>> 16)) + d) | 0
|
||||
b += ((c ^ d ^ a) + k[10] - 1094730640) | 0
|
||||
b = (((b << 23) | (b >>> 9)) + c) | 0
|
||||
a += ((b ^ c ^ d) + k[13] + 681279174) | 0
|
||||
a = (((a << 4) | (a >>> 28)) + b) | 0
|
||||
d += ((a ^ b ^ c) + k[0] - 358537222) | 0
|
||||
d = (((d << 11) | (d >>> 21)) + a) | 0
|
||||
c += ((d ^ a ^ b) + k[3] - 722521979) | 0
|
||||
c = (((c << 16) | (c >>> 16)) + d) | 0
|
||||
b += ((c ^ d ^ a) + k[6] + 76029189) | 0
|
||||
b = (((b << 23) | (b >>> 9)) + c) | 0
|
||||
a += ((b ^ c ^ d) + k[9] - 640364487) | 0
|
||||
a = (((a << 4) | (a >>> 28)) + b) | 0
|
||||
d += ((a ^ b ^ c) + k[12] - 421815835) | 0
|
||||
d = (((d << 11) | (d >>> 21)) + a) | 0
|
||||
c += ((d ^ a ^ b) + k[15] + 530742520) | 0
|
||||
c = (((c << 16) | (c >>> 16)) + d) | 0
|
||||
b += ((c ^ d ^ a) + k[2] - 995338651) | 0
|
||||
b = (((b << 23) | (b >>> 9)) + c) | 0
|
||||
|
||||
a += ((c ^ (b | ~d)) + k[0] - 198630844) | 0
|
||||
a = (((a << 6) | (a >>> 26)) + b) | 0
|
||||
d += ((b ^ (a | ~c)) + k[7] + 1126891415) | 0
|
||||
d = (((d << 10) | (d >>> 22)) + a) | 0
|
||||
c += ((a ^ (d | ~b)) + k[14] - 1416354905) | 0
|
||||
c = (((c << 15) | (c >>> 17)) + d) | 0
|
||||
b += ((d ^ (c | ~a)) + k[5] - 57434055) | 0
|
||||
b = (((b << 21) | (b >>> 11)) + c) | 0
|
||||
a += ((c ^ (b | ~d)) + k[12] + 1700485571) | 0
|
||||
a = (((a << 6) | (a >>> 26)) + b) | 0
|
||||
d += ((b ^ (a | ~c)) + k[3] - 1894986606) | 0
|
||||
d = (((d << 10) | (d >>> 22)) + a) | 0
|
||||
c += ((a ^ (d | ~b)) + k[10] - 1051523) | 0
|
||||
c = (((c << 15) | (c >>> 17)) + d) | 0
|
||||
b += ((d ^ (c | ~a)) + k[1] - 2054922799) | 0
|
||||
b = (((b << 21) | (b >>> 11)) + c) | 0
|
||||
a += ((c ^ (b | ~d)) + k[8] + 1873313359) | 0
|
||||
a = (((a << 6) | (a >>> 26)) + b) | 0
|
||||
d += ((b ^ (a | ~c)) + k[15] - 30611744) | 0
|
||||
d = (((d << 10) | (d >>> 22)) + a) | 0
|
||||
c += ((a ^ (d | ~b)) + k[6] - 1560198380) | 0
|
||||
c = (((c << 15) | (c >>> 17)) + d) | 0
|
||||
b += ((d ^ (c | ~a)) + k[13] + 1309151649) | 0
|
||||
b = (((b << 21) | (b >>> 11)) + c) | 0
|
||||
a += ((c ^ (b | ~d)) + k[4] - 145523070) | 0
|
||||
a = (((a << 6) | (a >>> 26)) + b) | 0
|
||||
d += ((b ^ (a | ~c)) + k[11] - 1120210379) | 0
|
||||
d = (((d << 10) | (d >>> 22)) + a) | 0
|
||||
c += ((a ^ (d | ~b)) + k[2] + 718787259) | 0
|
||||
c = (((c << 15) | (c >>> 17)) + d) | 0
|
||||
b += ((d ^ (c | ~a)) + k[9] - 343485551) | 0
|
||||
b = (((b << 21) | (b >>> 11)) + c) | 0
|
||||
|
||||
x[0] = (a + x[0]) | 0
|
||||
x[1] = (b + x[1]) | 0
|
||||
x[2] = (c + x[2]) | 0
|
||||
x[3] = (d + x[3]) | 0
|
||||
}
|
||||
|
||||
function md5blk(s) {
|
||||
var md5blks = [],
|
||||
i /* Andy King said do it this way. */
|
||||
|
||||
for (i = 0; i < 64; i += 4) {
|
||||
md5blks[i >> 2] =
|
||||
s.charCodeAt(i) +
|
||||
(s.charCodeAt(i + 1) << 8) +
|
||||
(s.charCodeAt(i + 2) << 16) +
|
||||
(s.charCodeAt(i + 3) << 24)
|
||||
}
|
||||
return md5blks
|
||||
}
|
||||
|
||||
function md5blk_array(a) {
|
||||
var md5blks = [],
|
||||
i /* Andy King said do it this way. */
|
||||
|
||||
for (i = 0; i < 64; i += 4) {
|
||||
md5blks[i >> 2] =
|
||||
a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24)
|
||||
}
|
||||
return md5blks
|
||||
}
|
||||
|
||||
function md51(s) {
|
||||
var n = s.length,
|
||||
state = [1732584193, -271733879, -1732584194, 271733878],
|
||||
i,
|
||||
length,
|
||||
tail,
|
||||
tmp,
|
||||
lo,
|
||||
hi
|
||||
|
||||
for (i = 64; i <= n; i += 64) {
|
||||
md5cycle(state, md5blk(s.substring(i - 64, i)))
|
||||
}
|
||||
s = s.substring(i - 64)
|
||||
length = s.length
|
||||
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
for (i = 0; i < length; i += 1) {
|
||||
tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3)
|
||||
}
|
||||
tail[i >> 2] |= 0x80 << (i % 4 << 3)
|
||||
if (i > 55) {
|
||||
md5cycle(state, tail)
|
||||
for (i = 0; i < 16; i += 1) {
|
||||
tail[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Beware that the final length might not fit in 32 bits so we take care of that
|
||||
tmp = n * 8
|
||||
tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/)
|
||||
lo = parseInt(tmp[2], 16)
|
||||
hi = parseInt(tmp[1], 16) || 0
|
||||
|
||||
tail[14] = lo
|
||||
tail[15] = hi
|
||||
|
||||
md5cycle(state, tail)
|
||||
return state
|
||||
}
|
||||
|
||||
function md51_array(a) {
|
||||
var n = a.length,
|
||||
state = [1732584193, -271733879, -1732584194, 271733878],
|
||||
i,
|
||||
length,
|
||||
tail,
|
||||
tmp,
|
||||
lo,
|
||||
hi
|
||||
|
||||
for (i = 64; i <= n; i += 64) {
|
||||
md5cycle(state, md5blk_array(a.subarray(i - 64, i)))
|
||||
}
|
||||
|
||||
// Not sure if it is a bug, however IE10 will always produce a sub array of length 1
|
||||
// containing the last element of the parent array if the sub array specified starts
|
||||
// beyond the length of the parent array - weird.
|
||||
// https://connect.microsoft.com/IE/feedback/details/771452/typed-array-subarray-issue
|
||||
a = i - 64 < n ? a.subarray(i - 64) : new Uint8Array(0)
|
||||
|
||||
length = a.length
|
||||
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
for (i = 0; i < length; i += 1) {
|
||||
tail[i >> 2] |= a[i] << (i % 4 << 3)
|
||||
}
|
||||
|
||||
tail[i >> 2] |= 0x80 << (i % 4 << 3)
|
||||
if (i > 55) {
|
||||
md5cycle(state, tail)
|
||||
for (i = 0; i < 16; i += 1) {
|
||||
tail[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Beware that the final length might not fit in 32 bits so we take care of that
|
||||
tmp = n * 8
|
||||
tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/)
|
||||
lo = parseInt(tmp[2], 16)
|
||||
hi = parseInt(tmp[1], 16) || 0
|
||||
|
||||
tail[14] = lo
|
||||
tail[15] = hi
|
||||
|
||||
md5cycle(state, tail)
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
function rhex(n) {
|
||||
var s = '',
|
||||
j
|
||||
for (j = 0; j < 4; j += 1) {
|
||||
s += hex_chr[(n >> (j * 8 + 4)) & 0x0f] + hex_chr[(n >> (j * 8)) & 0x0f]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
function hex(x) {
|
||||
var i
|
||||
for (i = 0; i < x.length; i += 1) {
|
||||
x[i] = rhex(x[i])
|
||||
}
|
||||
return x.join('')
|
||||
}
|
||||
|
||||
// In some cases the fast add32 function cannot be used..
|
||||
if (hex(md51('hello')) !== '5d41402abc4b2a76b9719d911017c592') {
|
||||
add32 = function(x, y) {
|
||||
var lsw = (x & 0xffff) + (y & 0xffff),
|
||||
msw = (x >> 16) + (y >> 16) + (lsw >> 16)
|
||||
return (msw << 16) | (lsw & 0xffff)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
||||
/**
|
||||
* ArrayBuffer slice polyfill.
|
||||
*
|
||||
* @see https://github.com/ttaubert/node-arraybuffer-slice
|
||||
*/
|
||||
|
||||
if (typeof ArrayBuffer !== 'undefined' && !ArrayBuffer.prototype.slice) {
|
||||
;(function() {
|
||||
function clamp(val, length) {
|
||||
val = val | 0 || 0
|
||||
|
||||
if (val < 0) {
|
||||
return Math.max(val + length, 0)
|
||||
}
|
||||
|
||||
return Math.min(val, length)
|
||||
}
|
||||
|
||||
ArrayBuffer.prototype.slice = function(from, to) {
|
||||
var length = this.byteLength,
|
||||
begin = clamp(from, length),
|
||||
end = length,
|
||||
num,
|
||||
target,
|
||||
targetArray,
|
||||
sourceArray
|
||||
|
||||
if (to !== undefined) {
|
||||
end = clamp(to, length)
|
||||
}
|
||||
|
||||
if (begin > end) {
|
||||
return new ArrayBuffer(0)
|
||||
}
|
||||
|
||||
num = end - begin
|
||||
target = new ArrayBuffer(num)
|
||||
targetArray = new Uint8Array(target)
|
||||
|
||||
sourceArray = new Uint8Array(this, begin, num)
|
||||
targetArray.set(sourceArray)
|
||||
|
||||
return target
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
||||
/**
|
||||
* Helpers.
|
||||
*/
|
||||
|
||||
function toUtf8(str) {
|
||||
str += ''
|
||||
if (/[\u0080-\uFFFF]/.test(str)) {
|
||||
str = unescape(encodeURIComponent(str))
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
function utf8Str2ArrayBuffer(str, returnUInt8Array) {
|
||||
var length = str.length,
|
||||
buff = new ArrayBuffer(length),
|
||||
arr = new Uint8Array(buff),
|
||||
i
|
||||
|
||||
for (i = 0; i < length; i += 1) {
|
||||
arr[i] = str.charCodeAt(i)
|
||||
}
|
||||
|
||||
return returnUInt8Array ? arr : buff
|
||||
}
|
||||
|
||||
function arrayBuffer2Utf8Str(buff) {
|
||||
return String.fromCharCode.apply(null, new Uint8Array(buff))
|
||||
}
|
||||
|
||||
function concatenateArrayBuffers(first, second, returnUInt8Array) {
|
||||
var result = new Uint8Array(first.byteLength + second.byteLength)
|
||||
|
||||
result.set(new Uint8Array(first))
|
||||
result.set(new Uint8Array(second), first.byteLength)
|
||||
|
||||
return returnUInt8Array ? result : result.buffer
|
||||
}
|
||||
|
||||
function hexToBinaryString(hex) {
|
||||
var bytes = [],
|
||||
length = hex.length,
|
||||
x
|
||||
|
||||
for (x = 0; x < length - 1; x += 2) {
|
||||
bytes.push(parseInt(hex.substr(x, 2), 16))
|
||||
}
|
||||
|
||||
return String.fromCharCode.apply(String, bytes)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
||||
/**
|
||||
* SparkMD5 OOP implementation.
|
||||
*
|
||||
* Use this class to perform an incremental md5, otherwise use the
|
||||
* static methods instead.
|
||||
*/
|
||||
|
||||
function SparkMD5() {
|
||||
// call reset to init the instance
|
||||
this.reset()
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string.
|
||||
* A conversion will be applied if an utf8 string is detected.
|
||||
*
|
||||
* @param {String} str The string to be appended
|
||||
*
|
||||
* @return {SparkMD5} The instance itself
|
||||
*/
|
||||
SparkMD5.prototype.append = function(str) {
|
||||
// Converts the string to utf8 bytes if necessary
|
||||
// Then append as binary
|
||||
this.appendBinary(toUtf8(str))
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a binary string.
|
||||
*
|
||||
* @param {String} contents The binary string to be appended
|
||||
*
|
||||
* @return {SparkMD5} The instance itself
|
||||
*/
|
||||
SparkMD5.prototype.appendBinary = function(contents) {
|
||||
this._buff += contents
|
||||
this._length += contents.length
|
||||
|
||||
var length = this._buff.length,
|
||||
i
|
||||
|
||||
for (i = 64; i <= length; i += 64) {
|
||||
md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)))
|
||||
}
|
||||
|
||||
this._buff = this._buff.substring(i - 64)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the incremental computation, reseting the internal state and
|
||||
* returning the result.
|
||||
*
|
||||
* @param {Boolean} raw True to get the raw string, false to get the hex string
|
||||
*
|
||||
* @return {String} The result
|
||||
*/
|
||||
SparkMD5.prototype.end = function(raw) {
|
||||
var buff = this._buff,
|
||||
length = buff.length,
|
||||
i,
|
||||
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
ret
|
||||
|
||||
for (i = 0; i < length; i += 1) {
|
||||
tail[i >> 2] |= buff.charCodeAt(i) << (i % 4 << 3)
|
||||
}
|
||||
|
||||
this._finish(tail, length)
|
||||
ret = hex(this._hash)
|
||||
|
||||
if (raw) {
|
||||
ret = hexToBinaryString(ret)
|
||||
}
|
||||
|
||||
this.reset()
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the internal state of the computation.
|
||||
*
|
||||
* @return {SparkMD5} The instance itself
|
||||
*/
|
||||
SparkMD5.prototype.reset = function() {
|
||||
this._buff = ''
|
||||
this._length = 0
|
||||
this._hash = [1732584193, -271733879, -1732584194, 271733878]
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the internal state of the computation.
|
||||
*
|
||||
* @return {Object} The state
|
||||
*/
|
||||
SparkMD5.prototype.getState = function() {
|
||||
return {
|
||||
buff: this._buff,
|
||||
length: this._length,
|
||||
hash: this._hash
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the internal state of the computation.
|
||||
*
|
||||
* @param {Object} state The state
|
||||
*
|
||||
* @return {SparkMD5} The instance itself
|
||||
*/
|
||||
SparkMD5.prototype.setState = function(state) {
|
||||
this._buff = state.buff
|
||||
this._length = state.length
|
||||
this._hash = state.hash
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases memory used by the incremental buffer and other additional
|
||||
* resources. If you plan to use the instance again, use reset instead.
|
||||
*/
|
||||
SparkMD5.prototype.destroy = function() {
|
||||
delete this._hash
|
||||
delete this._buff
|
||||
delete this._length
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the final calculation based on the tail.
|
||||
*
|
||||
* @param {Array} tail The tail (will be modified)
|
||||
* @param {Number} length The length of the remaining buffer
|
||||
*/
|
||||
SparkMD5.prototype._finish = function(tail, length) {
|
||||
var i = length,
|
||||
tmp,
|
||||
lo,
|
||||
hi
|
||||
|
||||
tail[i >> 2] |= 0x80 << (i % 4 << 3)
|
||||
if (i > 55) {
|
||||
md5cycle(this._hash, tail)
|
||||
for (i = 0; i < 16; i += 1) {
|
||||
tail[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Do the final computation based on the tail and length
|
||||
// Beware that the final length may not fit in 32 bits so we take care of that
|
||||
tmp = this._length * 8
|
||||
tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/)
|
||||
lo = parseInt(tmp[2], 16)
|
||||
hi = parseInt(tmp[1], 16) || 0
|
||||
|
||||
tail[14] = lo
|
||||
tail[15] = hi
|
||||
md5cycle(this._hash, tail)
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the md5 hash on a string.
|
||||
* A conversion will be applied if utf8 string is detected.
|
||||
*
|
||||
* @param {String} str The string
|
||||
* @param {Boolean} [raw] True to get the raw string, false to get the hex string
|
||||
*
|
||||
* @return {String} The result
|
||||
*/
|
||||
SparkMD5.hash = function(str, raw) {
|
||||
// Converts the string to utf8 bytes if necessary
|
||||
// Then compute it using the binary function
|
||||
return SparkMD5.hashBinary(toUtf8(str), raw)
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the md5 hash on a binary string.
|
||||
*
|
||||
* @param {String} content The binary string
|
||||
* @param {Boolean} [raw] True to get the raw string, false to get the hex string
|
||||
*
|
||||
* @return {String} The result
|
||||
*/
|
||||
SparkMD5.hashBinary = function(content, raw) {
|
||||
var hash = md51(content),
|
||||
ret = hex(hash)
|
||||
|
||||
return raw ? hexToBinaryString(ret) : ret
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
||||
/**
|
||||
* SparkMD5 OOP implementation for array buffers.
|
||||
*
|
||||
* Use this class to perform an incremental md5 ONLY for array buffers.
|
||||
*/
|
||||
SparkMD5.ArrayBuffer = function() {
|
||||
// call reset to init the instance
|
||||
this.reset()
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an array buffer.
|
||||
*
|
||||
* @param {ArrayBuffer} arr The array to be appended
|
||||
*
|
||||
* @return {SparkMD5.ArrayBuffer} The instance itself
|
||||
*/
|
||||
SparkMD5.ArrayBuffer.prototype.append = function(arr) {
|
||||
var buff = concatenateArrayBuffers(this._buff.buffer, arr, true),
|
||||
length = buff.length,
|
||||
i
|
||||
|
||||
this._length += arr.byteLength
|
||||
|
||||
for (i = 64; i <= length; i += 64) {
|
||||
md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)))
|
||||
}
|
||||
|
||||
this._buff =
|
||||
i - 64 < length
|
||||
? new Uint8Array(buff.buffer.slice(i - 64))
|
||||
: new Uint8Array(0)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the incremental computation, reseting the internal state and
|
||||
* returning the result.
|
||||
*
|
||||
* @param {Boolean} raw True to get the raw string, false to get the hex string
|
||||
*
|
||||
* @return {String} The result
|
||||
*/
|
||||
SparkMD5.ArrayBuffer.prototype.end = function(raw) {
|
||||
var buff = this._buff,
|
||||
length = buff.length,
|
||||
tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
i,
|
||||
ret
|
||||
|
||||
for (i = 0; i < length; i += 1) {
|
||||
tail[i >> 2] |= buff[i] << (i % 4 << 3)
|
||||
}
|
||||
|
||||
this._finish(tail, length)
|
||||
ret = hex(this._hash)
|
||||
|
||||
if (raw) {
|
||||
ret = hexToBinaryString(ret)
|
||||
}
|
||||
|
||||
this.reset()
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the internal state of the computation.
|
||||
*
|
||||
* @return {SparkMD5.ArrayBuffer} The instance itself
|
||||
*/
|
||||
SparkMD5.ArrayBuffer.prototype.reset = function() {
|
||||
this._buff = new Uint8Array(0)
|
||||
this._length = 0
|
||||
this._hash = [1732584193, -271733879, -1732584194, 271733878]
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the internal state of the computation.
|
||||
*
|
||||
* @return {Object} The state
|
||||
*/
|
||||
SparkMD5.ArrayBuffer.prototype.getState = function() {
|
||||
var state = SparkMD5.prototype.getState.call(this)
|
||||
|
||||
// Convert buffer to a string
|
||||
state.buff = arrayBuffer2Utf8Str(state.buff)
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the internal state of the computation.
|
||||
*
|
||||
* @param {Object} state The state
|
||||
*
|
||||
* @return {SparkMD5.ArrayBuffer} The instance itself
|
||||
*/
|
||||
SparkMD5.ArrayBuffer.prototype.setState = function(state) {
|
||||
// Convert string to buffer
|
||||
state.buff = utf8Str2ArrayBuffer(state.buff, true)
|
||||
|
||||
return SparkMD5.prototype.setState.call(this, state)
|
||||
}
|
||||
|
||||
SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy
|
||||
|
||||
SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish
|
||||
|
||||
/**
|
||||
* Performs the md5 hash on an array buffer.
|
||||
*
|
||||
* @param {ArrayBuffer} arr The array buffer
|
||||
* @param {Boolean} [raw] True to get the raw string, false to get the hex one
|
||||
*
|
||||
* @return {String} The result
|
||||
*/
|
||||
SparkMD5.ArrayBuffer.hash = function(arr, raw) {
|
||||
var hash = md51_array(new Uint8Array(arr)),
|
||||
ret = hex(hash)
|
||||
|
||||
return raw ? hexToBinaryString(ret) : ret
|
||||
}
|
||||
|
||||
var _sparkIns = new SparkMD5()
|
||||
|
||||
export function md5(str) {
|
||||
_sparkIns.append(str)
|
||||
return _sparkIns.end()
|
||||
}
|
||||
|
||||
export function md5Sum(binStr) {
|
||||
_sparkIns.appendBinary(binStr)
|
||||
return _sparkIns.end()
|
||||
}
|
||||
|
||||
export default _sparkIns
|
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
function noop(){}export default{nextTick:function(){let t=[];let e=document.createTextNode("\x3c!-- --\x3e");new MutationObserver((function(){let e=t.length;for(let n=0;n<e;n++)t[n]();t=t.slice(e)})).observe(e,{characterData:!0});let n=!1;return function(i){t.push(i),n=!n,e.data=n}}(),offset(t){try{var e=t.getBoundingClientRect();if(e.width||e.height||t.getClientRects().length){var n=t.ownerDocument,i=n.documentElement,o=n.defaultView;return{top:e.top+o.pageYOffset-i.clientTop,left:e.left+o.pageXOffset-i.clientLeft}}}catch(t){return{left:0,top:0}}},each(t,e){if(t)if(Array.isArray(t))for(let n,i=0;(n=t[i++])&&!1!==e(n,i-1););else for(let n in t)if(t.hasOwnProperty(n)&&!1===e(t[n],n))break},bind(t,e,n=noop,i=!1){let o=e.split(",");return this.each(o,(function(e){e=e.trim(),t.addEventListener(e,n,i)})),n},catch(t,e,n,i){return this.bind(t,e,(function(t){t.stopPropagation(),n&&n(t)}),i)},unbind(t,e,n=noop,i=!1){let o=e.split(",");this.each(o,(function(e){e=e.trim(),t.removeEventListener(e,n,i)}))},outside(t,e=noop){return this.bind(document,"mousedown",n=>{if(n)if(n.path){for(var i=n.path.concat();i.length>3;)if(i.shift()===t)return}else{var o=n.explicitOriginalTarget||n.target;if(t===o||t.contains(o)||t.root&&t.root.contains(o))return}e(n)})},clearOutside(t=noop){this.unbind(document,"mousedown",t)}};
|
||||
function noop(){}export default{nextTick:function(){let t=[];let e=document.createTextNode("\x3c!-- --\x3e");new MutationObserver(function(){let e=t.length;for(let n=0;n<e;n++)t[n]();t=t.slice(e)}).observe(e,{characterData:!0});let n=!1;return function(i){t.push(i),n=!n,e.data=n}}(),each(t,e){if(t)if(Array.isArray(t))for(let n,i=0;(n=t[i++])&&!1!==e(n,i-1););else for(let n in t)if(t.hasOwnProperty(n)&&!1===e(t[n],n))break},bind(t,e,n=noop,i=!1){let o=e.split(",");return this.each(o,function(e){e=e.trim(),t.addEventListener(e,n,i)}),n},catch(t,e,n,i){return this.bind(t,e,function(t){t.stopPropagation(),n&&n(t)},i)},unbind(t,e,n=noop,i=!1){let o=e.split(",");this.each(o,function(e){e=e.trim(),t.removeEventListener(e,n,i)})},outside(t,e=noop){return this.bind(document,"mousedown",n=>{if(n)if(n.path){for(var i=n.path.concat();i.length>3;)if(i.shift()===t)return}else{var o=n.explicitOriginalTarget||n.target;if(t===o||t.contains(o)||t.root&&t.root.contains(o))return}e(n)})},clearOutside(t=noop){this.unbind(document,"mousedown",t)}};
|
13
src/main.js
13
src/main.js
|
@ -9,7 +9,7 @@ const path = require('path')
|
|||
const fs = require('iofs')
|
||||
|
||||
require('./tools/init')
|
||||
const { createMainWindow, createViewWindow } = require('./tools/window')
|
||||
const { createMainWindow, createFloatWindow } = require('./tools/window')
|
||||
const createMenu = require('./tools/menu')
|
||||
const Socket = require('./tools/socket')
|
||||
|
||||
|
@ -44,13 +44,13 @@ protocol.registerSchemesAsPrivileged([
|
|||
|
||||
/* ----------------------------------------------------- */
|
||||
|
||||
// app.dock.hide()
|
||||
|
||||
// 初始化应用
|
||||
app.once('ready', () => {
|
||||
// 注册协议
|
||||
protocol.registerStreamProtocol('app', function(req, cb) {
|
||||
var file = decodeURIComponent(req.url.replace(/^app:\/\/local\//, ''))
|
||||
.replace(/\#.*$/, '')
|
||||
.replace(/\?.*$/, '')
|
||||
var ext = path.extname(file)
|
||||
|
||||
file = path.resolve(ROOT, file)
|
||||
|
@ -69,7 +69,7 @@ app.once('ready', () => {
|
|||
var ext = path.extname(file)
|
||||
|
||||
file = path.resolve(CACHE_DIR, file)
|
||||
|
||||
console.log(file)
|
||||
cb({
|
||||
data: fs.origin.createReadStream(file),
|
||||
mimeType: MIME_TYPES[ext] || MIME_TYPES.all,
|
||||
|
@ -81,13 +81,14 @@ app.once('ready', () => {
|
|||
|
||||
// 创建浏览器窗口
|
||||
app.__main__ = createMainWindow(path.resolve(ROOT, './images/app.png'))
|
||||
// app.__float__ = createFloatWindow()
|
||||
|
||||
createMenu(app.__main__)
|
||||
Socket(app, createViewWindow)
|
||||
Socket(app)
|
||||
|
||||
app.__main__.on('closed', () => {
|
||||
app.__main__ = null
|
||||
app.__view__ = null
|
||||
app.__float__ = null
|
||||
app.exit()
|
||||
})
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @date 2021/01/04 14:58:46
|
||||
*/
|
||||
|
||||
const { app, ipcMain } = require('electron')
|
||||
const { app, ipcMain, net } = require('electron')
|
||||
const fs = require('iofs')
|
||||
const path = require('path')
|
||||
const Epub = require('epub')
|
||||
|
@ -13,45 +13,36 @@ const HOME = path.resolve(app.getPath('userData'))
|
|||
const DB_FILE = path.join(HOME, 'app.cache')
|
||||
const CACHE_DIR = path.join(HOME, 'book_cache')
|
||||
|
||||
module.exports = function(app, createViewWindow) {
|
||||
function fetch(url) {
|
||||
return new Promise((y, n) => {
|
||||
var conn = net.request(url)
|
||||
var r = []
|
||||
|
||||
conn.on('response', res => {
|
||||
res.on('data', c => {
|
||||
r.push(c)
|
||||
})
|
||||
|
||||
res.on('end', _ => {
|
||||
y(Buffer.concat(r).toString())
|
||||
})
|
||||
})
|
||||
|
||||
conn.on('error', e => {
|
||||
n(e)
|
||||
})
|
||||
|
||||
conn.end()
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = function(app) {
|
||||
ipcMain.on('app', (ev, conn) => {
|
||||
switch (conn.type) {
|
||||
case 'get-books':
|
||||
ev.returnValue = JSON.parse(fs.cat(DB_FILE))
|
||||
break
|
||||
|
||||
case 'save-books':
|
||||
fs.echo(JSON.stringify(conn.data), DB_FILE)
|
||||
ev.returnValue = true
|
||||
break
|
||||
|
||||
case 'read':
|
||||
let params = JSON.parse(Buffer.from(conn.data, 'base64'))
|
||||
if (app.__view__) {
|
||||
// 打开同一个文档, 直接忽略
|
||||
if (app.__view__.__title__ === params.title) {
|
||||
app.__view__.focus()
|
||||
ev.returnValue = true
|
||||
return
|
||||
}
|
||||
app.__view__.destroy()
|
||||
}
|
||||
app.__view__ = createViewWindow(conn.data)
|
||||
app.__view__.__title__ = params.title
|
||||
ev.returnValue = true
|
||||
break
|
||||
|
||||
case 'delete-book':
|
||||
let dir = path.join(CACHE_DIR, conn.data)
|
||||
fs.rm(dir, true)
|
||||
ev.returnValue = true
|
||||
break
|
||||
|
||||
case 'save-cover':
|
||||
let file = path.join(CACHE_DIR, conn.data.name, 'cover.webp')
|
||||
let buf = Buffer.from(conn.data.base64, 'base64')
|
||||
fs.echo(buf, file)
|
||||
ev.returnValue = true
|
||||
case 'fetch':
|
||||
fetch(conn.data).then(r => {
|
||||
ev.returnValue = r
|
||||
})
|
||||
break
|
||||
|
||||
case 'parse-book':
|
||||
|
@ -60,11 +51,8 @@ module.exports = function(app, createViewWindow) {
|
|||
let cache = JSON.parse(fs.cat(DB_FILE))
|
||||
|
||||
eb.on('end', async _ => {
|
||||
let { title } = eb.metadata
|
||||
let cover = ''
|
||||
let { title, cover } = eb.metadata
|
||||
let dir = path.join(CACHE_DIR, title)
|
||||
let dict = {}
|
||||
let toc = []
|
||||
|
||||
function saveImage(id, name) {
|
||||
return new Promise(done => {
|
||||
|
@ -77,32 +65,12 @@ module.exports = function(app, createViewWindow) {
|
|||
|
||||
function saveHtml(id, name) {
|
||||
return new Promise(done => {
|
||||
eb.getChapterRaw(id, (err, txt) => {
|
||||
let m = (txt + '').match(/<body[^>]*?>([\w\W]+)<\/body>/)
|
||||
if (m) {
|
||||
let htm = m[1]
|
||||
.replace(
|
||||
/<(?!img|image)([\w\-]+)[^>]*?( id="[^\s]*?")?[^>]*?>/g,
|
||||
'<$1$2>'
|
||||
)
|
||||
.replace(/<pre><code>/g, '<wc-code>')
|
||||
.replace(/<\/code><\/pre>/g, '</wc-code>')
|
||||
|
||||
htm = htm
|
||||
.replace(/<pre>/g, '<wc-code>')
|
||||
.replace(/<\/pre>/g, '</wc-code>')
|
||||
|
||||
htm = htm
|
||||
.replace(/<wc-code>([\w\W]*?)<\/wc-code>/g, function(m, s) {
|
||||
s = s.replace(/<\/?\w+>/g, '')
|
||||
return `<wc-code>${s}</wc-code>`
|
||||
})
|
||||
.trim()
|
||||
|
||||
fs.echo(htm, path.join(dir, name.replace('.xhtml', '.html')))
|
||||
} else {
|
||||
console.log(id, name, txt)
|
||||
}
|
||||
eb.getChapter(id, (err, txt) => {
|
||||
// txt = (txt + '').replace(
|
||||
// /<(?!img|image)([\w\-]+)[^>]*>/g,
|
||||
// '<$1>'
|
||||
// )
|
||||
fs.echo(txt, path.join(dir, name.replace('.xhtml', '.html')))
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
@ -117,10 +85,7 @@ module.exports = function(app, createViewWindow) {
|
|||
break
|
||||
|
||||
case 'application/x-dtbncx+xml':
|
||||
eb.toc.forEach(_ => {
|
||||
dict[_.id] = _
|
||||
})
|
||||
|
||||
fs.echo(JSON.stringify(eb.toc), path.join(dir, 'toc.json'))
|
||||
break
|
||||
|
||||
case 'application/xhtml+xml':
|
||||
|
@ -130,7 +95,7 @@ module.exports = function(app, createViewWindow) {
|
|||
default:
|
||||
if (it['media-type'].startsWith('image')) {
|
||||
saveImage(it.id, it.href)
|
||||
if (it.href.includes('cover')) {
|
||||
if (it.href.includes(cover)) {
|
||||
cover = it.href
|
||||
}
|
||||
}
|
||||
|
@ -138,48 +103,7 @@ module.exports = function(app, createViewWindow) {
|
|||
}
|
||||
}
|
||||
|
||||
toc = eb.flow.map((it, i) => {
|
||||
let tmp = dict[it.id] || { level: i === 0 ? i : undefined }
|
||||
if (tmp.level === undefined) {
|
||||
tmp.level = 1
|
||||
}
|
||||
if (it.id === 'titlepage') {
|
||||
it.level = 0
|
||||
it.title = '封面'
|
||||
} else {
|
||||
it.level = tmp.level
|
||||
let cp
|
||||
|
||||
if (it.title) {
|
||||
cp = it.title
|
||||
} else {
|
||||
cp = fs
|
||||
.cat(path.join(dir, it.href.replace('.xhtml', '.html')))
|
||||
.toString()
|
||||
cp = cp.split(/[\r\n]/).shift()
|
||||
cp = cp.replace(/<\/?[\w\-]+[^>]*?>/g, '').trim()
|
||||
}
|
||||
|
||||
it.title = cp
|
||||
.slice(0, 20)
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
}
|
||||
return it
|
||||
})
|
||||
|
||||
fs.echo(JSON.stringify(toc), path.join(dir, 'toc.json'))
|
||||
|
||||
if (!cover) {
|
||||
cover = 'cover.webp'
|
||||
app.__main__.webContents.send('app', {
|
||||
type: 'draw-cover',
|
||||
data: title
|
||||
})
|
||||
}
|
||||
|
||||
let info = { title, cover }
|
||||
|
||||
if (cache[cate]) {
|
||||
if (!cache[cate].some(it => it.title === title)) {
|
||||
cache[cate].push(info)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @date 2020/12/10 14:57:49
|
||||
*/
|
||||
|
||||
const { app, BrowserWindow } = require('electron')
|
||||
const { BrowserWindow } = require('electron')
|
||||
|
||||
/**
|
||||
* 应用主窗口
|
||||
|
@ -29,28 +29,28 @@ exports.createMainWindow = function(icon) {
|
|||
|
||||
win.on('ready-to-show', _ => {
|
||||
win.show()
|
||||
// win.openDevTools()
|
||||
win.openDevTools()
|
||||
})
|
||||
|
||||
win.on('close', ev => {
|
||||
if (app.__view__) {
|
||||
ev.preventDefault()
|
||||
win.hide()
|
||||
}
|
||||
})
|
||||
|
||||
return win
|
||||
}
|
||||
|
||||
// 创建悬浮窗口
|
||||
exports.createViewWindow = function(params) {
|
||||
exports.createFloatWindow = function() {
|
||||
var win = new BrowserWindow({
|
||||
width: 1136,
|
||||
height: 768,
|
||||
minWidth: 1136,
|
||||
minHeight: 768,
|
||||
// show: false,
|
||||
title: 'E-pub Reader',
|
||||
width: 280,
|
||||
height: 360,
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
frame: false,
|
||||
show: false,
|
||||
vibrancy: 'hud',
|
||||
visualEffectState: 'active',
|
||||
webPreferences: {
|
||||
experimentalFeatures: true,
|
||||
nodeIntegration: true,
|
||||
|
@ -60,11 +60,11 @@ exports.createViewWindow = function(params) {
|
|||
|
||||
// win.openDevTools()
|
||||
|
||||
win.loadURL('app://local/view.html?' + params)
|
||||
|
||||
win.on('closed', ev => {
|
||||
app.__view__ = null
|
||||
win.on('blur', ev => {
|
||||
win.hide()
|
||||
})
|
||||
|
||||
win.loadURL('app://local/float.html')
|
||||
|
||||
return win
|
||||
}
|
||||
|
|
|
@ -6,28 +6,31 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
|
||||
<title></title>
|
||||
<link href="/lib/css/reset-basic.css" rel="stylesheet">
|
||||
<link href="/css/view.css" rel="stylesheet">
|
||||
<script src="/js/view.js" type="module"></script>
|
||||
<link href="/css/float.css" rel="stylesheet">
|
||||
<script src="/js/float.js" type="module"></script>
|
||||
</head>
|
||||
<body>
|
||||
<body class="noselect">
|
||||
|
||||
<div class="app" anot="app">
|
||||
<wc-scroll class="toc noselect" ref="toc">
|
||||
<item
|
||||
:for="it in toc"
|
||||
:class="{['lev-' + it.level]: 1, active: it.title === curr}"
|
||||
@click="viewChapter(it)"
|
||||
>
|
||||
<span class="text-ell" :attr-title="it.title" :text="it.title"></span>
|
||||
</item>
|
||||
</wc-scroll>
|
||||
|
||||
<wc-scroll class="chapter-box" ref="chapter">
|
||||
<div class="chapter">
|
||||
<article class="detail" :html="chapter"></article>
|
||||
<div class="app" anot="app">
|
||||
<wc-scroll class="list">
|
||||
<section class="item" :for="it in list">
|
||||
<div class="info">
|
||||
<h3 class="text-ell" :text="it.name"></h3>
|
||||
<cite :text="it.code"></cite>
|
||||
</div>
|
||||
|
||||
<div class="today">
|
||||
<span class="money" :text="'¥' + it.cm"></span>
|
||||
<span
|
||||
class="percent"
|
||||
:class="{red: it.cp > 0, green: it.cp < 0}"
|
||||
:text="it.cp + '%'">
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
<section :if="list.length === 0" class="item">啥基都没有...</section>
|
||||
</wc-scroll>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/Users/yutent/Library/Application Support/org.bytedo.epub/app.cache
|
Loading…
Reference in New Issue