pixivイラストページ改善

pixivイラストページのタグに作者マーカーと百科事典アイコン、ユーザー名の列に作品タグを復活させます

目前为 2018-06-20 提交的版本。查看 最新版本

// ==UserScript==
// @name        pixivイラストページ改善
// @description pixivイラストページのタグに作者マーカーと百科事典アイコン、ユーザー名の列に作品タグを復活させます
// @namespace   Aime
// @match       https://www.pixiv.net/member_illust.php*
// @version     1.0.0
// @grant       none
// @run-at      document-idle
// @noframes
// ==/UserScript==
(() => {
"use strict";
const pixivService = {
	enablePixpediaIcon	: true,		// 百科事典アイコンを付けるか?
	enableTagCloud		: true,		// 作品タグを表示するか?

	_existPixpedia	: {},
	_illustTags		: {},
	_currenAuthorId	: -1,
	_delayTimer		: null,

	run: function() {
		const root = document.getElementById("root");
		if (!root)
			return;

		const head = document.querySelector("head");
		const style = document.createElement("style");
		style.textContent = this._style;
		head.appendChild(style);

		new MutationObserver(records => {
			records.forEach(record => {
				record.addedNodes.forEach(node => {
					if (!node.querySelectorAll)
						return;
					// 増えたタグに百科事典アイコンを付ける
					const tags = node.querySelectorAll("a.gtm-new-work-tag-event-click:not([pixpedia]");
					if (tags.length) {
						if (this.enablePixpediaIcon)
							tags.forEach(node => this.insertPixpedia(node));
						this.authorTags();
					}
					// タグが減ったか変わらない場合は画像が変わったかで判断
					// イラスト:img._2r_DywD, うごイラ:div._3QPzwxP, 閲覧注意:div._27qPnrS
					if (node.classList.contains("_2r_DywD") || node.classList.contains("_3QPzwxP") || node.classList.contains("_27qPnrS")) {
						this.stopDelayTimer();
						this._delayTimer = setTimeout(this.illustChanged.bind(this), 1000);
					}

				});
			});
		}).observe(root, { childList: true, subtree: true });
	},

	stopDelayTimer: function() {
		if (this._delayTimer) {
			clearTimeout(this._delayTimer);
			this._delayTimer = null;
		}
	},
	illustChanged: function() {
		this.stopDelayTimer();
		this.authorTags();
	},

	insertPixpedia: async function(node) {
		if (node.hasAttribute("pixpedia"))
			return;
		node.setAttribute("pixpedia", "true");
		node.addEventListener("mouseover", this, true);
		try {
			const eTag = encodeURIComponent(node.textContent.trim());
			if (!(eTag in this._existPixpedia))
				this._existPixpedia[eTag] = !!await this.fetchJSON("https://www.pixiv.net/ajax/tag/" + eTag + "/info");
			const a = document.createElement("a");
			a.className = "pixpedia-icon" + (this._existPixpedia[eTag]? "": " pixpedia-icon-no-item");
			a.href = "https://dic.pixiv.net/a/" + eTag;
			node.parentElement.appendChild(a);
		} catch (e) {
			console.error(e);
		}
	},
	handleEvent: function(event) {
		event.stopPropagation();
	},

	authorTags: async function() {
		const match = /illust_id=(\d+)/.exec(location.href);
		if (!match)
			return;
		const illustId = match[1];
		let authorId;
		try {
			if (!(illustId in this._illustTags))
				this._illustTags[illustId] = await this.fetchJSON("https://www.pixiv.net/ajax/tags/illust/" + illustId);
			const tagData = this._illustTags[illustId];
			if (!tagData)
				return;
			authorId = tagData.authorId;

			document.querySelectorAll("li._1tTPwGC").forEach(elem => {
				let isOwn = false;
				const a = elem.querySelector("a.gtm-new-work-tag-event-click");
				if (a) {
					const tag = a.textContent.trim();
					const find = tagData.tags.find(t => t.tag == tag);
					isOwn = find && find.userId === authorId;
				}
				if (isOwn)
					elem.classList.add("author-tag-marker");
				else
					elem.classList.remove("author-tag-marker");
			});
		} catch (e) {
			console.error(e);
		}

		if (this.enableTagCloud && authorId && this._currenAuthorId !== authorId) {
			this._currenAuthorId = authorId;
			this.authorTagCloud(authorId);
		}
	},

	authorTagCloud: async function(authorId) {
		const aside = document.querySelector("aside._2e0p8Qb");
		if (!aside)
			return;

		let ok = false;
		try {
			// タグ一覧ページから引っ張ってきて差し込む
			const tagAllUrl = "https://www.pixiv.net/member_tag_all.php?id=" + authorId;
			const response	= await this.fetchSameOrigin(tagAllUrl);
			const text		= await response.text();
			const parser	= new DOMParser();
			const html		= parser.parseFromString(text, "text/html");
			const tagCloud	= html.querySelector("ul.tagCloud");
			if (tagCloud) {
				let container = document.getElementById("author-tags");
				if (!container) {
					container = document.createElement("div");
					container.id = "author-tags";
					container.className = "_3mXmB-F";
					aside.insertBefore(container, document.querySelector("._3M6FtEB"));
				}
				container.innerHTML = `<h2><a href="${tagAllUrl}">作品タグ</a></h2>`;
				container.appendChild(tagCloud);
				ok = true;
			}
		} catch(e) {
			console.error(e);
		}
		if (!ok) {
			const container = document.getElementById("author-tags");
			if (container)
				container.parentElement.removeChild(container);
		}
	},

	fetchSameOrigin: function (url) {
		return fetch(url, { mode: "same-origin", credentials: "same-origin" });
	},
	fetchJSON: async function(url) {
		const response = await this.fetchSameOrigin(url);
		const data = await response.json();
		if (data.error)
			throw new Error(data.message);
		return data.body;
	},

	_style: `
/* 百科事典 */
.pixpedia-icon {
	display: inline-block;
	margin-left: 2px;
	width: 15px;
	height: 14px;
	vertical-align: -2px;
	text-decoration: none;
	background: url(https://s.pximg.net/www/images/inline/pixpedia.png) no-repeat;
}
.pixpedia-icon-no-item {
	background: url(https://s.pximg.net/www/images/inline/pixpedia-no-item.png) no-repeat;
}
.pixpedia-icon::before {
	display: none;
}

/* 作者タグ */
.author-tag-marker::before {
	content: "*" !important;
	color: #E66;
}
/* "#"を消す */
.qE_sxIX::before {
	display: none !important;
}

/* tag cloud */
#author-tags._3mXmB-F {
	padding: 8px;
	background-color: #FFF;
}
#author-tags h2 {
	color: #333;
	font-size: 14px;
	margin: 0 0 8px;
}
#author-tags h2 a {
	color: inherit;
	text-decoration: none;
}
.tagCloud {
	font-size: 12px;
	line-height: 1.6;
	padding: 0;
	margin: 0;
	word-break: break-all;
}
.tagCloud li {
	display: inline;
	font-size: 12px;
	padding: 0px 2px;
	margin: 0px;
}
.tagCloud li a {
	color: inherit;
	text-decoration: none;
}
.tagCloud li.level1 {
	font-size: 20px;
	font-weight: bold;
}
.tagCloud li.level1 a {
	color: #3E5B71;
}
.tagCloud li.level2 {
	font-size: 18px;
	font-weight: bold;
}
.tagCloud li.level2 a {
	color: #3E5B71;
}
.tagCloud li.level3 {
	font-size: 17px;
	font-weight: bold;
}
.tagCloud li.level3 a {
	color: #587C97;
}
.tagCloud li.level4 {
	font-size: 16px;
	font-weight: bold;
}
.tagCloud li.level4 a {
	color: #587C97;
}
.tagCloud li.level5 {
	font-size: 14px;
	font-weight: bold;
}
.tagCloud li.level5 a {
	color: #587C97;
}
.tagCloud li.level6 a {
	color: #5E9ECE;
}
.tagCloud li a:hover {
	background-color: #3E5B71;
	color: #FFF;
}
.tagCloud li .cnt {
	font-size: 11px;
	font-weight: normal;
	color: #999999;
}
`
};

pixivService.run();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址