您需要先安装一款用户样式管理器扩展(如 Stylus)后才能安装此样式。
您需要先安装一款用户样式管理器扩展(如 Stylus)后才能安装此样式。
您需要先安装一款用户样式管理器扩展(如 Stylus)后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
您需要先安装一款用户样式管理器扩展后才能安装此样式。
(我已经安装了用户样式管理器,让我安装!)
// ==UserScript==
// @name Extract images for tieba.baidu.com
// @name:zh 贴吧壁纸收割机
// @namespace https://github.com/cmheia/extract-images-for-tieba
// @description Adds a button that get all attached images as original size to every post.
// @include http://tieba.baidu.com/p/*
// @author cmheia
// @version 0.3.1
// @icon http://tb1.bdstatic.com/tb/favicon.ico
// @grant GM_setClipboard
// @grant GM_xmlhttpRequest
// @license MPL
// ==/UserScript==
(function () {
'use strict';
var $id = function (o) {
return document.getElementById(o);
};
// 去重
var doUnique = function (arr) {
var result = [],
hash = {};
for (let i = 0, elem; (elem = arr[i]) !== undefined; i++) {
if (!hash[elem]) {
result.push(elem);
hash[elem] = true;
}
}
return result;
};
// 插入样式表
var apendStyle = function (cssText) {
var head = document.head || document.querySelectorAll('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
var textNode = document.createTextNode(cssText);
style.appendChild(textNode);
head.appendChild(style);
};
// 创建样式表
var addStyle = function () {
apendStyle(".margin8 {margin:8px;} .preview_item {padding:3px;display:inline-block;vertical-align:top;position:relative;} .preview_box {max-width:300px;max-height:300px;vertical-align:bottom;} .preview_container {z-index:11000;} .preview_selector {position:absolute;left:0;} .preview_excluded {background:#FFCCFF;}");
};
// 页面显示信息
var msg = function (msg) {
$id("extracted").innerHTML = msg;
};
// 取得分页数量
var getPages = function () {
var l_posts_num = document.querySelectorAll('.l_posts_num > li > span.red');
return parseInt(l_posts_num[l_posts_num.length - 1].innerText);
};
// 取得IMG标签中的SRC
var getImgTags = function (content) {
// console.group("取得IMG标签中的SRC");
let images1 = content.match(/<img[^<>]*class=\"BDE_Image\"[^<>]*src\=\"(?:(?:(?:http|https)\:\/\/)?[^<>]*(?:jpg|jpeg|gif|png|webp))\"[^<>]*>/g);
let images2 = content.match(/<img[^<>]*src\=\"(?:(?:(?:http|https)\:\/\/)?[^<>]*(?:jpg|jpeg|gif|png|webp))\"[^<>]*class=\"BDE_Image\"[^<>]*>/g);
let images = null;
if (null === images1 && null === images2) {
return [];
}
if (null !== images1 && null === images2) {
images = images1;
}
if (null === images1 && null !== images2) {
images = images2;
}
if (null !== images1 && null !== images2) {
images = images1.concat(images2);
images1 = images2 = null;
}
// console.log("匹配结果", images);
var imageSrc = [];
if (null !== images) {
imageSrc = images.map(function (val, i) {
let src = val.match(/(?:(?:http|https):\/\/)([^\.]*)([^\/]*)(.*)(?:\.(?:jpg|jpeg|gif|png|webp))/);
// console.log(i, val);
// console.log(src);
if (null !== src) {
if ("adscdn" === src[1] || ".bdstatic.com" === src[2] ) {
// 先去广告
// console.log("去广告");
return undefined;
}
if (".baidu.com" === src[2] || ".bdimg.com" === src[2]) {
let m = src[0].match(/(?:[\w\d\.]+)(?:jpg|jpeg|gif|png|webp)/);
// console.log("return", m);
return `http://imgsrc.baidu.com/forum/pic/item/${m[0]}`;
}
if (".sinaimg.cn" === src[2]) {
let m = src[0].match(/((?:http|https)\:\/\/[\w\d\.]+)sinaimg\.cn\/([\w\d]+)\/([\w\d\.\?]+)/);
// console.log("return", m);
return `${m[1]}sinaimg.cn/large/${m[3]}`;
}
// console.log("原始链接", src[0]);
return src[0];
} else {
return undefined;
}
});
}
for (let i = imageSrc.length - 1; i >= 0; i--) {
if (undefined === imageSrc[i]) {
imageSrc.splice(i, 1);
}
}
// console.log(imageSrc);
// console.groupEnd();
return imageSrc;
};
// 取得单个分页原图链接
var extractSinglePage = function (content) {
var images = getImgTags(content);
var result = doUnique(images);
// console.warn(result);
if (null === result || 0 === result.length) {
return null;
}
return result;
};
// 取得所有分页原图链接
var extractAllPages = function (pages, auto) {
var imageSrc = {};
var parsedPages = 0;
var failedPages = 0;
var collectImages = function () {
if (pages === parsedPages) {
// console.debug("提取失败", failedPages, "页");
var imageSrcArray = [];
for (let i in imageSrc) {
// console.debug("第", i, "页", imageSrc[i].length, "图");
for (let j of imageSrc[i]) {
imageSrcArray.push(j);
}
}
var result = doUnique(imageSrcArray);
if (null === result || 0 === result.length) {
msg("然而并没有图片 (╯#-_-)╯~~~~~~~~~~~~~~~~~╧═╧");
} else {
exportAlbum(result, auto);
}
}
};
var parseRespond = function (xhr) {
var currentPage = xhr.finalUrl.replace(/http\:\/\/tieba.baidu.com\/p\/(\d+)\?pn=(\d+)$/, "$2") - 1;
imageSrc[currentPage] = getImgTags(xhr.response);
parsedPages++;
msg(`到手${parsedPages}页,就剩${(pages - parsedPages)}页啦 (ฅ´ω\`ฅ)`);
collectImages();
};
var xhrErrorHandler = function (xhr) {
var currentPage = xhr.finalUrl.replace(/http\:\/\/tieba.baidu.com\/p\/(\d+)\?pn=(\d+)$/, "$2") - 1;
msg(`第${currentPage}页提取失败 (ಥ_ಥ)`);
// console.debug(`第${currentPage}页提取失败 (ಥ_ಥ)`);
parsedPages++;
failedPages++;
collectImages();
};
for (let i = 1; i <= pages; i++) {
let url = window.location.origin + window.location.pathname + "?pn=" + i;
GM_xmlhttpRequest({
method : 'GET',
url : url,
onload : parseRespond,
onerror : xhrErrorHandler
});
}
};
// 仅收割当前分页
var extracterImage = function (auto) {
var result = extractSinglePage(document.querySelector('#j_p_postlist').innerHTML);
if (null !== result && 0 < result.length) {
exportAlbum(result, auto);
} else {
msg("然而并不能收割 (╯#-_-)╯~~~~~~~~~~~~~~~~~╧═╧");
}
};
// 收割全部分页
var extracterImages = function (auto) {
// console.clear();
var pages = getPages();
if (0 === pages) {
msg("度娘又改版了 (╯#-_-)╯~~~~~~~~~~~~~~~~~╧═╧");
} else if (1 === pages) {
let result = extractSinglePage(document.querySelector('#j_p_postlist').innerHTML);
if (null !== result && 0 < result.length) {
exportAlbum(result, auto);
} else {
msg("然而并不能收割 (╯#-_-)╯~~~~~~~~~~~~~~~~~╧═╧");
}
} else {
extractAllPages(pages, auto);
msg("正在搞这 " + pages + " 页图,不要急嘛 (๑•̀_•́๑)");
}
};
// 新建图集
var exportAlbum = function (images, auto) {
if (null === images || 0 === images.length) {
return;
}
var imageCount = images.length;
if (auto) {
GM_setClipboard(images.join("\r\n"));
msg(`搞到这${imageCount}张图啦 (⺻▽⺻ )`);
return;
}
// 删除图集
var removeAlbum = function () {
if (null !== $id("preview_window")) {
document.body.removeChild($id("preview_window"));
}
msg("");
};
// 恢复被隐藏的元素
var showOtherElements = function () {
for (let i = 0; i < document.body.children.length; i++) {
if ("DIV" === document.body.children[i].tagName && "y" === document.body.children[i].getAttribute("data-hide")) {
document.body.children[i].style.display = "";
}
}
document.querySelector(".tbui_aside_float_bar").style.display = "";
};
// 隐藏无关元素
var hideOtherElements = function () {
for (let i = 0; i < document.body.children.length; i++) {
if ("DIV" === document.body.children[i].tagName && "com_userbar_message" !== document.body.children[i].id) {
document.body.children[i].style.display = "none";
document.body.children[i].setAttribute("data-hide", "y");
}
}
document.querySelector(".tbui_aside_float_bar").style.display = "none";
};
// 导出选中图片链接
var exportSelected = function () {
var items = $id("preview_list");
var counts = items.children.length;
var result = [];
for (let i = 0; i < counts; i++) {
if (items.children[i].children[1].checked) {
result.push(items.children[i].children[0].src);
}
}
if (0 < result.length) {
GM_setClipboard(result.join("\r\n"));
$id("export_msg").innerHTML = "搞到这" + result.length + "张图啦 (⺻▽⺻ )";
} else {
$id("export_msg").innerHTML = "至少选择一张图吧 ◔ ‸◔?";
}
};
// 关闭图片墙
var closePreviewWindow = function () {
showOtherElements();
$id("preview_window").style.display = "none";
};
// 选中全部图片
var previewSelectAll = function () {
var items = $id("preview_list");
var counts = items.children.length;
for (let i = 0; i < counts; i++) {
items.children[i].children[1].checked = true;
items.children[i].className = "preview_item";
}
$id("previewer_selected").innerHTML = counts;
};
// 反选
var previewSelectInvert = function () {
var items = $id("preview_list");
var counts = items.children.length;
for (let i = 0; i < counts; i++) {
items.children[i].children[1].checked = !items.children[i].children[1].checked;
items.children[i].className = (items.children[i].children[1].checked) ? "preview_item" : "preview_item preview_excluded";
}
$id("previewer_selected").innerHTML = counts - parseInt($id("previewer_selected").innerHTML);
};
// 点击图片切换选中状态
var previewSelector = function (o) {
o.nextSibling.checked = !o.nextSibling.checked;
var selected = $id("previewer_selected");
selected.innerHTML = parseInt(selected.innerHTML) + ((o.nextSibling.checked === true) ? 1 : -1);
if (o.nextSibling.checked) {
o.parentNode.className = "preview_item";
} else {
o.parentNode.className = "preview_item preview_excluded";
}
};
// 创建控制栏
var controller = document.createElement('div');
controller.id = "previewer_ctrl";
controller.style = "position:relative";
var info = document.createElement('span');
info.id = "previewer_info";
info.className = "margin8";
info.innerHTML = "共<span class='red'>" + imageCount + "</span>图,已选<span id='previewer_selected' class='red'>" + imageCount + "</span>图";
controller.appendChild(info);
var buttonClose = document.createElement('a');
buttonClose.href = "javascript:;";
buttonClose.className = "margin8";
buttonClose.innerHTML = "关闭图片墙";
buttonClose.addEventListener("click", closePreviewWindow);
controller.appendChild(buttonClose);
var buttonSelectAll = document.createElement('a');
buttonSelectAll.href = "javascript:;";
buttonSelectAll.className = "margin8";
buttonSelectAll.innerHTML = "全选";
buttonSelectAll.addEventListener("click", previewSelectAll);
controller.appendChild(buttonSelectAll);
var buttonInvert = document.createElement('a');
buttonInvert.href = "javascript:;";
buttonInvert.className = "margin8";
buttonInvert.innerHTML = "反选";
buttonInvert.addEventListener("click", previewSelectInvert);
controller.appendChild(buttonInvert);
var buttonExportSelected = document.createElement('a');
buttonExportSelected.href = "javascript:;";
buttonExportSelected.className = "margin8";
buttonExportSelected.innerHTML = "导出选定图片";
buttonExportSelected.addEventListener("click", exportSelected);
controller.appendChild(buttonExportSelected);
var message = document.createElement('span');
message.id = "export_msg";
message.className = "margin8";
controller.appendChild(message);
// 创建图片列表
var itemList = document.createElement('ul');
itemList.id = "preview_list";
var previewer = document.createElement('div');
previewer.id = "preview_matrix";
previewer.appendChild(itemList);
for (let i = 0; i < imageCount; i++) {
let item = document.createElement('li');
item.innerHTML = "<img id='" + "preview_img_" + i + "' class='preview_box' src='" + images[i] + "'><input type='checkbox' id='" + "preview_cb_" + i + "' class='preview_selector' checked='checked'>";
item.className = "preview_item";
item.children[0].addEventListener("click", function () {
previewSelector(this);
});
itemList.appendChild(item);
}
// 删除旧的图片墙
removeAlbum();
var container = document.createElement('div');
container.id = "preview_window";
container.className = "preview_container";
container.appendChild(controller);
container.appendChild(previewer);
hideOtherElements();
document.body.appendChild(container);
var button = document.createElement('a');
button.href = "javascript:;";
button.innerHTML = "打开图片墙";
button.addEventListener("click", function () {
hideOtherElements();
$id("preview_window").style.display = "";
});
$id("extracted").appendChild(button);
};
// 添加按钮
var addButton = function () {
var button = document.createElement('li');
button.innerHTML = "<a href='javascript:;' class='margin8'>收割</a><span id='extracted'></span>";
button.class = "l_reply_num";
button.children[0].addEventListener("click", function () {
extracterImages(false);
});
document.addEventListener("keyup", function (event) {
// F9 = 120
// F10 = 121
if (120 === event.keyCode) {
extracterImage(true);
} else if (121 === event.keyCode) {
extracterImages(true);
}
}, true);
document.querySelector('.l_posts_num').appendChild(button);
};
// 运行
(function () {
var DOMObserverTimer = false;
var DOMObserverConfig = {
attributes : true,
childList : true,
};
var DOMObserver = new MutationObserver(function () {
if (DOMObserverTimer !== 'false') {
clearTimeout(DOMObserverTimer);
}
DOMObserverTimer = setTimeout(function () {
DOMObserver.disconnect();
if (!$id("extracted")) {
// console.log("重新添加按钮");
addButton();
}
DOMObserver.observe(document.querySelector('#j_p_postlist'), DOMObserverConfig);
}, 100);
});
DOMObserver.observe(document.querySelector('#j_p_postlist'), DOMObserverConfig);
})();
addStyle();
addButton();
})();