// ==UserScript==
// @name 免Flash文件上传
// @name:en Upload without Flash
// @namespace https://greasyfork.org/zh-CN/users/605474
// @version 1.2
// @description 无需调用Flash,从课程平台上传附件,不必为了传作业多装一个浏览器!
// @description:en No need to call Flash, upload accessories from the course platform, do not have to make multiple browsers for the homework!
// @author Ziu
// @match *://cc.bjtu.edu.cn:81/*
// @match *://cc.bjtu.edu.cn:81/meol/common/hw/student/write.jsp?hwtid=*
// @icon https://gitee.com/ziuc/utool-filebed/raw/master/20210514-231824-0795.png
// @require https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js
// @require https://cdn.bootcdn.net/ajax/libs/jquery/1.7.2/jquery.min.js
// @grant none
// @license MIT
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
// 上传回调函数全局变量
let index = 0;
let isAbort = 0;
let oloaded = 0;
let ot = 0;
// 预置DOM
let frontTag = "
上传作业 ";
let uploadBox = ' '
let uploadBtn = '上传   ';
let emptyBtn = '清空 ';
// 外部DOM操作
$('#tmenu').append(frontTag);
$('.infotable>tbody>tr:contains("请输入你的答案")').after(uploadBox);
// 信息显示部分
let upldIconList = ['🕒','⚡','✅','🕒','⌛','🔒','✅']; // 所有icon统一管理
let infoIconList = ['🔄','⚠','🚫','🕒','⌛','🔒','✅']; // 所有icon统一管理
// 动效
$('#inputDiv').mouseenter(function (){$('#inputDiv').css('background-color','#87bd04');$('#textShow').css('color','#e7e8e0')});
$('#inputDiv').mouseleave(function (){$('#inputDiv').css('background-color','#c6f062');$('#textShow').css('color','#5c6b77')});
$('tr').mouseenter(function(){$(this).css('background','#f2f2f2')});
$('tr').mouseleave(function(){$(this).css('background','#ffffff')});
// 文件选择前事件监听
$('#inputDiv').click(function (){$('#currentFile').trigger('click');});
$('#currentFile').change(fileChangedByInput);
function fileChangedByInput(){
let filelist = $('#currentFile')[0].files;
// 缓存区展示
$('#inputDiv').hide(); // 隐藏上传框
$('#filenames, #buttonDiv').empty(); // 先清空 再插入
let sizeType = getSizeType(filelist);
let nameType = getNameType(filelist); // todo
for(let i=0;i📄   |  '+item.showName+' ('+item.sizeType.size+item.sizeType.type+')'+' ';
$('#filenames').append(fileObject);
}
// 文件选择后外部DOM插入
$('#buttonDiv').append(uploadBtn);
$('#buttonDiv').append(emptyBtn);
// 文件选择后事件监听
$('#emptyTrigger').click(function (){$('#currentFile').val('');$('#filenames, #buttonDiv').empty();$('#inputDiv').show();isAbort=1;});
$('#uploadTrigger').click(function (){
// 处理文件缓存区
$('#uploadTrigger').hide();
$('#uploadTrigger').css('cursor','not-allowed');
isAbort = 0; // 按上传之前按过清空,将isAbort置回0
sendFileMsg();
function sendFileMsg(){
if(index >= filelist.length){
// 递归结束
$('#currentFile').val(''); // 文件清空
$('#emptyTrigger').css('cursor','pointer');
index = 0; // 递归条件置零
return // 结束递归
}
let formData = new FormData();
formData.append('Filename', filelist[index].name);
formData.append('Filedata', filelist[index]);
let xReq = new XMLHttpRequest();
xReq.open('POST','http://cc.bjtu.edu.cn:81/meol/servlet/SerUpload');
xReq.addEventListener("load", onSuccess);
xReq.addEventListener("error", onError);
xReq.upload.onloadstart = onStart;
xReq.upload.onprogress = onProgress;
xReq.upload.onabort = onAbort;
xReq.send(formData);
function onStart(){
ot = new Date().getTime(); // 设置上传开始时间,用以计算时间速度
oloaded = 0; // 设置上传开始时,已上传的文件大小为0
}
function onProgress(evt){
if(isAbort==1){
xReq.abort(); // 上传过程中随时检查,终止请求
}
// 进度计算
let percentage;
percentage = (evt.loaded * 100 / evt.total).toFixed(0);
// 速度计算
let nt = new Date().getTime(); // 获取当前时间
let perTime = (nt-ot)/1000; // 计算出上次调用该方法时到现在的时间差,单位为s
ot = new Date().getTime(); //重新赋值,用以下次计算
let perLoad = evt.loaded - oloaded; // 计算该分段上传的文件大小,单位b
oloaded = evt.loaded; // 重新赋值,用以下次计算
let speed = perLoad/perTime; // 单位 B/s
let bspeed = speed;
let Sunits = 'B/s';
if(speed/1024>1){
speed = speed/1024;
Sunits = 'KB/s'
}
if(speed/1024>1){
speed = speed/1024;
Sunits = 'MB/s';
}
speed = speed.toFixed(1);
// 时间计算 文件>100MB触发
if(evt.total>104857600){
let restTime = ((evt.total-evt.loaded)/bspeed).toFixed(0);
// 更新文件缓存区
$('#timeRemainTh'+index).html('  |  '+upldIconList[0]+restTime+'秒');
}
// 更新文件缓存区
$('#fileTh'+index).css('background-size',percentage+'%');
$('#speedTh'+index).html('  |  '+upldIconList[1]+speed+Sunits);
}
function onAbort(){
isAbort = 0; // 终止条件置零
index = 0; // 请求终止后index也必须归零,因为中止未完成递归,若中止文件index>0则第二次上传请求无法发起
}
function onSuccess(){
// 插入编辑器操作
let myiframe = document.getElementsByTagName('iframe')[1].contentDocument;
let textArea = myiframe.getElementsByClassName('cke_show_borders');
let constructor = ''+filelist[index].name+'
'
$(textArea).append(constructor);
// 处理缓存区操作
$('#speedTh'+index).html('  |  '+upldIconList[2]);
$('#speedTh'+index).attr('title','[已上传]');
$('#timeRemainTh'+index).remove();
$('#fileTh'+index).css('background','#c6f062');
// 递归操作
index++;
sendFileMsg();
}
function onError(){
alert('上传失败');
}
}
})
}
function getSizeType(filelist){
let RtnsizeType = [];
for(let item of filelist){
let sizeTypeTMP = {};
if(item.size<1024){
sizeTypeTMP.size = (item.size).toFixed(2);
sizeTypeTMP.type = 'B';
}
else if(item.size>1024&&item.size<1048576){
sizeTypeTMP.size = (item.size/1024).toFixed(2);
sizeTypeTMP.type = 'KB';
}
else if(item.size>1048576&&item.size<1073741824){
sizeTypeTMP.size = (item.size/1048576).toFixed(2);
sizeTypeTMP.type = 'MB';
}
else if(item.size>1073741824){
alert('你选择了大于1GB的文件,服务器存储资源有限,建议选择其他传输方式。');
sizeTypeTMP.size = (item.size/1073741824).toFixed(2);
sizeTypeTMP.type = 'GB';
}
RtnsizeType.push(sizeTypeTMP);
}
return RtnsizeType;
}
function getNameType(filelist){
// 文件名显示长度限制
let nameType = [];
let limit = 25;
for(let item of filelist){
let splitName = item.name.split('.'); // 预防文件名中含.的情况
let newName = '';
for(let i=0;ilimit){
newName = newName.slice(0,limit) + '...';
}
nameType.push(newName);
}
return nameType;
}
function judgeOnceInPage(){
if($("script:contains('该作业不允许重复提交,确定提交作业吗?')").length!=0){
let newspan = '(只能提交一次) ';
$('span:contains("查看作业任务")').after(newspan);
alert("注意,此作业只能提交一次,请检查无误后再提交!");
return 1;
}
else return 0;
}
function getInfoList(){
let initInfoList = $('.infolist');
let initSubmits = $('.enter');
let infoList = [];
for(let i=0;i'
$(".infolist[href='hwtask.view.jsp?hwtid="+infoTMP.id+"']").before(attentionIcon);
}
else {
let attentionIcon = ''+infoIconList[3]+' '
$(".infolist[href='hwtask.view.jsp?hwtid="+infoTMP.id+"']").before(attentionIcon);
}
}
function onError(){
alert('请求失败');
}
}
function appendSubmitInfo(hwtid){
if(!infoTMP.able){
// 过期作业,不发请求
return
}
// 检查是否已经提交
let url = 'http://cc.bjtu.edu.cn:81/meol/common/hw/student/taskanswer.jsp?hwtid='+hwtid;
let data = 'hwtid='+hwtid;
let xReq = new XMLHttpRequest();
xReq.responseType = "document";
xReq.open('GET',url,true); // 注意,此处请求应当为异步请求 用以接收text/html数据
xReq.addEventListener("load", onSuccess);
xReq.addEventListener("error", onError);
xReq.send(data);
function onSuccess(){
let myResponse = this.responseXML;
let iptArea = $(myResponse).find("tr:contains('回答的内容')+tr>td>input");
if(iptArea.length<=0){
let submitIcon = ''+infoIconList[4]+' '
$(".infolist[href='hwtask.view.jsp?hwtid="+infoTMP.id+"']").before(submitIcon);
}
else{
let submitIcon = ''+infoIconList[6]+' '
$(".infolist[href='hwtask.view.jsp?hwtid="+infoTMP.id+"']").before(submitIcon);
}
}
function onError(){
alert('请求失败');
}
}
}
return infoList;
}
// 页面加载完毕,执行拖拽上传功能
window.onload = function () {
if($("span:contains('查看作业任务')").length==0){
// 判断是否在作业页面
return
}
let oBox = document.getElementById('inputDiv');
let timer = null;
document.ondragover = function(){
clearTimeout(timer);
timer = setTimeout(function(){
// 文件放下后执行操作
$('#p1').html('📁文件上传📝');
$('#inputDiv').css('background-color','#c6f062');$('#textShow').css('color','#5c6b77');
},200);
};
// 进入子集的时候 会触发ondragover 频繁触发 不给ondrop机会
oBox.ondragover = function(){
return false;
};
oBox.ondragleave = function(){
$('#p1').html('📌请将文件拖拽到此区域');
$('#inputDiv').css('background-color','#87bd04');$('#textShow').css('color','#e7e8e0');
};
oBox.ondrop = function(ev){
$('#currentFile')[0].files = ev.dataTransfer.files;
fileChangedByInput();
return false;
};
};
// 列表信息增强与单词提交判断函数触发
judgeOnceInPage();
getInfoList();
})();