完成阅读器1.0.0

master
宇天 2021-01-08 20:34:22 +08:00
parent 71aebe5cbd
commit 6c161866da
18 changed files with 1120 additions and 109 deletions

View File

@ -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;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}@-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{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:'🌘'}}

View File

@ -24,6 +24,7 @@ body {
.app {
position: relative;
display: flex;
width: 100%;
height: 100%;
.category {
@ -163,6 +164,31 @@ 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 {

View File

@ -1,6 +1,6 @@
@charset "UTF-8";
/**
*
*
* @authors yutent<yutent@doui.cc>
* @date 2018/12/16 17:15:07
*/

View File

@ -16,6 +16,8 @@
<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>
@ -28,7 +30,12 @@
<wc-scroll class="books-scroll">
<list class="books">
<book class="book" :for="it in books">
<book
class="book"
:for="it in books"
@dblclick="read(it)"
@contextmenu="pickCtx2(it, $event)"
>
<img :src="'book://cache/' + it.title + '/' + it.cover">
</book>
</list>
@ -38,13 +45,28 @@
<div class="drag-mask" ref="mask" :visible="isDragIn"></div>
<div class="book-loading" ref="books" :visible="loading">
<div class="book-loading" :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>

View File

@ -9,7 +9,9 @@
import '/lib/anot.js'
import '/lib/scroll/index.js'
import layer from '/lib/layer/index.js'
import '/lib/layer/index.js'
import Utils from '/lib/utils.js'
import { md5 } from '/lib/md5.js'
import app from '/lib/socket.js'
@ -25,7 +27,7 @@ Anot({
state: {
input: '',
curr: '默认分类',
cates: [{ name: '默认分类', num: 12 }],
cates: [],
books: [],
loading: false,
isDragIn: false,
@ -33,12 +35,21 @@ Anot({
num: 0,
curr: 0
},
$db: {}
$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.preventDefault()
@ -50,7 +61,7 @@ Anot({
this.isDragIn = false
})
$doc.bind('drop', ev => {
$doc.bind('drop', async ev => {
ev.preventDefault()
this.isDragIn = false
@ -72,17 +83,32 @@ Anot({
let book = files.pop()
let res = app.dispatch('parse-book', { book, cate: this.curr })
await sleep(500)
if (res) {
this.books.push(res)
}
}
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 })
// 默认选中第一个
@ -91,10 +117,161 @@ Anot({
books = db[k]
}
}
// books = books.concat(books, books, books, books, books, books)
this.$db = db
this.cates = cates
this.books = books
this.books = books || []
},
methods: {}
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))
},
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
// }
// }
}
})

View File

@ -8,7 +8,7 @@ import '/lib/anot.js'
import '/lib/scroll/index.js'
import '/lib/code/index.js'
import layer from '/lib/layer/index.js'
import { md5 } from '/lib/md5.js'
import fetch from '/lib/fetch/index.js'
import app from '/lib/socket.js'
@ -16,29 +16,52 @@ Anot({
$id: 'app',
state: {
toc: [],
title: 'HTML5 canvas开发详解(第2版) (无)',
curr: '',
file: '',
chapter: ''
book: '', // 当前阅读的书名
curr: '', // 当前选中的章节名
file: '', // 章节所属的文件名
chapter: '' // 章节渲染html文本
},
mounted() {
// app.on('float-visible', data => {})
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 || ''
document.title = this.title
this.getToc()
}
},
methods: {
getToc() {
fetch('book://cache/HTML5 canvas开发详解(第2版) (无)/toc.json')
fetch(`book://cache/${this.book}/toc.json`)
.then(r => r.json())
.then(list => {
for (let it of list) {
let chapter, idx
for (let i = -1, it; (it = list[++i]); ) {
delete it.id
delete it.order
}
this.toc = list
this.viewChapter(list[23])
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)
})
},
@ -49,6 +72,8 @@ Anot({
this.curr = item.title
Anot.ls(md5(this.book), item.title)
if (this.file === file) {
if (hash) {
location.hash = hash
@ -58,14 +83,14 @@ Anot({
}
} else {
this.file = file
fetch('book://cache/HTML5 canvas开发详解(第2版) (无)/' + file)
fetch(`book://cache/${this.book}/${file}`)
.then(r => r.text())
.then(txt => {
this.chapter = txt.replace(
/<img[^>]*?src="(.*?)"[^>]*?\/?>/g,
(m, s1) => {
s1 = s1.replace('../', '')
return `<img src="book://cache/${this.title}/${s1}">`
return `<img src="book://cache/${this.book}/${s1}">`
}
)

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
"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}};
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}}

View File

@ -1 +1 @@
"use strict";import Drag from"./core.js";Anot.directive("drag",{priority:1500,init:function(e){e.expr='"'+e.expr+'"',e.overflow=!0,e.axis="xy",e.element.dataset.axis&&(e.axis=e.element.dataset.axis,delete e.element.dataset.axis),e.limit=!1,e.element.dataset.limit&&(e.limit=e.element.dataset.limit,e.overflow=!1,delete e.element.dataset.limit)},update:function(e){var t=this.element;if(e)for(t=this.element.parentNode;t;){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})}});
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})}});

View File

@ -1,14 +1,12 @@
/**
*
* @authors yutent (yutent@doui.cc)
* @date 2020-07-07 16:27:17
* @version v2.0.1
* @authors yutent (yutent.io@gmail.com)
* @date 2020-12-23 15:31:02
* @version v1.0.0
*
*/
'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")}}};
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{--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;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:var(--color-red-1)}:host([color='blue']){color:var(--color-blue-1)}:host([color='green']){color:var(--color-green-1)}:host([color='teal']){color:var(--color-teal-1)}:host([color='orange']){color:var(--color-orange-1)}:host([color='dark']){color:var(--color-dark-1)}:host([color='purple']){color:var(--color-purple-1)}:host([color='grey']){color:var(--color-grey-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(o){o&&this.setAttribute("is",o)}drawPath(){var{is:o}=this.props,r=dict[o];this.__ICO__&&o&&r&&(this.__ICO__.innerHTML="loading"===o?r:`<path d="${r}" />`,this.__ICO__.classList.toggle("load","loading"===o))}attributeChangedCallback(o,r,e){if(null!==e&&r!==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 Normal file
View File

@ -0,0 +1,764 @@
/*
* 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

View File

@ -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}}(),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}}(),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)}};

View File

@ -50,9 +50,9 @@ protocol.registerSchemesAsPrivileged([
app.once('ready', () => {
// 注册协议
protocol.registerStreamProtocol('app', function(req, cb) {
var file = decodeURIComponent(
req.url.replace(/^app:\/\/local\//, '')
).replace(/\#.*$/, '')
var file = decodeURIComponent(req.url.replace(/^app:\/\/local\//, ''))
.replace(/\#.*$/, '')
.replace(/\?.*$/, '')
var ext = path.extname(file)
file = path.resolve(ROOT, file)
@ -71,6 +71,7 @@ app.once('ready', () => {
var ext = path.extname(file)
file = path.resolve(CACHE_DIR, file)
cb({
data: fs.origin.createReadStream(file),
mimeType: MIME_TYPES[ext] || MIME_TYPES.all,
@ -82,10 +83,9 @@ app.once('ready', () => {
// 创建浏览器窗口
app.__main__ = createMainWindow(path.resolve(ROOT, './images/app.png'))
app.__view__ = createViewWindow()
createMenu(app.__main__)
Socket(app)
Socket(app, createViewWindow)
app.__main__.on('closed', () => {
app.__main__ = null

View File

@ -4,7 +4,7 @@
* @date 2021/01/04 14:58:46
*/
const { app, ipcMain, net } = require('electron')
const { app, ipcMain } = require('electron')
const fs = require('iofs')
const path = require('path')
const Epub = require('epub')
@ -13,42 +13,39 @@ const HOME = path.resolve(app.getPath('userData'))
const DB_FILE = path.join(HOME, 'app.cache')
const CACHE_DIR = path.join(HOME, 'book_cache')
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) {
module.exports = function(app, createViewWindow) {
ipcMain.on('app', (ev, conn) => {
switch (conn.type) {
case 'fetch':
fetch(conn.data).then(r => {
ev.returnValue = r
})
break
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':
if (app.__view__) {
// 打开同一个文档, 直接忽略
if (app.__view__.__title__ === conn.data.title) {
app.__view__.focus()
ev.returnValue = true
return
}
app.__view__.destroy()
}
app.__view__ = createViewWindow(conn.data)
app.__view__.__title__ = conn.data.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 'parse-book':
let { book, cate } = conn.data
let eb = new Epub(book.path)

View File

@ -4,7 +4,7 @@
* @date 2020/12/10 14:57:49
*/
const { BrowserWindow } = require('electron')
const { app, BrowserWindow } = require('electron')
/**
* 应用主窗口
@ -27,21 +27,23 @@ exports.createMainWindow = function(icon) {
win.loadURL('app://local/index.html')
// win.on('ready-to-show', _ => {
// win.show()
win.on('ready-to-show', _ => {
win.show()
// win.openDevTools()
// })
})
win.on('close', ev => {
if (app.__view__) {
ev.preventDefault()
win.hide()
}
})
return win
}
// 创建悬浮窗口
exports.createViewWindow = function() {
exports.createViewWindow = function(params) {
var win = new BrowserWindow({
width: 1024,
height: 768,
@ -56,9 +58,13 @@ exports.createViewWindow = function() {
}
})
win.openDevTools()
// win.openDevTools()
win.loadURL('app://local/view.html')
win.loadURL('app://local/view.html?' + params)
win.on('closed', ev => {
app.__view__ = null
})
return win
}

View File

@ -12,7 +12,7 @@
<body>
<div class="app" anot="app">
<wc-scroll class="toc noselect">
<wc-scroll class="toc noselect" ref="toc">
<item
:for="it in toc"
:class="{['lev-' + it.level]: 1, active: it.title === curr}"