// ==UserScript==
// @name 内容展开显示
// @namespace hzhbest
// @include *://*/*
// @description 展开鼠标下方的内容。
// @version 0.2
// @run-at document-end
// @license GNU GPLv3
// ==/UserScript==
(function () {
'use strict';
var videotimeout, popuptimeout, mvouttimeout;
var popuptime, mvouttime, clstime;
var curelem;
var topbox, expbox, closebtn;
var firstopen, vsrc, mt = "";
var padding = 3;
let css = `
.expand_box{display: none; position: absolute; max-height: 98%; max-width: 95%; height: auto; overflow-y: auto; scrollbar-width: thin; background: #ececec; border: 1px solid #a8a8a8; box-shadow: 0 0 5px #222; z-index: 10000; padding: ${padding}px;}
.expand_box.shown{display: block !important;}
.expand_box_clb{opacity: 0.05; position: absolute; top: 0; right: 0; font: Arial 16px; height: 18px; line-height:16px; border: 1px solid #737373; background: #f4f4f4;}
.expand_box_clb:hover{opacity: 1;}
`;
// 设置选项 ===
popuptimeout = 0.5; // 鼠标悬停弹出延时(秒)
mvouttimeout = 1; // 鼠标移出关闭延时(秒)
//videotimeout = 3; // 视频播放完后自动关闭延时(秒);钉住时不关闭
// 设置选项 ||=
document.body.addEventListener('mouseover', texpand, false);
addCSS(css);
topbox = creaElemIn('div', document.body);
topbox.className = 'expand_box';
closebtn = creaElemIn('div', topbox);
closebtn.className = 'expand_box_clb';
closebtn.innerHTML = 'X';
expbox = creaElemIn('div', topbox);
firstopen = false;
topbox.addEventListener('mouseleave', (event) => {
console.log("41mouseleave:", event.target);
firstopen = false;
mvouttime = setTimeout(() => {
if (!firstopen) reset();
}, mvouttimeout * 1000);
}, false);
topbox.addEventListener('mousemove', () => {
clearTimeout(mvouttime);
}, false);
closebtn.addEventListener('click', reset, false);
function texpand(event) {
if (!event.shiftKey) {
return;
}
let tnode = event.target;
if (tnode !== curelem) {
clearTimeout(popuptime);
}
if (!tnode.textContent && !tnode.src && !window.getComputedStyle(tnode).backgroundImage) {
return;
} console.log(tnode.nodeName, tnode);
if (!!tnode.textContent && tnode.nodeName == "A") {
var tnodestyle = window.getComputedStyle(tnode);
var fontsize = Number(tnodestyle.fontSize.replace('px', ''));
var linehght = Number(tnodestyle.lineHeight.replace('px', ''));
var pos = getTrueSize(tnode);
var lineChrCnt = Math.floor(pos.w / fontsize);
var lineCnt = Math.ceil(tnode.textContent.length / lineChrCnt);
if (pos.h < linehght * lineCnt) {
pos.h = linehght * lineCnt;
popuptime = setTimeout(() => {
expandtext(tnode, pos);
}, popuptimeout * 1000);
}
} else if (window.getComputedStyle(tnode).overflow !== "visible") {
var pos = getTrueSize(tnode);
popuptime = setTimeout(() => {
expandtext(tnode, pos);
}, popuptimeout * 1000);
}
/* if (tnode.nodeName == 'DIV' && tnode.className.indexOf('detail_wbtext_') == 0) {
btnexpand = tnode.querySelector('span.expand');
} else if (tnode.nodeName == 'P' && tnode.className == 'txt') {
btnexpand = tnode.querySelector('a[action-type="fl_unfold"]');
} else if (true || !/weibo\.com\/\d{10}\/[a-z0-9A-Z]{9}\??/.test(location.href)) {
var tvnode = getVideoBox(tnode, event);
//console.log('tvnode159: ', tvnode);
if (!!tvnode) {
popuptime = setTimeout(() => {
expandvideo(tvnode, event);
}, popuptimeout * 1000);
//console.log("167:", exptime, tvnode);
} else {
//console.log("181c:", exptime);
clearTimeout(popuptime);
}
} */
curelem = tnode;
}
function reset() {
topbox.classList.remove('shown');
}
function expandtext(tnode, posiz) {
firstopen = true;
expbox.innerHTML = tnode.innerHTML;
var tnodestyle = window.getComputedStyle(tnode);
var fontsize = Number(tnodestyle.fontSize.replace('px', ''));
var linehigh = Number(tnodestyle.lineHeight.replace('px', ''));
var wh = window.innerHeight;
var ww = window.innerWidth;
var etop = Math.max(posiz.t - padding, wh * 0.02);
var eheight = Math.min(wh * 0.94 - etop, posiz.h);
var ewidth = posiz.w;
var eleft = Math.max(ww * 0.02, Math.min(ww * 0.98 - posiz.w, posiz.l)) - padding;
topbox.classList.add('shown');
expbox.style = `line-height: ${linehigh}px; font-size: ${fontsize}px;`;
topbox.style = `height: ${eheight}px; width: ${ewidth}px; top: ${etop + window.scrollY}px; left: ${eleft}px; `;
}
/* function getVideoBox(elem, event) {
var velem, telem;
if (!!elem) {
if (elem.nodeName == 'VIDEO') {
velem = elem;
} else {
telem = elem.parentNode.querySelector('video');
if (!!telem && isCursorInElem(telem, event)) {
velem = telem;
}
}
if (!!velem && velem.parentNode.nodename !== 'a' && velem.parentNode.id !== "__wb_fbox") {
return velem;
}
}
return false;
} */
/* function expandvideo(vnode, event) {
//快捷展开动图
if (vsrc == vnode.src) {
return;
}
clearTimeout(clstime);
fbox.src = vnode.src;
vsrc = fbox.src;
fbox.controls = true;
bbox.style.display = "block";
// let mx = event.screenX, my = event.screenY;
// mx -= 50;
// my = 10; //Math.min(my - 50, window.innerHeight - fbox.offsetHeight - 50);console.log('fboxh2: ', fbox.offsetHeight);
bbox.style.top = 40 + "px";
bbox.style.right = 50 + "px";
vnode.addEventListener('mouseleave', (event) => {
//console.log("222c:", exptime);
clearTimeout(popuptime);
}, false);
} */
function creaElemIn(tagname, destin) { //在 destin 内末尾创建元素 tagname
let theElem = destin.appendChild(document.createElement(tagname));
return theElem;
}
function addCSS(css, cssid) {
let stylenode = creaElemIn('style', document.getElementsByTagName('head')[0]);
stylenode.textContent = css;
stylenode.type = 'text/css';
stylenode.id = cssid || '';
}
function isCursorInElem(elem, event) {
var x = Number(event.clientX) // 鼠标相对屏幕横坐标
var y = Number(event.clientY) // 鼠标相对屏幕纵坐标
var elemLeft = Number(elem.getBoundingClientRect().left) // obj相对屏幕的横坐标
var elemRight = Number(
elem.getBoundingClientRect().left + elem.clientWidth
) // obj相对屏幕的横坐标+width
var elemTop = Number(elem.getBoundingClientRect().top) // obj相对屏幕的纵坐标
var elemBottom = Number(
elem.getBoundingClientRect().top + elem.clientHeight
) // obj相对屏幕的纵坐标+height
return (x > elemLeft && x < elemRight && y > elemTop && y < elemBottom);
}
function getTrueSize(elem, posiz) {
if (!posiz) {
var p = elem.getBoundingClientRect();
posiz = {
w: p.width,
h: p.height,
t: p.top,
l: p.left
};
}
var pp = elem.parentNode.getBoundingClientRect();
if (pp.width >= posiz.w && pp.height >= posiz.h && pp.top <= posiz.t && pp.left <= posiz.l) {
return posiz;
} else {
return getTrueSize(elem.parentNode, {
w: Math.min(posiz.w, pp.width),
h: Math.min(posiz.h, pp.height),
t: Math.max(posiz.t, pp.top),
l: Math.max(posiz.l, pp.left)
});
}
}
})();