// ==UserScript==
// @name 文库下载器/支持度娘、道客、豆丁、智库、360、原创力文库
// @namespace wenku
// @version 2.2
// @description 文库下载器/支持度娘、道客、豆丁、智库、360、原创力文库的文档下载
// @author zhihu
// @license End-User License Agreement
// @match https://*/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @require https://cdn.bootcdn.net/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js
// @require https://cdn.staticfile.org/html2canvas/1.4.1/html2canvas.min.js
// @grant GM_xmlhttpRequest
// @grant GM.xmlHttpRequest
// @connect docimg1.docin.com
// @connect view-cache.book118.com
// @connect docreado.mbalib.com
// @connect so3.360tres.com
// @antifeature membership 为防止接口被盗!该脚本需要输入验证码之后才能使用完整功能,感谢理解
// @grant unsafeWindow
// ==/UserScript==
(function() {
'use strict';
//全局对象
const window = unsafeWindow||window
//---------------------------公共方法开始---------------------------
String.prototype.startWith=function(str){
if(typeof str !== 'string') str = str.toString()
if(this==null||this==''||this.length==0||str.length==0||str.length>this.length) return false
let len = str.length
return this.slice(0,len) === str
}
String.prototype.endWith=function(str){
if(typeof str !== 'string') str = str.toString()
if(this==null||this==''||this.length==0||str.length==0||str.length>this.length) return false
let len = str.length
return this.slice(-len) === str
}
/**
* 公共样式
*/
const COMMON_STYLE = `
.zh-container *{
padding:0;
margin:0
}
.zh-input{
outline-style: none;
border-radius: 5px;
border: 1px solid #e7e9eb;
color: var(--999, #999);
width: 100%;
flex: 1 1 0%;
font-size: 12px;
line-height: 16px;
padding:5px;
}
.zh-button{
text-align: center;
font-size: 14px;
padding: 7px 15px;
background: #54be99;
border: 1px solid #54bc99;
color: #fff;
border-radius: 3px;
user-select:none;
cursor:pointer;
}
.zh-button.zh-default{
background: #fff;
color: #54bc99;
margin-bottom: 10px;
}
.user-select{
user-select: none;
}
`;
const HREF = window.location.href;
const Utils = {
/**
* 添加css
* @params {String} css - css样式
*/
appendStyle(css){
let style = document.createElement('style');
style.textContent = css;
style.type = 'text/css';
let doc = document.head || document.documentElement;
doc.appendChild(style);
},
/**
* 添加js文件
* @params {String} url - js文件地址
*/
appendScript:function(url) {
let script = document.createElement('script');
script.src = url;
var docu = document.head || document.documentElement;
docu.appendChild(script);
},
/**
* 自动滚动页面
* @params {Number} distance - 每次滚动的距离
* @params {Number} originalLocation - 滚动条初始位置
* @params {Number} targetLocation - 滚动条目标位置
* @params {Number} delay - 每次滚动的时间差
*/
scrollPage(distance,originalLocation,targetLocation,delay = 1000){
const scrollTo = ()=>{
window.scrollTo({
top: originalLocation,
behavior: "smooth"
});
}
let time = Math.ceil(Math.abs(targetLocation - originalLocation)/distance)*delay + delay
Utils.toast('正在自动预览页面,请勿操作','warning',time)
//先滚动到起始位置
scrollTo()
let timer = null;
return new Promise((resolve, reject) => {
if(originalLocation<targetLocation){
timer = setInterval(()=>{
if(originalLocation<targetLocation){
originalLocation += distance
scrollTo()
// 相比上次位置减10,根据自己需要的速度修改
}else{
clearInterval(timer)
resolve(true)
}
},delay)
}else{
timer = setInterval(()=>{
if(originalLocation>targetLocation){
originalLocation -=distance
scrollTo()
// 相比上次位置减10,根据自己需要的速度修改
}else{
clearInterval(timer)
resolve(true)
}
},delay)
}
})
},
/**
* 延时
* @params {Number} time - 需要延迟的时间
*/
sleep(time){
return new Promise(resolve => setTimeout(resolve, time));
},
/**
* 网络请求
* @params {String} method - 请求类型(GET,POST...)
* @params {String} url - 请求地址
* @params {Object} data - 请求body
* @params {String} responseType - 返回的数据类型
*/
request(method, url, data, headers = {} , responseType = 'text') {
return new Promise((resolve, reject) => {
let xmlHttpRequest = GM_xmlhttpRequest||GM.xmlHttpRequest
xmlHttpRequest({
method,
url,
data,
headers,
responseType,
onerror: reject,
ontimeout: reject,
onload: (response) => {
if (response.status >= 200 && response.status < 300) {
resolve(responseType === 'text' ? response.responseText : response.response);
} else {
reject(new Error(response.statusText));
}
}
});
});
},
/**
* 下载图片
* @params {String} url - 图片远程地址
*/
loadImage (url) {
return new Promise(async (resolve, reject) => {
url.startsWith("//")&&(url='http:'+url);
if (!url) {
reject('loadImage:请传入图片地址');
}
let img = await Utils.request('GET', url, null,{}, 'blob');
console.log(img)
let imgEl = document.createElement('img');
imgEl.onload = () => {
resolve(imgEl);
}
imgEl.onabort = imgEl.onerror = reject;
imgEl.src = URL.createObjectURL(img);
})
},
/**
* 信息提示
* @params {String} msg - 信息内容
* @params {String} type - 信息类型
* @params {Number} delay - 自动移除消息的时间
*/
msgBox:null,
toast (msg,type = 'success',delay = 3000){
let typeMap = {
success:{
bg:'#f0f9eb',
text:'#67c23a',
border:'#e1f3d8'
},
error:{
bg:'#fef0f0',
text:'#f56c6c',
border:'#fde2e2'
},
warning:{
bg:'#fdf6ec',
text:'#e6a23c',
border:'#faecd8'
}
}
if(!this.msgBox){
this.msgBox = document.createElement('div')
this.msgBox.style = `position: fixed;
top: 100px;
left: 0;
right: 0;
margin: 0 auto;
width: 300px;
padding: 20px;
z-index:9999999999;
`
this.msgBox.classList.add('zh-container')
document.body.appendChild(this.msgBox)
}
let msgItem = document.createElement('div')
let id = 'msg' + new Date().getTime()
msgItem.setAttribute('id',id)
msgItem.innerHTML = `<p>${msg}</p>`
msgItem.style = `
text-align: center;
width: fit-content;
margin: 0 auto;
padding: 10px 20px;
font-size: 14px;
line-height: 20px;
border: 1px solid;
border-radius: 5px;
margin-bottom:10px;
`
msgItem.style.background = typeMap[type].bg
msgItem.style.color = typeMap[type].text
msgItem.style.borderColor = typeMap[type].border
this.msgBox.appendChild(msgItem)
setTimeout(()=>{
document.querySelector('#'+id).remove()
},delay)
},
//进度条
progressBox:null,
progress:{
width:500,
height:90,
padding:20,
createDialogElement(){
if(!Utils.progressBox){
let css = `
.zh-shadow{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999999998;
background-color: rgb(97 97 97 / 20%);
}
.zh-panel{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999999998;
background-color: #fff;
width: ${this.width}px;
height: ${this.height}px;
margin: auto;
border-radius: 10px;
box-shadow: 0 0 6px 3px #00000026;
padding:${this.padding}px;
box-sizing:border-box;
}
.zh-panel .zh-progress-wrapper{
width: 100%;
background: #f1f1f1;
height: 20px;
position: relative;
border-radius: 3px;
margin-bottom: 10px;
}
.zh-panel .zh-progress-wrapper #zh-progress{
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 0px;
background: #56ab8d;
border-radius: 3px;
}
.zh-panel .zh-progress-tips{
display:flex;
justify-content: space-between;
font-size: 12px;
line-height:20px;
color: #000;
}
.zh-panel .zh-progress-tips #zh-text{
flex: 1;
}
.zh-panel .zh-progress-tips #zh-progress-text{
width: 50px;
text-align: right;
color: #56ab8d;
}
`
Utils.appendStyle(css)
Utils.progressBox = document.createElement('div')
Utils.progressBox.innerHTML = `
<div class="zh-shadow"></div>
<div class="zh-panel">
<div class="zh-progress-wrapper">
<div id="zh-progress"></div>
</div>
<div class="zh-progress-tips">
<span id="zh-text">正在下载</span>
<span id="zh-progress-text">0%</span>
</div>
</div>
`
document.body.appendChild(Utils.progressBox)
}
},
showStatus(text = '',progress = -1){
if(!Utils.progressBox){
this.createDialogElement()
}
text&&(document.querySelector('.zh-panel #zh-text').innerHTML = text)
if (progress >= 0) {
progress = Math.min(progress, 100);
document.querySelector('.zh-panel #zh-progress').style.width = `${Math.floor(progress)}%`;
document.querySelector('.zh-panel #zh-progress-text').innerHTML = `${Math.floor(progress)}%`;
}
},
hideStatus(){
Utils.progressBox.remove()
Utils.progressBox = null
}
},
//拼接Get请求链接
getAjaxUrl(url,params){
if(!url.endWith('?')) url+='?'
let query = ''
for( var i in params ){
query += '&' + i + '=' + params[i];
}
query = query.slice(1)
return url+query;
},
/**
* /html转canvas
* @params {Object} el - 需要转换成canvas的元素
*/
htmlToCanvas(el){
return new Promise((resolve, reject) => {
html2canvas(el,{
useCORS: true, // 【重要】开启跨域配置
scale: window.devicePixelRatio < 3 ? window.devicePixelRatio : 2,
allowTaint: true, // 允许跨域图片
})
.then(canvas => {
resolve(canvas)
})
.catch(err=>reject(err));
})
},
/**
* 弹窗拖拽功能
* @params {Object} el - 元素节点
* @params {String} strongName - localStrong存储名
*/
drag(el,strongName = ''){
if(!el||!strongName){
console.log(el)
return null
}
//获取存储的定位信息
const item = window.localStorage.getItem(strongName)
console.log(JSON.parse(item))
//设置节点定位
if(item){
const {top,left} = JSON.parse(item)
el.style.top = top + 'px';
el.style.left = left + 'px';
}
let disX,disY,startTime,lastTime,startLeft,lastLeft,startTop,lastTop;
el.onmousedown = function(event){
//鼠标距节点左边缘的距离
disX = event.pageX - el.offsetLeft;
//鼠标距节点顶部的距离
disY = event.pageY -el.offsetTop;
//按下的时间
startTime = (new Date).getTime()
startTop = event.pageY;
startLeft = event.pageX;
document.onmousemove = function(event){
let left = event.pageX - disX ;
let top = event.pageY - disY;
if(left < 0){
left = 0
}else{
left = Math.min(left,document.documentElement.clientWidth - el.offsetWidth)
}
if(top < 0){
top = 0
}else{
top = Math.min(top,document.documentElement.clientHeight - el.offsetHeight)
}
el.style.left = left + 'px';
el.style.top = top + 'px';
//存储位置信息
window.localStorage.setItem(strongName,JSON.stringify({left,top}))
}
document.onmouseup = function(event){
lastTime = (new Date).getTime()
console.log(event)
lastTop = event.pageY;
lastLeft = event.pageX;
document.onmousemove = null
}
//阻止点击捕获事件
document.addEventListener('click',(event)=>{
if((Math.abs(lastTop - startTop) > 5)||(Math.abs(lastLeft - startLeft) > 5)||(lastTime - startTime > 500)) event.stopPropagation()
},true)
}
},
/**
* 保存blob数据至本地的方法
* @params {Blob} content - 需要保存的blob数据
* @params {String} file_name - 保存文件的命名
* @params {String} type - 保存文件的格式
*/
save(content,file_name, type="") {
if (!type && content instanceof Blob) {
type = content.type;
}
let blob = null;
if (content instanceof Array) {
blob = new Blob(content, { type });
} else {
blob = new Blob([content], { type });
}
const url = URL.createObjectURL(blob);
const el = document.createElement("a");
el.download = file_name || "未命名文件";
el.href = url;
el.click();
URL.revokeObjectURL(url);
},
}
//---------------------------公共方法结束---------------------------
//---------------------------文档下载类开始-------------------------
class DocDownload{
// 下载弹窗id
elementId = 'zhihuDocDownload';
//是否已经创建下载弹窗
isMount = false;
//开始页码
pageStart = {
value:'',
initVlaue:''
};
//结束页码
pageEnd = {
value:'',
initVlaue:''
};
//预览速度
preSpeed = {
value:300,
initVlaue:300
};
//是否有预览失败的
hasPreviewFail = false;
//是否正在预览
isPreviewing = false;
//是否开启自动预览
autoPreview = true;
//是否开启分批下载
splitDownload = true;
//当前平台 道客:daoke 豆丁:docin
platform = '';
//css样式
style = `
.zh-dialog{
box-shadow: 0 0 6px 3px #00000038;
z-index: 99999997;
top: 100px;
position: fixed;
right: 50px;
background: #fff;
padding:20px;
border-radius: 8px;
width:120px;
box-sizing: content-box;
}
.zh-dialog-item{
display:flex;
flex-direction:column
}
.zh-dialog-item .title{
font-size:14px;
font-weight:500;
color:#333;
margin-bottom:5px
}
.zh-dialog-item .content{
display:flex;
align-items:center;
margin-bottom: 10px;
}
.zh-dialog-item .content .cut{
margin: 0 5px
}
.zh-dialog-item .content .text{
font-size:12px;
color:#666;
margin-left:5px
}
.zh-default{
margin-bottom:10px;
}
`;
constructor(options){
if(options.preSpeed){
this.preSpeed.value = options.preSpeed
this.preSpeed.initVlaue = options.preSpeed
}
if(!options.platform) throw new TypeError('请传入platform')
this.platform = options.platform
if(options.autoPreview !== undefined){
this.autoPreview = options.autoPreview;
}
if(options.splitDownload !== undefined){
this.splitDownload = options.splitDownload;
}
this.createDialogElement()
}
//创建下载弹窗元素
createDialogElement(){
if(this.isMount) return;
//插入公共CSS
Utils.appendStyle(COMMON_STYLE)
//插入CSS
Utils.appendStyle(this.style)
//创建div元素
let autoPreviewHtml = this.autoPreview ?`
<div class="zh-dialog-item">
<label class="title user-select">预览速度</label>
<div class="content">
<input class="zh-input" id="preSpeed" value="${this.preSpeed.value}"></input>
<span class="text user-select">像素</span>
</div>
</div>
<div class="zh-button zh-default user-select" id="zh-preview">自动预览</div>
`:''
let splitDownloadHtml = this.splitDownload?`
<div class="zh-dialog-item">
<label class="title user-select">分批下载</label>
<div class="content">
<input class="zh-input" placeholder="页码" type="number" id="pageStart"></input>
<span class="cut">-</span>
<input class="zh-input" placeholder="页码" type="number" id="pageEnd"></input>
</div>
</div>
`:''
let div = document.createElement('div')
let html = `
<div id="zh-wk" class="zh-dialog zh-container">
${splitDownloadHtml}
${autoPreviewHtml}
<div class="zh-button user-select" id="zh-download">下载文档</div>
</div>
`
div.innerHTML = html
div.setAttribute('id',this.elementId)
// 挂载到body
document.body.appendChild(div)
if(this.autoPreview){
document.querySelector('#zh-preview').addEventListener('click',()=>{
if(!this.isPreviewing){
this.isPreviewing = true
this.preview().finally(()=>{
this.isPreviewing = false
})
}
})
this.observerInputChange('preSpeed');
}
if(this.splitDownload){
this.observerInputChange('pageStart');
this.observerInputChange('pageEnd');
}
//拖拽移动
let el = document.querySelector('#zh-wk')
Utils.drag(el,'zh-wk')
}
// 监听点击下载
start(callback){
let isClick = false
document.querySelector('#zh-download').addEventListener('click',(e)=>{
//如果未点击或预览失败可以点击
if(!isClick&&!this.isPreviewing){
//点击之后锁死,不让再次点击
isClick = true
callback(()=>{
//重置开关状态
isClick = false;
this.hasPreviewFail = false;
})
}
})
}
//监听输入框变化,变化后给变量赋值
observerInputChange(id) {
document.querySelector('#'+id).addEventListener('change',(e)=>{
let val = Math.abs(parseInt(e.target.value))
e.target.value = val||this[id].initVlaue
this[id].value = val||this[id].initVlaue
})
}
//检测页码是否输入有误
checkPage(len){
if(!this.pageStart.value||!this.pageEnd.value) {
return true
}
if(this.pageStart.value>this.pageEnd.value) {
throw new TypeError('输入错误,起始页码大于结束页码')
}
if(this.pageStart.value > len){
throw new TypeError('输入错误,起始页码大于页码数')
}
if(this.pageEnd.value > len){
throw new TypeError('输入错误,结束页码大于页码数')
}
return true
}
//检测页面是否预览完成
checkPageHasNoPreview(){
var map ={
daoke:{
el:'.page_pb',
verifyFn:(i)=>elements[i - 1].childNodes.length !== 0
},
docin:{
el:'.model',
verifyFn:(i)=>document.querySelector('#img_'+i)?.childNodes.length === 0
},
max_book:{
el:'.webpreview-item',
verifyFn:(i)=>elements[i - 1].querySelector('img').getAttribute('src') === null
},
sodoc:{
el:'.wenku-detail__showdoc__imgContainer',
verifyFn:(i)=>elements[i - 1].childNodes.length === 0
}
}
var elements = document.querySelectorAll(map[this.platform].el);
let noPreview = [];
// 下载页码
let pageStart = (this.pageStart.value&&this.pageEnd.value)?this.pageStart.value:1
let pageEnd = (this.pageStart.value&&this.pageEnd.value)?this.pageEnd.value:elements.length
for ( let i=pageStart; i <= pageEnd;i++){
let isEmpty = map[this.platform].verifyFn(i)
console.log(isEmpty)
isEmpty&&noPreview.push(i)
}
if(noPreview.length > 0){
let errorMsg = noPreview.map(item=>`第${item}页`).join(',')
Utils.toast(`${errorMsg} 预览失败,请手动预览上述页码`,'error',5000);
return true
}
return false
}
//滚动页面预览
async preview(targetLocation){
switch (this.platform){
case 'daoke':
//展开全文
let continueButton = document.querySelector("#continueButton")
continueButton&&window.buyContinueRead();
break;
case 'max_book':
let WebPreview = window?.WebPreview||''
if(!WebPreview) return Utils.toast('该页面不支持自动预览','error')
let preview_page = WebPreview?.Data?.preview_page
WebPreview.Preview.jump(preview_page)
break;
}
// //展开全文docin
// let continueButton = document.querySelector(".model-fold-show")
// continueButton&&window.docinReader.halfPageHanlde&&window.docinReader.halfPageHanlde();
let target = targetLocation||document.body.scrollHeight;
await Utils.scrollPage(this.preSpeed.value,0,target,600)
return Promise.resolve(true)
}
// 导出PDF
async exportPdf(pageCanvas,title){
async function max_book_ppt(i){
//跳转至该页面
window.gosld(i)
//清除父容器缩放
document.querySelector('#view')?.setAttribute("style", "")
Utils.progress.showStatus(`正在获取第${i + 1}页网页数据`);
await Utils.sleep(100);
let node = document.querySelector('#view'+i)
return Utils.htmlToCanvas(node)
}
try {
// 下载页码
let pageStart = (this.pageStart.value&&this.pageEnd.value)?this.pageStart.value - 1:0
let pageEnd = (this.pageStart.value&&this.pageEnd.value)?this.pageEnd.value:pageCanvas.length
//创建PDF
let doc = null
for(let i = pageStart;i < pageEnd; i++){
let page = i + 1;
let el = pageCanvas[i]
Utils.progress.showStatus(`正在创建第${page}页`,(page/pageCanvas.length) * 100);
if(this.platform === 'max_book_ppt') el = await max_book_ppt(i)
//获取页面尺寸
let pageSize = [parseInt(pageCanvas[i].clientWidth),parseInt(pageCanvas[i].clientHeight)];
//如果没有创建PDF,先创建,已创建直接增加页面
if (!doc) {
doc = new Pdf(pageSize);
} else {
doc.addPage(pageSize);
}
Utils.progress.showStatus(`正在合成第${page}页`);
let imageData
//图片节点先加载图片至本地
console.log(el,el.tagName)
if(el.tagName === 'IMG'){
imageData = await Utils.loadImage(el.getAttribute("src"))
console.log(imageData.offsetWidth)
}else if(el.tagName === 'CANVAS'){
imageData =el.toDataURL('image/jpeg', 1.0);
}else{
throw new TypeError('imageData:此节点数据不能转换成图片')
}
//将图片数据写入PDF
doc.addImage({
imageData,
width:pageSize[0],
height:pageSize[1]
});
Utils.progress.showStatus(`第${page}页创建成功`);
await Utils.sleep(100)
}
doc.save(title);
} catch (error) {
return Promise.reject(error)
}finally{
Utils.progress.hideStatus()
}
}
}
//---------------------------文档下载类结束-------------------------
//---------------------------jsPdf类开始---------------------------
class Pdf{
doc = null;
constructor(pageSize){
this.doc = new jspdf.jsPDF({
orientation: pageSize[0] < pageSize[1] ? 'p' : 'l',
unit: 'pt',
format: pageSize,
compress: true
});
}
// 增加页面
addPage(pageSize){
this.doc.addPage({
orientation: pageSize[0] < pageSize[1] ? 'p' : 'l',
format: pageSize,
})
}
//添加图片到页面
addImage({imageData,width,height,x = 0,y = 0,type="JPEG"}){
this.doc.addImage(imageData, type, x, y, width, height);
}
//保存pdf
save(title){
this.doc.save(`${title}.pdf`);
}
}
//---------------------------jsPdf类结束---------------------------
//---------------------------文库初始化开始-------------------------
const wenkuInit = {
//道客巴巴初始化
daoke(){
//创建节点
const docDown = new DocDownload({
preSpeed:400,
platform:'daoke'
})
docDown.start(async (reClick)=>{
try {
//输入了页码才检测页码是否正常
let len = document.querySelectorAll('.outer_page').length||0
docDown.checkPage(len)
//检测是否有页面未预览成功
docDown.hasPreviewFail = docDown.checkPageHasNoPreview()
if(!docDown.hasPreviewFail){
//标题
let title = window?.words||"道客巴巴文档";
//页面的canvas
let pageCanvas = document.getElementsByClassName("inner_page");
//下载文档
await docDown.exportPdf(pageCanvas,title)
}
} catch (error) {
Utils.toast(error.message,'error')
} finally{
reClick()
}
})
},
//豆丁初始化
docin(){
//创建节点
const docDown = new DocDownload({
preSpeed:400,
platform:'docin'
})
docDown.start(async (reClick)=>{
try {
//输入了页码才检测页码是否正常
let len = document.querySelectorAll('.model').length||0
docDown.checkPage(len)
//检测是否有页面未预览成功
docDown.hasPreviewFail = docDown.checkPageHasNoPreview()
if(!docDown.hasPreviewFail){
//标题
let title = window?.docinShareConfig?.title||"豆丁文档";
//页面的canvas
let container = document.querySelector('#contentcontainer')
let pageCanvas = container?.getElementsByTagName("canvas").length>0?container.getElementsByTagName("canvas"):container.getElementsByTagName("img");
//下载文档
await docDown.exportPdf(pageCanvas,title)
}
} catch (error) {
console.log(error)
Utils.toast(error.message,'error')
} finally{
reClick()
}
})
},
//原创力初始化
max_book(){
//创建节点
const docDown = new DocDownload({
preSpeed:400,
platform:'max_book'
})
//获取PPT预览链接
const getOfficeSrc = function(detail){
let previewUrl = detail.preview.pic.view_token
window.open(previewUrl)
}
docDown.start(async (reClick)=>{
try {
let detail = window?.base?.detail||''
if(!detail) throw new TypeError('下载错误,文档参数获取失败')
if(detail.format === "pptx"||detail.format === "ppt") {
getOfficeSrc(detail)
}else{
//输入了页码才检测页码是否正常
let len = document.querySelectorAll('.webpreview-item').length||0
docDown.checkPage(len)
//检测是否有页面未预览成功
docDown.hasPreviewFail = docDown.checkPageHasNoPreview()
if(!docDown.hasPreviewFail){
//标题
let title = window?.base?.detail?.search_q||"原创力文档";
//页面的canvas
let pageCanvas = document.querySelectorAll('.webpreview-item img');
//下载文档
await docDown.exportPdf(pageCanvas,title)
}
}
} catch (error) {
console.log(error)
Utils.toast(error.message,'error')
} finally{
reClick()
}
})
},
max_book_ppt(){
//创建节点
const docDown = new DocDownload({
preSpeed:400,
platform:'max_book_ppt',
autoPreview:false
})
const preview = function(pageCount){
return new Promise(async (resolve, reject) => {
let timer = null
timer = setInterval(()=>{
window.nextPage()
Utils.toast('正在自动预览页面,请勿操作','warning',370)
if(document.querySelector('#PageIndex').textContent == pageCount){
clearInterval(timer)
resolve(true)
}
},400)
})
}
docDown.start(async (reClick)=>{
try {
//输入了页码才检测页码是否正常
let len = document.querySelectorAll('#PageInfo div').length||0
docDown.checkPage(len)
let pageCount = window?.pageCount
if(!pageCount) throw new TypeError('下载错误,文档参数获取失败')
//预览页面
await preview(pageCount)
//获取节点
let pageCanvas = document.querySelectorAll('#view>div')
if(pageCanvas.length > 0){
//标题
let title = "原创力PPT文档";
//下载文档
await docDown.exportPdf(pageCanvas,title)
}
console.log('预览完成')
} catch (error) {
console.log(error)
Utils.toast(error.message,'error')
} finally{
reClick()
}
})
},
//智库
mbalib(){
//创建节点
const docDown = new DocDownload({
preSpeed:400,
platform:'mbalib',
autoPreview:false,
splitDownload:false
})
docDown.start(async reClick =>{
try {
let DEFAULT_URL = window?.DEFAULT_URL||null
if(!DEFAULT_URL) throw new TypeError('DEFAULT_URL:文档下载失败')
Utils.toast('正在获取pdf文件数据')
let content = await Utils.request('GET', DEFAULT_URL, null,null,'blob');
let file_name = window?.wgDocTitle||'智库文档'
Utils.toast('成功获取到pdf文件数据,正在下载')
Utils.save(content,file_name)
} catch (error) {
console.log(error)
Utils.toast(error.message,'error')
} finally{
reClick()
}
})
},
//百度
bdwk(){
//创建节点
const docDown = new DocDownload({
preSpeed:400,
platform:'bdwk',
autoPreview:false,
splitDownload:false
})
docDown.start(reClick=>{
window.open('http://wenku.zhihupe.com/tool/index?url='+encodeURIComponent(window.location.href));
reClick()
})
},
//360
sodoc(){
//创建节点
const docDown = new DocDownload({
preSpeed:400,
platform:'sodoc'
})
docDown.start(async (reClick)=>{
try {
let asyncData = window?.asyncData||null;
if(!asyncData) throw new TypeError('asyncData:文档下载失败');
//输入了页码才检测页码是否正常
let len = asyncData?.DocInfo?.Field03.length||0;
docDown.checkPage(len);
//检测是否有页面未预览成功
docDown.hasPreviewFail = docDown.checkPageHasNoPreview()
if(!docDown.hasPreviewFail){
//标题
let title = asyncData?.DocInfo.Title||'360文档';
//页面的canvas
let pageCanvas = document.querySelectorAll('.wenku-detail__showdoc__imgContainer>img');
//下载文档
await docDown.exportPdf(pageCanvas,title)
}
} catch (error) {
console.log(error)
Utils.toast(error.message,'error')
} finally{
reClick()
}
})
}
}
//---------------------------文库初始化结束-------------------------
//网址匹配
const siteMap = [
{
match:['www.doc88.com/p.*'],
initFunc:wenkuInit.daoke
},
{
match:['www.docin.com/p.*'],
initFunc:wenkuInit.docin
},
{
match:['max.book118.com/html/.*'],
initFunc:wenkuInit.max_book
},
{
match:['view-cache.book118.com/pptView.html','view.*.book118.com'],
initFunc:wenkuInit.max_book_ppt
},
{
match:['doc.mbalib.com/view/.*'],
initFunc:wenkuInit.mbalib
},
{
match:['wenku.baidu.com/view/.*','wenku.baidu.com/tfview/.*'],
initFunc:wenkuInit.bdwk
},
{
match:['wenku.so.com/d/.*'],
initFunc:wenkuInit.sodoc
}
]
//生成正则表达式
function createReg(arr){
return new RegExp(arr.join('|'))
}
//根据网址匹配
for (const site of siteMap) {
let reg = createReg(site.match)
let host = window.location.hostname + window.location.pathname
let result = reg.test(host)
console.log(result,host)
if(result){
return site.initFunc()
}
}
// Your code here...
})();