Extract JSON-/string-style info from Pixiv/Twitter/Booru image pages.
// ==UserScript==
// @name Image Webinfo
// @name:zh-CN 图片网页信息提取
// @version 1.6.0
// @description Extract JSON-/string-style info from Pixiv/Twitter/Booru image pages.
// @description:zh-CN 将 Pixiv/Twitter/Booru 图片页面中的信息以 JSON 或字符串形式导出。
// @author wklchris
// @match https://danbooru.donmai.us/
// @match https://danbooru.donmai.us/posts*
// @match https://www.pixiv.net/artworks/*
// @match https://x.com/*/status/*
// @grant none
// @license MIT
// @namespace https://greasyfork.org/users/672201
// ==/UserScript==
(function() {
'use strict';
// --- Customization ---
// Specify returned keys when copy string
const pixiv_str_keys = [
// 'artist',
// 'illust_id',
'artist_id',
'post_date',
'post_title'
];
const booru_str_keys = [
//'artists',
//'copyrights',
'characters',
//'general',
//'booru_id',
//'rating_level'
];
const sitePostPatterns = [
{ code: "AC", regex: new RegExp("^(?:https://)?arca\.live/b/([^/]+)/([0-9]+)$"), groupNames: ["forum_name", "post_id"] },
{ code: "AS", regex: new RegExp("^(?:https://)?(?:www\.)?artstation\.com/artwork/([^/]+)$"), groupNames: ["post_name"] },
{ code: "BL", regex: new RegExp("^(?:https://)?(?:www\.)?bilibili\.com/opus/([0-9]+)$"), groupNames: ["post_id"] },
{ code: "BS", regex: new RegExp("^(?:https://)?bsky\.app/profile/([^/]+)/post/([^/]+)$"), groupNames: ["user_name", "post_name"] },
{ code: "BT", regex: new RegExp("^(?:https://)?booth\.pm/en/items/([0-9]+)$"), groupNames: ["post_id"] },
{ code: "DB", regex: new RegExp("^(?:https://)?danbooru\.donmai\.us/posts/([0-9]+)$"), groupNames: ["post_id"] },
{ code: "DA", regex: new RegExp("^(?:https://)?(?:www\.)?deviantart\.com/([^/]+)/art/[^/]+-([0-9]+)$"), groupNames: ["user_name", "post_id"] },
{ code: "DL", regex: new RegExp("^(?:https://)?(?:www\.)?dlsite\.com/(?:[^/]+)/work/=/product_id/(?:[A-Z]+)([0-9]+)\.html$"), groupNames: ["post_id"] },
{ code: "FB", regex: new RegExp("^(?:https://)?(?:www\.)?facebook\.com/photo\?fbid=([0-9]+)$"), groupNames: ["post_id"] },
{ code: "PF", regex: new RegExp("^(?:https://)?([^/]+)\.fanbox\.cc/posts/([0-9]+)$"), groupNames: ["user_name", "post_id"] },
{ code: "FA", regex: new RegExp("^(?:https://)?fantia\.jp/posts/([0-9]+)$"), groupNames: ["post_id"] },
{ code: "FL", regex: new RegExp("^(?:https://)?(?:www\.)?flickr\.com/photos/(?:[^/]+)/([0-9]+)/?$"), groupNames: ["post_id"] },
{ code: "GB", regex: new RegExp("^(?:https://)?gelbooru\.com/index\.php\?page=post&s=view&id=([0-9]+)$"), groupNames: ["post_id"] },
{ code: "GR", regex: new RegExp("^(?:https://)?([^/]+)\.gumroad\.com/l/([^/]+)$"), groupNames: ["user_name", "post_name"] },
{ code: "HI", regex: new RegExp("^(?:https://)?hitomi\.la/(?:[^/]+)/(?:[^/]+-)?([0-9]+)(?:\.html)?(?:#\d+)?$"), groupNames: ["post_id"] },
{ code: "IG", regex: new RegExp("^(?:https://)?(?:www\.)?instagram\.com/p/([^/]+)/$"), groupNames: ["post_name"] },
{ code: "JR", regex: new RegExp("^(?:https://)?joyreactor\.com/post/([0-9]+)$"), groupNames: ["post_id"] },
{ code: "KC", regex: new RegExp("^(?:https://)?konachan\.com/post/show/([0-9]+)$"), groupNames: ["post_id"] },
{ code: "KB", regex: new RegExp("^(?:https://)?(?:www\.)?kurobbs\.com/([^/]+)/post/([0-9]+)$"), groupNames: ["forum_name", "post_id"] },
{ code: "KF", regex: new RegExp("^(?:https://)?ko-fi\.com/s/([^/]+)$"), groupNames: ["post_name"] },
{ code: "LT", regex: new RegExp("^(?:https://)?([^/]+)\.lofter\.com/post/([0-9]+)$"), groupNames: ["user_name", "post_id"] },
{ code: "MB", regex: new RegExp("^(?:https://)?(?:www\.)?melonbooks\.co\.jp/detail/detail\.php\?product_id=([0-9]+)$"), groupNames: ["post_id"] },
{ code: "NB", regex: new RegExp("^(?:https://)?blog\.naver\.com/([^/]+)/([0-9]+)$"), groupNames: ["user_name", "post_id"] },
{ code: "PT", regex: new RegExp("^(?:https://)?(?:www\.)?patreon\.com/([^/]+)/posts/[^/]+-([0-9]+)$"), groupNames: ["user_name", "post_id"] },
{ code: "PI", regex: new RegExp("^(?:https://)?(?:www\.)?pinterest\.com/pin/([0-9]+)/?$"), groupNames: ["post_id"] },
{ code: "PX", regex: new RegExp("^(?:https://)?(?:www\.)?pixiv\.net/artworks/([0-9]+)$"), groupNames: ["post_id"] },
{ code: "RD", regex: new RegExp("^(?:https://)?(?:www\.)?reddit\.com/r/([^/]+)/comments/([^/]+)/(?:[^/]+)/?$"), groupNames: ["forum_name", "post_name"] },
{ code: "SB", regex: new RegExp("^(?:https://)?safebooru\.org/index\.php\?page=post&s=view&id=([0-9]+)$"), groupNames: ["post_id"] },
{ code: "SK", regex: new RegExp("^(?:https://)?skeb\.jp/@([^/]+)/works/([0-9]+)$"), groupNames: ["user_name", "post_id"] },
{ code: "TT", regex: new RegExp("^(?:https://)?twitter\.com/([^/]+)/status/([0-9]+)$"), groupNames: ["user_name", "post_id"] },
{ code: "TT", regex: new RegExp("^(?:https://)?x\.com/([^/]+)/status/([0-9]+)$"), groupNames: ["user_name", "post_id"] },
{ code: "WB", regex: new RegExp("^(?:https://)?(?:www\.)?weibo\.com/([0-9]+)/([^/]+)$"), groupNames: ["user_id", "post_name"] }
];
// --- Main ---
let artwork_data = {};
let export_json_btn = document.createElement("button");
export_json_btn.innerHTML = "Export WebInfo as JSON";
let export_str_btn = document.createElement("button");
export_str_btn.innerHTML = "Export WebInfo as String";
// General functions
function logMessage(msg) {
console.log("[ImageWebInfo] " + msg);
}
let popMessage = 'Image webinfo exported to clipboard.';
function copyToClipboard(s) {
try {
navigator.clipboard.writeText(s);
} catch (err) {
popMessage = 'Image webinfo export failed.';
logMessage(popMessage);
}
}
function getSitePostData(url) {
for (const { code, regex, groupNames } of sitePostPatterns) {
const match = regex.exec(url);
if (!match) { continue; }
const result = { code };
groupNames.forEach((name, i) => {
result[name] = match[i + 1];
});
return result;
}
return null;
}
function getSitePostIdFallback(url) {
const _site_url = url || '';
return _site_url.substring(_site_url.lastIndexOf('/') + 1);
}
function stripQueryString(s) {
const qm_index = s.indexOf('?');
return qm_index >= 0 ? s.substring(0, qm_index) : s;
}
function getFilenameForCopy(display_filename) {
return display_filename.replace(/^\(bad\)\s*|\.[^/.]+$/g, '').trim();
}
function queryTagNames(container, selector, sep = " ") {
return Array.from(container.querySelectorAll(selector))
.map(x => (x.dataset.tagName || x.innerText || x.textContent || '').trim().replace(/ /g, "_"))
.join(sep);
}
function copyBooruInfo(data, as_JSON = true) {
let s = "";
if (as_JSON == true) {
s = JSON.stringify(data);
} else {
// If not, concatenate the field into a comma-sep string
s = booru_str_keys.map(key => `"${data[key].replaceAll(', ', '", "')}"`).join("\t");
}
copyToClipboard(s);
return data;
}
function attemptedQuerySelector(qs, callback) {
// querySelector may not find the element when the website loads slowly.
// Keep attempting until found or exceed the given maximum attempts.
var attempts = 0, max_attempts = 20;
var attemptCall = function() {
var elem = document.querySelector(qs);
if (elem) {
console.log(`Found querySelector '${qs}' in ${attempts} attempts`);
return callback(elem);
} else {
attempts++;
if (attempts >= max_attempts) {
console.warn(`Could not find: ${qs} within ${max_attempts} attempts`);
} else {
setTimeout(attemptCall, 4000*(attempts + 1)/max_attempts + 1000)
}
}
};
attemptCall();
}
async function downloadWithCustomName(url, filename) {
try {
const response = await fetch(url);
const blob = await response.blob();
const blobUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = blobUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setTimeout(() => URL.revokeObjectURL(blobUrl), 100);
} catch (error) {
console.error('Fail in downloading with customized name: ', error);
// Open the link directly when fail
window.open(url, '_blank');
}
}
// --- Pixiv posts ---
if (location.hostname.includes("pixiv")) {
function getPixivInfo(as_JSON=true) {
let data = {};
// Get user
let user_tag = document.querySelector('aside div[aria-haspopup="true"] > div > a');
data['artist'] = user_tag.childNodes[0].innerText
let split_user_url = user_tag.href.split('/');
data['artist_id'] = split_user_url[split_user_url.length - 1];
// Get post id
let split_url = location.href.split('/');
data['illust_id'] = split_url[split_url.length - 1];
// Get upload date
let timestr = document.getElementsByTagName('time')[0].innerText;
let time_seps = {'year': '年', 'month': '月', 'day': '日'};
let i_start = 0, i_end = -1, tmp_data = {};
for (const [key, sep] of Object.entries(time_seps)) {
i_start = i_end+1;
i_end = timestr.search(sep);
tmp_data[key] = timestr.substring(i_start, i_end);
}
data['post_date'] = `${tmp_data['year']}-${tmp_data['month'].padStart(2, 0)}-${tmp_data['day'].padStart(2, 0)}`;
// Get post title (if having a title)
let title_dom = document.querySelector('figcaption h1');
data['post_title'] = title_dom ? title_dom.innerText : '' ;
let s = "";
if (as_JSON == true) {
s = JSON.stringify(data)
} else {
s = pixiv_str_keys.map((x, i) => data[x]).join(",");
}
copyToClipboard(s);
return data;
}
// Add buttons & their click functions
let search_booru_btn = document.createElement("button");
search_booru_btn.innerHTML = "Search artist on Booru";
let search_booru_illust_btn = document.createElement("button");
search_booru_illust_btn.innerHTML = "Search illust on Booru";
attemptedQuerySelector('aside section button', (exist_dom) => {
exist_dom.parentNode.insertBefore(export_json_btn, exist_dom.nextSibling);
exist_dom.parentNode.insertBefore(export_str_btn, export_json_btn.nextSibling);
exist_dom.parentNode.insertBefore(search_booru_btn, export_str_btn.nextSibling);
exist_dom.parentNode.insertBefore(search_booru_illust_btn, search_booru_btn.nextSibling);
});
export_json_btn.onclick = function() {
artwork_data = getPixivInfo(true);
export_json_btn.style.background = 'lightgreen';
export_str_btn.style.removeProperty("background");
};
export_str_btn.onclick = function() {
artwork_data = getPixivInfo(false);
export_str_btn.style.background = 'lightgreen';
export_json_btn.style.removeProperty("background");
};
search_booru_btn.onclick = function() {
if (!('artist_id' in artwork_data)) {
artwork_data = getPixivInfo(false);
}
let _prefix = "https://danbooru.donmai.us/artists?commit=Search&search%5Border%5D=created_at&search%5Burl_matches%5D=https%3A%2F%2Fwww.pixiv.net%2Fusers%2F";
let _url = _prefix + artwork_data["artist_id"];
window.open(_url, "_blank");
};
search_booru_illust_btn.onclick = function() {
if (!('illust_id' in artwork_data)) {
artwork_data = getPixivInfo(false);
}
let illust_search_prefix = "https://danbooru.donmai.us/posts?tags=pixiv%3A";
let illust_search_url = illust_search_prefix + artwork_data["illust_id"];
window.open(illust_search_url, "_blank");
};
}
// --- Twitter/X Post ---
if (["twitter.com", "x.com"].includes(location.hostname)) {
let twitter_url_id = '';
function getTwitterInfo(as_JSON=true) {
let data = {};
// Get user
let user_tag = document.querySelector('article > div div[data-testid="User-Name"]');
data['artist'] = user_tag.childNodes[0].innerText;
// -- Twitter user only has username, doesn't have a user ID number.
// The matched id is only used for creating search buttons.
data['artist_id'] = '';
let split_user_url = user_tag.childNodes[1].querySelector('a').href.split('/');
twitter_url_id = split_user_url[split_user_url.length - 1];
// Get post id
data['illust_id'] = "T" + location.href.split('status/')[1].split('/')[0];
// Get upload date
data['post_date'] = document.getElementsByTagName('time')[0].dateTime.split('T')[0];
// Get post title (if having a title)
let tweet_nodes = document.querySelector('article div[data-testid="tweetText"]').querySelectorAll('span, img');
data['post_title'] = Array.from(tweet_nodes).map(
elem => elem.alt || elem.innerText.trim()).filter(d => d.length && d[0] != '#'
).join('').split('\n')[0];
let s = "";
if (as_JSON == true) {
s = JSON.stringify(data)
} else {
s = pixiv_str_keys.map((x, i) => data[x]).join("\t");
}
copyToClipboard(s);
return data;
}
// Add buttons & their click functions
let search_booru_btn = document.createElement("button");
search_booru_btn.innerHTML = "Search artist on Booru";
let search_booru_illust_btn = document.createElement("button");
search_booru_illust_btn.innerHTML = "Search illust on Booru";
attemptedQuerySelector('div[data-testid="User-Name"]', (exist_dom) => {
exist_dom.parentNode.insertBefore(export_json_btn, exist_dom.nextSibling);
exist_dom.parentNode.insertBefore(export_str_btn, export_json_btn.nextSibling);
exist_dom.parentNode.insertBefore(search_booru_btn, export_str_btn.nextSibling);
exist_dom.parentNode.insertBefore(search_booru_illust_btn, search_booru_btn.nextSibling);
});
export_json_btn.onclick = function() {
artwork_data = getTwitterInfo(true);
export_json_btn.style.background = 'lightgreen';
export_str_btn.style.removeProperty("background");
};
export_str_btn.onclick = function() {
artwork_data = getTwitterInfo(false);
export_str_btn.style.background = 'lightgreen';
export_json_btn.style.removeProperty("background");
};
search_booru_btn.onclick = function() {
if (!('artist_id' in artwork_data)) {
artwork_data = getTwitterInfo(false);
}
let _prefix = "https://danbooru.donmai.us/artists?commit=Search&search%5Border%5D=created_at&search%5Burl_matches%5D=https%3A%2F%2Fwww.twitter.com%2F";
let _url = _prefix + twitter_url_id;
window.open(_url, "_blank");
};
search_booru_illust_btn.onclick = function() {
if (!('illust_id' in artwork_data)) {
artwork_data = getTwitterInfo(false);
}
let illust_search_prefix = "https://danbooru.donmai.us/posts?tags=source%3A";
let illust_search_url = illust_search_prefix + encodeURIComponent(location.href.replace('x.com/','twitter.com/'));
window.open(illust_search_url, "_blank");
};
}
// --- Booru tooltips (homepage / search result pages) ---
function getBooruTooltipSourceUrl(root) {
const source_el = root.querySelector('a.post-tooltip-source');
if (!source_el) { return ''; }
const source_text = source_el.getAttribute('title') || source_el.getAttribute('href') || '';
if (!source_text || source_text == 'no source') { return ''; }
return source_text.replace(/^https?:\/\/(?:www\.)?/i, '');
}
function getBooruTooltipInfo(root) {
let data = {};
data["artists"] = queryTagNames(root, '.post-tooltip-body .tag-list a.tag-type-1');
data["copyrights"] = queryTagNames(root, '.post-tooltip-body .tag-list a.tag-type-3');
data["characters"] = queryTagNames(root, '.post-tooltip-body .tag-list a.tag-type-4');
data["general"] = queryTagNames(root, '.post-tooltip-body .tag-list a.tag-type-0');
data["meta"] = queryTagNames(root, '.post-tooltip-body .tag-list a.tag-type-5');
const post_votes_el = root.querySelector('.post-votes[data-id]');
data["booru_id"] = post_votes_el ? post_votes_el.dataset.id : '';
const time_el = root.querySelector('.post-tooltip-date time[datetime]');
data["booru_date"] = time_el ? time_el.getAttribute('datetime').split('T')[0] : '';
const score_el = root.querySelector('.post-score a');
data["booru_upvote"] = score_el ? score_el.textContent.trim() : '';
data["source_url"] = getBooruTooltipSourceUrl(root);
const rating_el = root.querySelector('a.post-tooltip-rating');
if (rating_el) {
const rating_match = /rating(?:%3A|:)([^&]+)/i.exec(rating_el.getAttribute('href') || '');
data["rating_level"] = rating_match ? decodeURIComponent(rating_match[1]) : rating_el.textContent.trim();
} else {
data["rating_level"] = '';
}
return data;
}
function getBooruTooltipFileExt(root) {
const dimensions_el = root.querySelector('.post-tooltip-dimensions');
if (!dimensions_el) { return ''; }
const ext_match = /(\.[a-z0-9]+)\s*,/i.exec(dimensions_el.textContent);
return ext_match ? ext_match[1] : '';
}
function getBooruTooltipFilenameSourceUrl(root) {
const source_el = root.querySelector('a.post-tooltip-source');
const source_url = source_el ? source_el.getAttribute('href') || '' : '';
return /^https?:\/\//i.test(source_url) ? source_url : '';
}
function buildBooruTooltipFilename(root) {
const source_url = getBooruTooltipFilenameSourceUrl(root);
const site_data = getSitePostData(source_url);
const file_prefix = site_data?.code || '#';
const site_id = site_data?.post_id || site_data?.post_name || getSitePostIdFallback(source_url);
const file_ext = getBooruTooltipFileExt(root);
return stripQueryString(file_prefix + site_id + "_p0" + file_ext);
}
function injectBooruTooltip(root) {
const info = getBooruTooltipInfo(root);
const filename = buildBooruTooltipFilename(root);
const meta_tags = info["meta"].split(/\s+/);
const display_filename = (meta_tags.includes('bad_id') || meta_tags.includes('bad id') ? '(bad) ' : '') + filename;
const tooltip_bar = document.createElement('div');
tooltip_bar.className = 'image-webinfo-tooltip';
tooltip_bar.style.display = 'flex';
tooltip_bar.style.alignItems = 'center';
tooltip_bar.style.flexWrap = 'wrap';
tooltip_bar.style.gap = '4px';
tooltip_bar.style.padding = '2px 8px';
tooltip_bar.style.fontSize = '10px';
const filename_span = document.createElement('span');
filename_span.className = 'image-webinfo-filename';
filename_span.style.flex = '1 1 200px';
filename_span.style.minWidth = '0';
filename_span.style.whiteSpace = 'normal';
filename_span.style.overflowWrap = 'anywhere';
filename_span.style.wordBreak = 'break-all';
filename_span.textContent = display_filename;
filename_span.title = display_filename;
const copy_filename_btn = document.createElement('button');
copy_filename_btn.type = 'button';
copy_filename_btn.textContent = '📋'; // Copy icon
copy_filename_btn.title = 'Copy filename';
copy_filename_btn.style.flex = '0 0 auto';
copy_filename_btn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
copyToClipboard(getFilenameForCopy(filename_span.textContent));
});
const export_json_btn_tooltip = document.createElement('button');
export_json_btn_tooltip.type = 'button';
export_json_btn_tooltip.textContent = 'JSON';
export_json_btn_tooltip.title = 'Copy image info as JSON';
export_json_btn_tooltip.style.flex = '0 0 auto';
export_json_btn_tooltip.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
copyBooruInfo(getBooruTooltipInfo(root), true);
export_json_btn_tooltip.style.background = 'lightgreen';
setTimeout(() => export_json_btn_tooltip.style.removeProperty('background'), 1000);
});
tooltip_bar.appendChild(filename_span);
tooltip_bar.appendChild(copy_filename_btn);
tooltip_bar.appendChild(export_json_btn_tooltip);
const tooltip_header = root.querySelector('.post-tooltip-header');
if (tooltip_header) {
tooltip_header.insertAdjacentElement('afterend', tooltip_bar);
} else {
root.prepend(tooltip_bar);
}
}
function initializeBooruTooltips() {
function processTooltips() {
document.querySelectorAll('#tooltips .tippy-content').forEach((root) => {
if (!root.querySelector('.post-tooltip-body')) { return; }
if (root.querySelector('.image-webinfo-tooltip')) { return; }
injectBooruTooltip(root);
});
}
attemptedQuerySelector('#tooltips', (tooltips_container) => {
const observer = new MutationObserver(processTooltips);
observer.observe(tooltips_container, { childList: true, subtree: true });
processTooltips();
});
}
// --- Booru posts ---
if (location.hostname.includes("booru")) {
if (!/^\/posts\/\d+\/?$/.test(location.pathname)) {
if (location.hostname === "danbooru.donmai.us") {
initializeBooruTooltips();
}
return;
}
// Add renamed link
let renamed_download_link = document.createElement("a");
const item_href = document.getElementById('post-option-download').querySelector('a').href;
renamed_download_link.href = item_href;
renamed_download_link.style.display = 'block';
renamed_download_link.style.paddingBottom = '3px';
renamed_download_link.text = "RENAMED FILENAME";
// Replace the original left-click (so that we can use custom filename).
// Note: the right-click context file save behavior is not implemented.
renamed_download_link.removeAttribute('onclick');
renamed_download_link.addEventListener('click', function(e) {
e.preventDefault();
downloadWithCustomName(
item_href,
renamed_download_link.innerText.replace(/\.[^/.]+$/, ''));
});
// Copy the renamed filename (without file extension and the possible '(bad)' prefix)
const fname_copy_button = document.createElement('button');
fname_copy_button.innerText = '📋'; // Copy icon
fname_copy_button.addEventListener('click', () => {
copyToClipboard(getFilenameForCopy(renamed_download_link.innerText));
});
function getBooruInfo(as_JSON=true) {
let data = {};
let tag_list = document.getElementById("tag-list").querySelector("div");
function query_tags(ul_class, sep=" ") {
// Get tag list by ul_class name. Join by sep if multiple.
return queryTagNames(tag_list, `ul.${ul_class} a.search-tag`, sep);
}
data["artists"] = query_tags("artist-tag-list");
data["copyrights"] = query_tags("copyright-tag-list");
data["characters"] = query_tags("character-tag-list");
data["general"] = query_tags("general-tag-list");
data["meta"] = query_tags("meta-tag-list");
// Get information (rating-levels, etc.)
function query_by_id(dom_id, remove_str) {
let _text = document.getElementById(dom_id).innerText;
return _text.replace(remove_str, "").trim();
}
data["booru_id"] = query_by_id("post-info-id", "ID:");
data["booru_date"] = document.querySelector('#post-info-date a').href.split('%3A').at(-1);
data["booru_upvote"] = query_by_id("post-info-score", "Score:");
data["source_url"] = query_by_id("post-info-source", "Source:").replace("»", "").trim();
data["rating_level"] = query_by_id("post-info-rating", "Rating:");
return copyBooruInfo(data, as_JSON);
}
function updateRenamedDownloadLink() {
let renamed_filename = '';
const file_link = document.getElementById('post-info-size').querySelector('a').href;
const post_sources = document.getElementById('post-info-source').querySelectorAll('a');
// Handle pure text sources (such as "file://")
const post_url = post_sources[0]?.href || '';
const site_data = getSitePostData(post_url);
// Find the parent/children relations of the current post
const children_previews = document.querySelector('.posts-container');
let id_child = 0; // If not found parent
if (children_previews) {
const articles = children_previews.querySelectorAll('article');
for (let i = 0; i < articles.length; i++) {
if (articles[i].classList.contains('current-post')) {
id_child = i;
break;
};
}
}
// Process the filename
if (site_data?.code === "PX") { // Pixiv
renamed_filename = site_data.code + post_sources[1].href.split("/").pop();
} else { // Others
const file_prefix = site_data?.code || '#';
const site_id = site_data?.post_id || site_data?.post_name || getSitePostIdFallback(post_url);
const file_ext = file_link.substring(file_link.lastIndexOf('.'));
renamed_filename = file_prefix + site_id + "_p" + id_child + file_ext;
}
// Post-process: Remove everything after '?' if there is any
renamed_filename = stripQueryString(renamed_filename);
// Update the renamed link element
renamed_download_link.download = renamed_filename;
const meta_tags = document.querySelectorAll('ul.meta-tag-list a');
// If it is bad id (the post has revised version), mark it out in the text
let msg_bad_id = '';
for (const _meta_tag of meta_tags) {
if (_meta_tag.innerText == 'bad id') {
msg_bad_id = '(bad) ';
break;
}
}
renamed_download_link.text = msg_bad_id + renamed_filename;
}
// Update link for (renamed) image file download
updateRenamedDownloadLink();
// Add renamed link and buttons
attemptedQuerySelector('section[id="search-box"]', (exist_dom) => {
exist_dom.parentNode.insertBefore(renamed_download_link, exist_dom.nextSibling);
exist_dom.parentNode.insertBefore(fname_copy_button, renamed_download_link.nextSibling);
exist_dom.parentNode.insertBefore(export_json_btn, fname_copy_button.nextSibling);
exist_dom.parentNode.insertBefore(export_str_btn, export_json_btn.nextSibling);
});
export_json_btn.onclick = function() {
artwork_data = getBooruInfo(true);
export_json_btn.style.background = 'lightgreen';
export_str_btn.style.removeProperty("background");
};
export_str_btn.onclick = function() {
artwork_data = getBooruInfo(false);
export_str_btn.style.background = 'lightgreen';
export_json_btn.style.removeProperty("background");
};
}
})();