// ==UserScript== // @name sciDownload // @namespace http://tampermonkey.net/ // @version 0.7 // @description 涟漪效果 // @author Polygon // @icon data:image/png;base64,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 // @match *://*/* // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_download // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant unsafeWindow // @connect * // @run-at document-end // @downloadURL none // ==/UserScript== (function() { 'use strict' const utils = { api: 'https://service-8d4l1brd-1256272652.sh.apigw.tencentcs.com/sciDownload', doiRegex: new RegExp(/10\.\d{4,9}\/[-\._;\(\)\/:A-z0-9]+/), timeout: 25, height: 40, autoMax: {b: true, time: 1}, // 如果缩小状态下,sciState内容改变是否自动最大化以及弹出后自动收回的时间 // 这个b会自动记忆,如果最后一次运行状态是min,下次自动min get switchState() { return GM_getValue('sciDownload-state', 'max') }, set switchState(value) { GM_setValue('sciDownload-state', value) }, color: { success: '#e74c3c', flash: '#00b894', fail: '#2c3e50' }, svg: { doi: ` `, url: ` `, pdf: ``, switch: ` ` }, style() { let div = document.createElement('div') div.innerHTML = this.svg.doi div.style.opacity = '0' document.body.appendChild(div) const total = div.querySelector('.progress').getTotalLength() document.body.removeChild(div) return ` .sciTool { display: flex; position: fixed; height: ${this.height}px; bottom: 75px; font-family: NexusSans,Arial,Helvetica,Lucida Sans Unicode,Microsoft Sans Serif,Segoe UI Symbol,STIXGeneral,Cambria Math,Arial Unicode MS,sans-serif; font-size: 18px; cursor: pointer; box-shadow: 0px 0px 20px rgba(0, 0, 0, .1); transition: left .23s ease-out, opacity .23s, right .23s ease-out; z-index: 9999999999; } .sciTool * { box-sizing: border-box; } #sciContent { box-sizing: border-box; display: flex; align-items: center; justify-content: space-around; vertical-align: middle; white-space: nowrap; color: white; background-color: ${this.color.fail}; opacity: 0.72; transition: width .23s ease-out, opacity .23s; } #sciSwitch { width: ${this.height}px; height: ${this.height}px; color: white; background-color: #00b894; opacity: 0.72; transition: width .23s ease-out, opacity .23s; z-index: 1; } #sciContent #sciState { position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center; width: ${this.height}px; height: ${this.height}px; opacity: 1; } #sciContent #sciText { position: relative; overflow: hidden; height: 100%; display: flex; align-items: center; justify-content: center; color: white; padding-left: 5px; padding-right: 10px; opacity: 1; text-decoration: none; transition: width .23s ease-out; } #sciContent:hover { opacity: 1 !important; } #sciSwitch:hover { opacity: 1 !important; } /* left svg progress */ #sciContent #sciState .progressBox { transform: rotate(-90deg); } #sciContent #sciState .progress { stroke-dasharray: ${total}; animation: progressOffset ${this.timeout}s linear; } @keyframes progressOffset { from { stroke-dashoffset: ${total}; } to { stroke-dashoffset: 0; } } /* right div progress */ #sciProgressBox { right: 0px; } #sciProgress { position: relative; display: flex; justify-content: center; align-items: center; width: 0px; background-color: ${this.color.flash}; height: 40px; overflow: hidden; transition: width ${this.timeout}s linear; } #sciProgressText { position: absolute; color: white; right: 0px; padding-left: 5px; padding-right: 10px; } /* flash */ @keyframes sciFlash { from { opacity: 1; background-color: ${this.color.success}; } 50% { opacity: 0.72; background-color: ${this.color.flash}; } to { opacity: 1; background-color: ${this.color.success}; } } #sciDownloadBox .loading { animation: sciFlash 1.2s infinite !important; } /* switch button animation */ #sciSwitch svg .switch { transform: rotate(0deg); transform-origin: center center; transition: transform .23s ease-out .15s; } /* ripple effect */ .sciTool .ripple { position: absolute; background: #fff; transform: translate(-50%, -50%); pointer-events: none; border-radius: 50%; animation: ripple 1s linear infinite; } @keyframes ripple{ 0% { width: 0px; height: 0px; opacity: 0.5; } 100% { width: 500px; height: 500px; opacity: 0; } } ` }, initBox(doi) { if (this.sciContent) { if (this.sciContent.classList.contains('loading')) {this.sciContent.classList.remove('loading')} let sciProgressBox = document.querySelector('#sciProgressBox') if (sciProgressBox) {sciProgressBox.parentNode.removeChild(sciProgressBox)} this.sciContent.style['background-color'] = this.color.fail this.sciText.removeAttribute('href') this.changeContent(this.svg.doi, doi, () => { this.startProgress() }) } else { this.sciDownloadBox = document.createElement('div') this.sciDownloadBox.setAttribute('id', 'sciDownloadBox') this.sciDownloadBox.setAttribute('class', 'sciTool') this.sciDownloadBox.innerHTML = `
${this.svg.switch}
${this.svg.doi}
${doi}
` document.body.appendChild(this.sciDownloadBox) this.sciContent = this.sciDownloadBox.querySelector('#sciContent') this.sciState = this.sciDownloadBox.querySelector('#sciState') this.sciText = this.sciDownloadBox.querySelector('#sciText') this.sciDownloadBox.style.right = -this.getElementWidth(this.sciDownloadBox) + 'px' setTimeout(() => { this.sciDownloadBox.style.right = '0px' setTimeout(() => { this.startProgress() }, 230*2) }, 230) this.sciSwitch = this.sciDownloadBox.querySelector('#sciSwitch') this.sciSwitch.onclick = this.switchEvent // 涟漪效果点击事件 this.sciState.addEventListener('click', this.rippleClickEvent) this.sciText.addEventListener('click', this.rippleClickEvent) // 调整窗口重适应 window.onresize = () => { setTimeout(() => { this.sciSwitch.click() this.sciSwitch.click() }) } } }, rippleClickEvent(event) { let parent // 过滤内部元素 for (let i=0;i { ripple.remove() }, 1000) }, switchEvent(event) { if (utils.switchState == 'max') { utils.sciDownloadBox.style.left = getComputedStyle(utils.sciDownloadBox).left utils.sciDownloadBox.style.left = document.body.clientWidth - utils.height * 2 + 'px' utils.sciDownloadBox.style.right = -utils.getElementWidth(utils.sciDownloadBox) + 'px' let sciProgressBox = document.querySelector('#sciProgressBox') if (sciProgressBox) { sciProgressBox.style.right = -utils.getElementWidth(utils.sciState) + 'px' sciProgressBox.style.left = document.body.clientWidth + 'px' } utils.sciSwitch.querySelector('svg .switch').style.transform = 'rotate(90deg)' utils.switchState = 'min' } else if (utils.switchState == 'min') { utils.sciDownloadBox.style.left = '' utils.sciDownloadBox.style.right = '0px' let sciProgressBox = document.querySelector('#sciProgressBox') if (sciProgressBox) { sciProgressBox.style.left = '' sciProgressBox.style.right = '0px' } utils.sciSwitch.querySelector('svg .switch').style.transform = 'rotate(0deg)' utils.switchState = 'max' } }, startProgress() { let ele = this.sciText let sciProgressBox = document.createElement('div') sciProgressBox.setAttribute('id', 'sciProgressBox') sciProgressBox.setAttribute('class', 'sciTool') let totalWidth = this.getElementWidth(ele) sciProgressBox.innerHTML = `
${ele.innerHTML}
` document.body.appendChild(sciProgressBox) let sciProgress = sciProgressBox.querySelector('#sciProgress') sciProgressBox.querySelector('#sciProgressText').style.width = `${totalWidth}px` setTimeout(() => { sciProgress.style.width = `${totalWidth}px` if (this.switchState == 'min') {this.switchState = 'max'; this.sciSwitch.click()} }, 100) sciProgress.addEventListener('click', this.rippleClickEvent) }, getContentWidth(ele, content) { let oldContent = ele.innerHTML ele.innerHTML = content let width = this.getElementWidth(ele) ele.innerHTML = oldContent return width }, getElementWidth(ele) { return parseFloat(window.getComputedStyle(ele).width.replace('px', '')) }, changeContent(state, text, callback=null) { this.sciState.innerHTML = state let ele = this.sciText let sciProgressBox = document.querySelector('#sciProgressBox') if (sciProgressBox) {sciProgressBox.parentNode.removeChild(sciProgressBox)} let oldWidth = this.getElementWidth(ele) let newWidth = this.getContentWidth(ele, text) utils.log(`newWidth=${newWidth}, oldWidth=${oldWidth}`) ele.style.width = oldWidth + 'px' setTimeout(() => { ele.style.width = newWidth + 'px' ele.innerHTML = text setTimeout(() => { ele.style.width = 'fit-content' if (callback) {callback()} }, 230) if (this.switchState == 'min' & this.autoMax.b){ this.sciSwitch.click() setTimeout(() => { this.sciSwitch.click() }, this.autoMax.time * 1000) } }, 230) }, getDoi() { let selection = window.getSelection().toString() let sourceText = document.body.innerHTML let matches = selection.match(this.doiRegex) || sourceText.match(this.doiRegex) let doi = null if (matches) { doi = matches[0].replace('.pdf', '') } return doi }, getApi(doi) { this.log('初始化sciDownloadBox') this.initBox(doi) this.log('初始化sciDownloadBox完成') GM_xmlhttpRequest({ method: 'POST', url: this.api, responseType: 'json', headers: {"Content-Type": "application/x-www-form-urlencoded"}, data: `doi=${doi}&timeout=${this.timeout}`, onload: (res) => { console.log(res.response) utils.getPdf(res.response, doi) } }) }, getPdf(data, doi) { this.changeContent(this.svg.url, data.message) this.sciState.setAttribute('href', data.url) let exit = true switch (data.message) { case 'NotSupport': this.log('不支持该文章,退出...') break case 'Timeout': this.log('请求超时,退出...') break case 'DoiError': this.log('doi错误,退出...') break default: this.log('请求pdf中...') exit = false } if (exit) { return } let pdfURL = location.protocol + '//' + data.url.split('://')[1] utils.sciText.onclick = () => { setTimeout(() => { window.open(pdfURL) }, 1000) } this.sciContent.classList.add('loading') // 开始缓存同时尝试打开链接,可将下行反注释即可 // window.open(pdfURL) GM_xmlhttpRequest({ method: 'GET', url: pdfURL, responseType: 'blob', onload: function(res) { console.log(res.response) let fileURL = URL.createObjectURL(new Blob([res.response], {type: 'application/pdf'})) let title = doi.split('/').slice(1).join('/') utils.log('res.responseHeaders') console.log(res.responseHeaders) if (res.responseHeaders.search('application') !== -1) { let titleRes = res.responseHeaders.match(/filename=(.+)/) if (titleRes) { title = titleRes[1].replace(';', '').replace('.pdf', '').replace('"', '').replace('"', '') } } else { utils.sciContent.classList.remove('loading') return } utils.sciText.removeAttribute('href') utils.sciText.onclick = () => { setTimeout(() => { let win = window.open() win.document.write(``) win.document.title = title }, 1000) } utils.log('缓存pdf成功') utils.sciContent.classList.remove('loading') utils.sciContent.style['background'] = utils.color.success utils.changeContent(utils.svg.pdf, title) utils.sciState.onclick = (event) => { let aTag = document.createElement('a') aTag.setAttribute('href', fileURL) aTag.setAttribute('download', `${title}.pdf`) aTag.click() } } }) }, log(text) { console.log(`[sciDownload] ${text}`) } } try{ GM_addStyle(utils.style()) } catch { utils.log('添加style失败,退出...') return } let lastDoi = '' setInterval(function () { let doi = utils.getDoi() if (doi == lastDoi | doi == null) { return } lastDoi = doi utils.log('发现doi = ' + doi) utils.getApi(doi) }, 500) })();