// ==UserScript==
// @name Come Back Tieba Thumbnails
// @namespace https://gf.qytechs.cn/zh-CN/users/14997-lrh3321
// @homepageURL https://gf.qytechs.cn/zh-CN/scripts/31662-come-back-tieba-thumbnails
// @version 0.1.1
// @description 让被设置为页游的贴吧首页能正常显示缩略图
// @author LRH3321
// @match *://tieba.baidu.com/f*
// @icon http://www.baidu.com/favicon.ico
// @connect baidu.com
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// ==/UserScript==
(function () {
'use strict';
if (!document.body.classList.contains("app_forum_body"))
return;
var hooked = false;
BigpipeHook();
thumbnailsBack();
function BigpipeHook() {
if (hooked)
return;
var originalBroadcast = Bigpipe.broadcast;
hooked = true;
Bigpipe.broadcast = function (e, t) {
// console.log(e, t);
var r = originalBroadcast(e, t);
if (e === "page_change") {
window.setTimeout(thumbnailsBack, 1000);
// thumbnailsBack();
}
return r;
};
}
function thumbnailsBack() {
console.log("Getting thumbnails.");
var MOBILE_USER_AGENT = "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1";
function addImgsEventListener(li) {
li.onmouseover = function (ev) {
MiniblogImgPop.smallImg = this;
this.style.opacity = '0.84';
PopImg.show(this);
};
li.onmouseout = function (ev) {
this.style.opacity = '';
PopImg.hide();
};
li.onmousemove = function (ev) {
PopImg.move(this);
};
}
function createUList(tid, items) {
var ul = document.createElement("ul");
ul.className = "threadlist_media j_threadlist_media clearfix";
ul.id = "fm" + tid;
ul.style.cssFloat = "left";
for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
var el = items_1[_i];
var li = document.createElement("li");
if (el.hasAttribute("v_href")) {
console.log(el);
if (el)
continue;
// 视频帖
var div = document.createElement("div");
div.className = "threadlist_video";
var img = document.createElement("img");
img.src = el.src;
div.appendChild(img);
var a = document.createElement("a");
a.href = "#";
a.className = "threadlist_btn_play j_m_flash";
a.dataset.threadid = tid;
a.dataset.forumid = PageData.forum.id.toString();
a.dataset.isfive = "0";
a.dataset.video = el.getAttribute("v_href");
a.dataset.vsrc = el.getAttribute("v_href");
a.dataset.type = "movideo";
a.dataset.duration = "";
div.appendChild(a);
li.appendChild(div);
}
else {
var a = document.createElement("a");
a.className = "thumbnail vpic_wrap";
var img = document.createElement("img");
img.className = "threadlist_pic j_m_pic";
img.style.display = "inline";
img.style.width = "90px";
img.style.height = "90px";
var src = el.getAttribute("data-url");
var arr = src.split("/");
var pid = arr.pop();
img.src = src;
img.setAttribute("data-original", src);
img.setAttribute("bpic", "//imgsrc.baidu.com/forum/pic/item/" + pid);
a.appendChild(img);
li.appendChild(a);
}
addImgsEventListener(li);
ul.appendChild(li);
}
return ul;
}
function crateSmallWrap(tid, count, items) {
var wrap = document.createElement("div");
wrap.className = "small_wrap j_small_wrap";
wrap.setAttribute("is_handle", "true");
var anchor = document.createElement("a");
anchor.onclick = function () { return false; };
anchor.style.display = "none";
anchor.className = "small_btn_pre j_small_pic_pre";
wrap.appendChild(anchor);
anchor = anchor.cloneNode(true);
anchor.className = "small_btn_next j_small_pic_next";
wrap.appendChild(anchor);
var smallList = document.createElement("div");
smallList.className = "small_list j_small_list cleafix";
var smallListGallery = document.createElement("div");
smallListGallery.className = "small_list_gallery";
smallListGallery.appendChild(createUList(tid, items));
if (count) {
var smallPicNum = document.createElement("div");
smallPicNum.className = "small_pic_num center_text";
smallPicNum.textContent = "\u5171 " + count + " \u5F20";
smallListGallery.appendChild(smallPicNum);
}
smallList.appendChild(smallListGallery);
wrap.appendChild(smallList);
return wrap;
}
GM_xmlhttpRequest({
method: "GET",
url: location.href + "&_t=" + new Date().getTime(),
headers: { "User-Agent": MOBILE_USER_AGENT },
onload: function (resp) {
if (resp.status < 400) {
// console.log(resp);
var f = document.createElement("div");
f.innerHTML = resp.responseText;
var tlist = f.querySelectorAll("#tlist a.j_common[tid]");
var tarray = Array.from(tlist);
tarray.forEach(function (el) {
var mediasItems = el.querySelectorAll("div.medias_item img");
if (mediasItems.length === 0) {
return;
}
var s = undefined;
var medias_modal = el.querySelector("div.medias_modal");
if (medias_modal) {
s = medias_modal.textContent.trim();
s = s.substring(1, s.length - 1);
}
var tid = el.getAttribute("tid");
var node = document.querySelector("a[href='/p/" + tid + "']");
if (node) {
node.parentElement
.parentElement
.parentElement
.querySelector("div.threadlist_text")
.appendChild(crateSmallWrap(tid, s, mediasItems));
}
});
}
}
});
console.log("Getting done.");
}
/**
* PopImage
* @version 0.0.1
*/
function offset(source) {
var pt = {
x: 0,
y: 0,
width: source.offsetWidth,
height: source.offsetHeight
};
do {
pt.x += source.offsetLeft;
pt.y += source.offsetTop;
source = source.offsetParent;
} while (source);
return pt;
}
/**
* 图片上遮罩的阴影
*/
var MaskStatic = (function () {
function MaskStatic() {
}
MaskStatic.prototype.show = function (e) {
var smallImg = MiniblogImgPop.smallImg, bigImg = PopImg.img;
this.sOffset = offset(smallImg);
// 表示放大的倍数
this.scale = (bigImg.height + 14) * 1.0 / this.sOffset.height;
// 计算出bar的高度
if (window.innerHeight < bigImg.height) {
this.height = parseInt((window.innerHeight / this.scale).toString(), 10);
}
else {
this.height = this.sOffset.height;
}
// 计算bar的Top值可以允许的范围
this.range = this.sOffset.height - this.height;
// 计算 mask 的位置
this.nodes[0].style.left = this.sOffset.x + 'px';
this.nodes[0].style.width = this.sOffset.width + 'px';
this.nodes[0].style.top = this.sOffset.y + 'px';
this.nodes[1].style.left = this.sOffset.x + 'px';
this.nodes[1].style.width = this.sOffset.width + 'px';
this.nodes[1].style.bottom = (window.innerHeight - this.sOffset.y - this.sOffset.height) + 'px';
this.move(e);
this.nodes[0].style.opacity = "0.7";
this.nodes[1].style.opacity = "0.7";
};
MaskStatic.prototype.hide = function () {
this.nodes[0].style.opacity = '0';
this.nodes[1].style.opacity = '0';
this.nodes[0].style.height = '0';
this.nodes[1].style.height = '0';
};
MaskStatic.prototype.move = function (e) {
// 计算鼠标相对于元素的位置
var x = e.pageX - this.sOffset.x, y = e.pageY - this.sOffset.y;
// 计算bar的top值
var top = y - this.height / 2;
top = top < 0 ? 0 : top;
top = top > this.range ? this.range : top;
this.top = top;
this.nodes[0].style.height = top + 'px';
this.nodes[1].style.height = (this.sOffset.height - top - this.height) + 'px';
};
MaskStatic.prototype.init = function () {
var node1 = document.createElement('div');
node1.className = 'miniblogImgPop-mask';
document.body.appendChild(node1);
var node2 = document.createElement('div');
node2.className = 'miniblogImgPop-mask';
document.body.appendChild(node2);
this.nodes = [node1, node2];
};
return MaskStatic;
}());
var PopImgStatic = (function () {
function PopImgStatic() {
}
PopImgStatic.prototype.show = function (e) {
this.allowMove = false;
// fix firefox 22 beta 1
this._hideTimer && window.clearTimeout(this._hideTimer);
var that = this;
var smallImg = MiniblogImgPop.smallImg;
var src = this.getBigImgsrc(smallImg);
this.img.src = src;
this.imgWidth = 500;
imgReady(src, function () {
that.imgWidth = this.width;
that.layoutImg(e);
that.img.style.opacity = '1';
that.img.style.visibility = 'visible';
that.img.style.marginTop = '-15px';
Mask.show(e);
// 换算图片显示高度
// 1. 宽度超过 500 时,高度要等比例压缩
// 2. 加上边框高度
var imgDisplayHeight;
if (this.width > 500) {
imgDisplayHeight = (this.height + 14) * 500 / this.width;
}
else {
imgDisplayHeight = this.height + 14;
}
if (window.innerHeight > imgDisplayHeight) {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
that.img.style.top = (scrollTop + (window.innerHeight - imgDisplayHeight) / 2 + 15) + 'px';
that.allowMove = false;
}
else {
that.allowMove = true;
that.move(e);
}
});
};
/**
* 设置大图的宽度与位置
*/
PopImgStatic.prototype.layoutImg = function (e) {
var pos = offset(MiniblogImgPop.smallImg);
var left = pos.x + pos.width + 30;
var width = Math.min(this.imgWidth, 500);
// 如果小图右边放不下
if (left + width > window.innerWidth) {
left = pos.x - width - 30;
// 如果左边也放不下
if (left < 0) {
// 根据鼠标位置,选择空间大的一侧放置
if (e.pageX > window.innerWidth / 2) {
// 放置在左边
width = Math.min(width, e.pageX - 30);
left = 0;
}
else {
// 放置在右边
width = Math.min(width, window.innerWidth - e.pageX - 30);
left = window.innerWidth - width;
}
}
}
this.img.style.width = width + 'px';
this.img.style.left = left + 'px';
};
PopImgStatic.prototype.hide = function () {
var that = this;
this.img.style.opacity = '0';
this.img.style.marginTop = '0px';
Mask.hide();
this.shown = false;
this._hideTimer = window.setTimeout(function () {
that.img.src = '';
that.img.style.visibility = 'hidden';
}, 200);
};
PopImgStatic.prototype.init = function () {
var node = document.createElement('img');
node.id = 'miniblogImgPop';
document.body.appendChild(node);
this.img = node;
Mask.init();
};
PopImgStatic.prototype.move = function (e) {
this.layoutImg(e); // 重新计算大图宽度与位置
if (!this.allowMove) {
return;
}
Mask.move(e);
// 根据 Mask 的位置算出大图的位置
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
this.img.style.top = (scrollTop - Mask.top * Mask.scale) + 14 + 'px';
};
return PopImgStatic;
}());
var MiniblogImgPopStatic = (function () {
function MiniblogImgPopStatic() {
}
MiniblogImgPopStatic.prototype.init = function () {
PopImg.init();
};
return MiniblogImgPopStatic;
}());
var imgReady = (function () {
var list = [], intervalId = null,
// 用来执行队列
tick = function () {
var i = 0;
for (; i < list.length; i++) {
list[i].end ? list.splice(i--, 1) : list[i]();
}
!list.length && stop();
},
// 停止所有定时器队列
stop = function () {
window.clearInterval(intervalId);
intervalId = null;
};
return function (url, ready, load, error) {
var onready, width, height, newWidth, newHeight, img = new Image();
img.src = url;
// 如果图片被缓存,则直接返回缓存数据
if (img.complete) {
ready.call(img);
load && load.call(img);
return;
}
width = img.width;
height = img.height;
// 加载错误后的事件
img.onerror = function () {
error && error.call(img);
onready.end = true;
img = img.onload = img.onerror = null;
};
// 图片尺寸就绪
onready = function () {
newWidth = img.width;
newHeight = img.height;
if (newWidth !== width || newHeight !== height ||
// 如果图片已经在其他地方加载可使用面积检测
newWidth * newHeight > 1024) {
ready.call(img);
onready.end = true;
}
};
onready();
// 完全加载完毕的事件
img.onload = function () {
// onload在定时器时间差范围内可能比onready快
// 这里进行检查并保证onready优先执行
!onready.end && onready();
load && load.call(img);
// IE gif动画会循环执行onload,置空onload即可
img = img.onload = img.onerror = null;
};
// 加入队列中定期执行
if (!onready.end) {
list.push(onready);
// 无论何时只允许出现一个定时器,减少浏览器性能损耗
if (intervalId === null)
intervalId = setInterval(tick, 40);
}
};
})();
// 增加自定义样式
GM_addStyle("#miniblogImgPop {" +
"border: 7px solid rgba(255,255,255,1);" +
"box-shadow: 0 1px 30px rgba(0, 0, 0, 0.75), 0 0 40px rgba(0, 0, 0, 0.25) inset;" +
"z-index: 12345;" +
"opacity: 0;" +
"margin-top: 0;" +
"position: absolute;" +
"visibility: hidden;" +
"max-width: 500px;" +
"transition: opacity 0.2s ease-out 0s, margin-top 0.2s ease-out 0s;}");
// 增加自定义样式
GM_addStyle(".miniblogImgPop-mask {" +
"background: rgb(0, 0, 0);" +
"z-index: 999;" +
"position: absolute;" +
"transition: opacity 0.4s ease-out 0;}");
var PopImg = new PopImgStatic();
var Mask = new MaskStatic();
var MiniblogImgPop = new MiniblogImgPopStatic();
MiniblogImgPop.init();
PopImg.getBigImgsrc = function (li) {
var img = li.querySelector("img");
return img.getAttribute("bpic");
};
})();