Greasy Fork is available in English.
Shows translations of tags on Pixiv and prompts for untranslated tags.
当前为
// ==UserScript==
// @name Pixiv Tag Translation/Replacement
// @description Shows translations of tags on Pixiv and prompts for untranslated tags.
// @namespace http://scripts.chris.charabaruk.com/pixiv.net/~tag-translation
// @author coldacid
// @include http://www.pixiv.net/
// @include http://www.pixiv.net/*
// @include http://pixiv.net/
// @include http://pixiv.net/*
// @include https://www.pixiv.net/
// @include https://www.pixiv.net/*
// @include https://pixiv.net/
// @include https://pixiv.net/*
// @version 1
// @grant none
// ==/UserScript==
var TagsCollection;
{
const USER_DATA_KEY = 'com.charabaruk.chris.pixiv.net.tag-translation';
let version = 1;
let map = null;
let loadMap = function () {
var userData = window.localStorage[USER_DATA_KEY];
if (userData) {
userData = JSON.parse(userData);
} else {
userData = {version: 1};
}
version = userData.version || 1;
var tags = userData.tags || {
"R-18": null,
"3D": null
};
tags[Symbol.iterator] = function* () { for (var tag in this) yield [tag, this[tag]]; }
map = new Map(tags);
}
let saveMap = function () {
var userData = {version: version, tags: {}};
for (var [k, v] of map) { userData.tags[k] = v; }
window.localStorage[USER_DATA_KEY] = JSON.stringify(userData);
}
TagsCollection = function TagsCollection () {
loadMap();
}
Object.defineProperty(TagsCollection.prototype, 'version', {value: version});
TagsCollection.prototype.has = function (tag) { return map.has(tag); }
TagsCollection.prototype.get = function (tag) { return map.get(tag) || tag; }
TagsCollection.prototype.set = function (tag, translation) {
if (translation === undefined) {
if (tag.entries) {
for (var [key, value] of tag.entries()) {
map.set(key, value);
}
} else if (tag instanceof Object) {
for (var key of Object.getOwnPropertyNames(tag)) {
map.set(key, tag[key]);
}
} else {
throw new Error('missing translation');
}
} else {
map.set(tag, translation);
}
saveMap();
}
}
function setTagText($element, tag) {
var originalTag = $element.text(),
newText = `${tag} (${originalTag})`;
if ($element[0].nodeType == Node.TEXT_NODE) {
$element[0].textContent = newText;
} else {
$element.text(newText);
}
}
function GM_main ($) {
var tags = new TagsCollection();
var untranslated = new Map();
// content page regular tags, home page featured tags, home page favorite tags
$('li.tag > a.text, div.tag-name, section.favorite-tag > ul.favorite-tags > li > a')
.contents()
.filter((i, n) => n.nodeType == Node.TEXT_NODE) // only get the text nodes within the selected elements
.each((idx, el) => {
var $el = $(el),
tag = $el.text();
if (/^[\x20-\x7e]*$/.test(tag)) {
console.log(`"${tag}" only uses ASCII printable characters, skipping`);
return;
}
if (tags.has(tag)) {
setTagText($el, tags.get(tag));
} else {
let elList = untranslated.has(tag) ? untranslated.get(tag) : [];
elList.push($el);
untranslated.set(tag, elList);
}
});
if (untranslated.size > 0) {
var taglist = Array.from(untranslated.keys()).join(', ');
if (window.confirm(`There are ${untranslated.size} untranslated tags. Want to translate?\n\nTags: ${taglist}`)) {
var translations = new Map();
for (var [tag, $els] of untranslated.entries()) {
var translated = window.prompt(`Translation for: ${tag}\n\nLeave empty to cancel translating`, tag);
if (!translated) { break; }
// only save if the translation is different from the original tag
if (tag !== translated) {
translations.set(tag, translated);
$els.forEach($el => setTagText($el, translated));
}
}
tags.set(translations);
}
}
}
if (typeof jQuery === 'function') {
console.log(`Using local jQuery, version ${jQuery.fn.jquery}`);
GM_main(jQuery);
} else {
console.log('Loading jQuery from Google CDN');
add_jQuery(GM_main, '1.11.1');
}
function add_jQuery(callbackFn, jqVersion) {
jqVersion = jqVersion || "1.11.1";
var D = document,
targ = D.getElementsByTagName('head')[0] || D.body || D.documentElement,
scriptNode = D.createElement('script');
scriptNode.src = `//ajax.googleapis.com/ajax/libs/jquery/${jqVersion}/jquery.min.js`;
scriptNode.addEventListener('load', function () {
var scriptNode = D.createElement('script');
scriptNode.textContent =
'var gm_jQuery = jquery.noConflict(true);\n'
+ '(' + callbackFn.toString() + ')(gm_jQuery);';
targ.appendChild(scriptNode);
}, false);
targ.appendChild(scriptNode);
}