// ==UserScript==
// @name 网页TDKI等信息内容展示
// @namespace https://github.com/techstay/myscripts
// @version 0.1
// @description 本脚本用于展示网页的 标题、链接、描述、关键字、图标、预览图等信息 并可支持双击选中复制 ,便于快捷使用网页信息,免于控制台 HTML结构内查找
// @author xynagisa
// @match **://*/*
// @grant GM_addStyle
// ==/UserScript==
(function () {
"use strict";
var showIconsList = [];
var showImagesList = [];
var httpRegex = new RegExp(/http/);
window.onload = function () {
var script = document.createElement("script");
script.src = "https://cdn.bootcdn.net/ajax/libs/fetch/3.6.2/fetch.js";
script.setAttribute("type", "text/javascript");
console.log("pre F");
script.onload = function () {
console.log("加载完毕");
loadInfo(true);
};
script.onerror = function (e) {
console.log("err", e);
loadInfo(false);
};
function loadInfo(hasLoadFetch) {
// ~~ 获取网页的 Icon
function getIcons() {
// 方式一 直接获取link属性 截取url。 shortcut icon 是过时的写法
var textArr = [
"shortcut icon",
"icon",
"alternate icon",
"mask-icon",
"apple-touch-icon",
];
textArr.forEach(function (item) {
var checkQuery = document.querySelector(`link[rel="${item}"]`);
if (!checkQuery) {
return;
}
var checkHref = checkQuery.href;
if (checkHref) {
showIconsList.push(checkHref);
}
});
// 方式二 PWA 应用可以获取根域名的manifest 有链接的返回链接 没有的直接进行拼接
// 只有 fetch 引入成功时才可以使用
if (hasLoadFetch) {
var feil = document.querySelector('link[rel="manifest"]')?.href;
console.log("%c查找mainfest信息", "color:orange", feil);
if (feil) {
fetch(feil)
.then(function (res) {
return res.json();
})
.then((data) => {
if (!data.icons || !data.icons.length) return;
data.icons.forEach(function (iconItem, iconIndex) {
var url = httpRegex.test(iconItem.src)
? iconItem.src
: document.location.origin + "/" + iconItem.src;
showIconsList.push(url);
});
console.log(
"%c预存-mainfest.json数据 ",
"color:blue",
data,
showIconsList
);
setTimeout(function () {
refreshIconImg();
}, 2000);
});
}
}
// 方式三 未设置 link rel=type,而是直接放到网站根目录下,浏览器会 直接获取 favicon.ico
var img = new Image();
img.src = document.location.origin + "/favicon.ico";
img.onload = function () {
showIconsList.push(img.src);
console.log("获取到favcion", img.src, showIconsList);
setTimeout(function () {
refreshIconImg();
}, 2000);
};
img.onerror = function () {
console.log("该链接无效");
};
}
// 获取网页描述
function getDesc() {
var textArrDes = ["description", "twitter:description"];
var richArrs = ["og:description", "twitter:description"];
var metas = document.getElementsByTagName("meta");
var subMetas = [];
for (var i = 0; i < metas.length; i++) {
if (textArrDes.includes(metas[i].getAttribute("name"))) {
subMetas.push(metas[i].getAttribute("content"));
}
if (richArrs.includes(metas[i].getAttribute("property"))) {
subMetas.push(metas[i].getAttribute("content"));
}
}
console.log("描述List", subMetas);
return subMetas;
}
// ~~ 获取网页预览图
function getImgs() {
var textArrDes = ["image", "twitter:image", "twitter:image:src"];
var richArrs = ["og:image"];
var catchProperty = ["name", "property", "itemprop"];
var metas = document.getElementsByTagName("meta");
var subImgs = [];
// 摆烂 - 没有的不会匹配到 - 就这样吧
for (var i = 0; i < metas.length; i++) {
catchProperty.forEach(function (y) {
if (textArrDes.includes(metas[i].getAttribute(y))) {
subImgs.push(metas[i].getAttribute("content"));
}
if (richArrs.includes(metas[i].getAttribute(y))) {
subImgs.push(metas[i].getAttribute("content"));
}
});
}
console.log("预览图List", subImgs);
showImagesList = subImgs;
}
// 获取网页title
var titles = document.getElementsByTagName("title");
var pageTitle = titles[0].innerText;
// 获取网页链接
var linkUrl = window.location.href;
// descipiton
var desc = getDesc()[0];
// 获取网页关键词
var hasKeys = document.querySelector('meta[name="keywords"]');
var keywords = hasKeys ? hasKeys.content : "";
// 获取网页icon
getIcons();
// 获取网页预览图
getImgs();
console.log("%c获取网页title", "color:skyblue", pageTitle);
console.log("%c获取网页description", "color:skyblue", desc);
console.log("%c获取网页关键词", "color:skyblue", keywords);
console.log("%c获取网页图标", "color:green", showIconsList);
console.log("%c获取网页预览图", "color:green", showImagesList);
addContent();
// 获取之后 添加 遮罩面板到项目内部
function addContent() {
var div = document.createElement("div");
div.id = "xy-auto-webs-panel";
div.className = "xy-auto-webs-panel xy-none";
// 添加文字
var topTags = [
{ name: "标题", key: "title", content: pageTitle },
{ name: "链接", key: "link", content: linkUrl },
{ name: "描述", key: "description", content: desc },
{ name: "关键词", key: "keywords", content: keywords },
];
topTags.forEach(function (item) {
var itemDiv = document.createElement("div");
itemDiv.name = itemDiv.key;
itemDiv.className = "xy-auto-webs-panel-item";
var p = document.createElement("div");
p.innerText = item.name;
p.className = "xy-auto-webs-panel-item-title";
var content = document.createElement("div");
content.innerText = item.content || "";
content.className = "xy-auto-webs-panel-item-content xy-select-all";
content.onmousedown = () => {
navigator.clipboard.writeText(item.content);
};
itemDiv.appendChild(p);
itemDiv.appendChild(content);
div.appendChild(itemDiv);
});
// 添加 图标
var imgTags = [
{ name: "图标", key: "icon", content: showIconsList },
{ name: "预览图", key: "image", content: showImagesList },
];
imgTags.forEach(function (item, index) {
var itemDiv = document.createElement("div");
itemDiv.name = itemDiv.key;
itemDiv.className = "xy-auto-webs-panel-item";
var p = document.createElement("div");
p.innerText = item.name;
p.className = "xy-auto-webs-panel-item-title";
var content = document.createElement("div");
content.className = "xy-auto-webs-panel-item-content";
content.id = `xy-auto-webs-panel-item-content-${index + 1}`;
// content 下 添加自定义数量的节点
item.content = [...new Set(item.content)];
item.content.forEach(function (imgItem, imgIndex) {
var imgOuter = document.createElement("div");
imgOuter.className = "xy-auto-webs-panel-item-img-outer";
var imgTitle = document.createElement("div");
imgTitle.className = "xy-auto-webs-panel-item-img-url";
if (!httpRegex.test(imgItem)) {
imgTitle.className = "xy-auto-webs-panel-item-img-url xy-ells-2";
}
imgTitle.innerText = imgItem;
imgTitle.onmousedown = () => {
navigator.clipboard.writeText(imgItem);
};
var img = document.createElement("img");
img.className = "xy-auto-webs-panel-item-img";
img.alt = "(无图片)";
img.src = imgItem || "";
imgOuter.appendChild(imgTitle);
imgOuter.appendChild(img);
content.appendChild(imgOuter);
});
itemDiv.appendChild(p);
itemDiv.appendChild(content);
div.appendChild(itemDiv);
});
// 框外跟随滚动
document.body.appendChild(div);
}
}
document.body.appendChild(script);
// 添加按钮 控制 框的展示 与 隐藏
var canXyPanelShow = false;
var button = document.createElement("div");
button.className = "xy-auto-webs-panel-btn";
button.innerText = "网页信息 开/关";
button.onmousedown = function () {
var webSiteInfoPanel = document.getElementById("xy-auto-webs-panel");
if (!webSiteInfoPanel) return;
if (canXyPanelShow) {
canXyPanelShow = false;
// 或者使用 webSiteInfoPanel.setAttribute("class", xxx)
webSiteInfoPanel.className = "xy-auto-webs-panel xy-none";
} else {
canXyPanelShow = true;
webSiteInfoPanel.className = "xy-auto-webs-panel xy-show";
}
};
document.body.appendChild(button);
};
// 更新展示 Icon
// 清空原有节点 - 重新
// 或者 内部添加新增内容
function refreshIconImg() {
var iconContent = document.getElementById(
"xy-auto-webs-panel-item-content-1"
);
if (!iconContent) {
setTimeout(
function () {
refreshIconImg();
},
300
);
return;
}
iconContent.innerHTML = "";
showIconsList = [...new Set(showIconsList)];
showIconsList.forEach(function (imgItem, imgIndex) {
var imgOuter = document.createElement("div");
imgOuter.className = "xy-auto-webs-panel-item-img-outer";
var imgTitle = document.createElement("div");
imgTitle.className = "xy-auto-webs-panel-item-img-url";
if (!httpRegex.test(imgItem)) {
imgTitle.className = "xy-auto-webs-panel-item-img-url xy-ells-2";
}
imgTitle.innerText = imgItem;
imgTitle.onmousedown = () => {
navigator.clipboard.writeText(imgItem);
};
var img = document.createElement("img");
img.className = "xy-auto-webs-panel-item-img";
img.alt = "(无图片)";
img.src = imgItem || "";
imgOuter.appendChild(imgTitle);
imgOuter.appendChild(img);
iconContent.appendChild(imgOuter);
});
}
// 插入样式
var injectStyle = `
.xy-none {
display: none;
}
.xy-show {
display: block;
}
.xy-select-all{
user-select: all;
cursor: copy;
}
.xy-ells-2 {
/* todo : 双行省略 */
/* width: 160px; */
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.xy-auto-webs-panel-btn {
height: 40px;
width: 100px;
border-radius: 12px;
position: fixed;
top: 60px;
right: 20px;
color: white;
background: black;
font-weight: border;
z-index: 9999;
display: grid;
place-items: center;
cursor: pointer;
font-size: 12px;
user-select: none;
}
.xy-auto-webs-panel-btn:active {
box-shadow: inset 1px 1px 2px #babecc, inset -1px -2px 2px white;
}
/*.xy-auto-webs-panel-btn:hover {*/
/* box-shadow: 2px 2px 5px green,-2px -2px 5px green;*/
/*}*/
.xy-auto-webs-panel {
height: 400px;
width: 300px;
background: black;
overflow: scroll;
right: 10px;
top: 110px;
position: fixed;
/*color:yellow;*/
z-index: 9999;
padding: 10px;
/*opacity: 0.7;*/
font-size: 12px;
border-radius: 8px;
}
.xy-auto-webs-panel::-webkit-scrollbar {
width: 0 !important;
}
.xy-auto-webs-panel-item,
.xy-auto-webs-panel-item-0,
.xy-auto-webs-panel-item-1 {
display: flex;
margin: 5px 0;
}
.xy-auto-webs-panel-item-title {
width: 80px;
text-align: left;
font-weight: bolder;
font-size: 14px;
color: white;
user-select: none;
}
.xy-auto-webs-panel-item-content {
flex: 1;
word-spacing: 3px;
text-align: left;
flex-wrap: wrap;
color: skyblue;
/*word-break: break-all;*/
word-break: break-word;
line-height: 1.5;
}
.xy-auto-webs-panel-item-img-url {
margin-bottom: 10px;
user-select: all;
cursor: copy;
}
.xy-auto-webs-panel-item-img {
width: 80px;
height: 80px;
object-fit: contain;
user-select: none;
filter: none !important;
}
`;
GM_addStyle(injectStyle);
})();