// ==UserScript==
// @name Discuz论坛头像上传助手
// @author greasepig
// @description 突破图片尺寸、GIF帧数限制,无损上传
// @version 1.0.6
// @namespace http://userscripts.org/users/greasepig
// @include http://*/home.php?mod=spacecp&ac=avatar*
// @run-at document-end
// @grant GM_xmlhttpRequest
// @downloadURL https://update.greasyfork.icu/scripts/2253/Discuz%E8%AE%BA%E5%9D%9B%E5%A4%B4%E5%83%8F%E4%B8%8A%E4%BC%A0%E5%8A%A9%E6%89%8B.user.js
// @updateURL https://update.greasyfork.icu/scripts/2253/Discuz%E8%AE%BA%E5%9D%9B%E5%A4%B4%E5%83%8F%E4%B8%8A%E4%BC%A0%E5%8A%A9%E6%89%8B.meta.js
// ==/UserScript==
(function(){
var mycamera, action, query;
mycamera = document.getElementsByName('mycamera')[0];
if (mycamera == null) return;
query = mycamera.src.match(/^(.*)images\/camera\.swf.*(&appid=\d+).*(&input=.+&agent=[^&]+)/);
action = query[1] + 'index.php?m=user&inajax=1&a=rectavatar' + query[2] + query[3] + '&avatartype=virtual';
var out = document.createElement('div');
out.innerHTML = '
';
mycamera.parentNode.appendChild(out);
var btnSubmit = document.getElementById("submit");
var statusIcon = document.getElementById("status");
var uploadProgress = document.getElementById("progress");
var avatars = {
big: {img: document.getElementById("img_b"), hex: null},
middle: {img: document.getElementById("img_m"), hex: null},
small: {img: document.getElementById("img_s"), hex: null}
};
function readFile (onloadFunc) {
var reader = new FileReader();
reader.onload = onloadFunc;
return reader;
}
function showImage(target, file){
readFile(function(e){
avatars[target].img.src = e.target.result;
}).readAsDataURL(file);
}
function byte2hex(bytes) {
var uint8Array = new Uint8Array(bytes);
var hex = '';
for (var i = 0; i < uint8Array.length; i++) {
hex += uint8Array[i] < 16 ? '0' + uint8Array[i].toString(16) : uint8Array[i].toString(16);
}
return hex.toUpperCase();
}
function getImageHexString(target, file){
readFile(function(e){
avatars[target].hex = byte2hex(e.target.result);
if (avatars.big.hex && avatars.middle.hex && avatars.small.hex) {
btnSubmit.removeAttribute("disabled");
}
}).readAsArrayBuffer(file);
}
function handleFile(target, file){
var imageType = /image\/.*/;
if (!file.type.match(imageType)) {
alert("不是有效的图像文件!");
return;
}
if (file.size > 2097152) {
alert("文件大小必须在2M以内!");
return;
}
avatars[target].img.src = "http://bcs.duapp.com/user-img/discuz-avatar/loading.gif";
setTimeout(function(){
getImageHexString(target, file);
showImage(target, file);
}, 100);
}
function bindOpenFile(id) {
var handleBox = document.getElementById(id);
handleBox.addEventListener("click", function(e){
var file = document.createElement("input");
file.type = "file";
file.addEventListener("change", function(e){
handleFile(id, e.target.files[0]);
});
file.click();
}, false);
}
function gm_post(url, post) {
GM_xmlhttpRequest({
method: "POST",
url: url,
data: post,
headers: {"Content-Type": "application/x-www-form-urlencoded"},
onload: onloadHandler,
onerror: onerrorHandler,
upload: {onprogress: uploadOnprogressHandler}
});
}
function ajaxPost(url, post) {
var xhr = new XMLHttpRequest();
// xhr.onload = onloadHandler;
xhr.onload = function(e) {onloadHandler(e.target)};
xhr.onerror = onerrorHandler;
// xhr.onloadend = onloadendHandler;
xhr.upload.onprogress = uploadOnprogressHandler;
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(post);
}
function onloadHandler(response) {
uploadProgress.textContent = "100%";
var xml = (new DOMParser()).parseFromString(response.responseText, "text/xml");
// unsafeWindow.console.log(xml);
if (xml) {
var success = xml.querySelector('face');
if (success != null && success.getAttribute("success") == 1) {
statusIcon.className = "success";
} else {
statusIcon.className = "error";
var message = xml.querySelector('message');
if (message)
uploadProgress.textContent = message.getAttribute('type') + ': ' + message.getAttribute('value');
else uploadProgress.textContent = response.responseText;
}
} else {
statusIcon.className = "error";
uploadProgress.textContent = 'error: no responseXML';
}
onloadendHandler();
}
function onerrorHandler(e) {
statusIcon.className = "error";
onloadendHandler();
}
function onloadendHandler(e) {
btnSubmit.removeAttribute("disabled");
}
function uploadOnprogressHandler(e) {
if (e.lengthComputable) {
uploadProgress.textContent = Math.round(100 * e.loaded / e.total) + "%";
}
}
function upload() {
var post = "avatar1=" + avatars.big.hex + "&avatar2=" + avatars.middle.hex + "&avatar3=" + avatars.small.hex + "&urlReaderTS=" + Date.now();
btnSubmit.setAttribute("disabled", "disabled");
statusIcon.style.display = "block";
statusIcon.className = "loading";
if (navigator.userAgent.indexOf('Firefox') > 0)
gm_post(action, post);
else
ajaxPost(action, post);
}
bindOpenFile("big");
bindOpenFile("middle");
bindOpenFile("small");
btnSubmit.addEventListener("click", upload);
})();