您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
remove title link / remove excess text / custom title format / click button to copy
当前为
// ==UserScript== // @name dlsite title reformat // @namespace https://github.com/x94fujo6rpg/SomeTampermonkeyScripts // @version 0.51 // @description remove title link / remove excess text / custom title format / click button to copy // @author x94fujo6 // @match https://www.dlsite.com/maniax/work/=/product_id/* // @match https://www.dlsite.com/home/work/=/product_id/* // @grant GM_getValue // @grant GM_setValue // ==/UserScript== (function () { 'use strict'; let debug = true; let formatted_data = { id: "", title_original: "", title_formatted: "", circle: "", Year: "", year: "", month: "", day: "", series: "", author: "", scenario: "", illust: "", cv: "", age: "", type: "", tags: "", }; let data_list = Object.keys(formatted_data); let key_format = "format_seting"; let key_adv = "format_adv"; let default_format = "%id% %title_formatted%"; let default_adv = false; let updateid; let half = "1234567890()[]{}~!@#$%^&_+-=;':,.()~"; let full = "1234567890()[]{}~!@#$%︿&_+-=;’:,.()〜"; let forbidden = `<>:"/|?*\\`; let replacer = `<>:”/|?*\`; let separator = "、"; // separator for data like %tags% let oldUI_original_title = true; // Original / ID+Original button let oldUI_default_format_title = true; // DefaultFormat / ID+DefaultFormat button let format_setting = GM_getValue(key_format, default_format); print(`${key_format}: ${format_setting}`); let adv = GM_getValue(key_adv, default_adv); print(`${key_adv}: ${adv}`); window.onload = function () { window.document.body.onload = main(); }; function saveSetting() { GM_setValue(key_adv, adv); print(`saved ${key_adv}: ${adv}`); if (format_setting.length > 0) { GM_setValue(key_format, format_setting); print(`saved ${key_format}: ${format_setting}`); } else { print(`${key_format} not saved cus is empty`); } } function getData() { console.time(getData.name); //------------------------------------------------------ let sitedata = contents.detail[0]; let [Y, m, d] = sitedata.regist_date.split("/"); let y = Y.slice(2); let circle = document .getElementById("work_maker") .querySelector("span.maker_name[itemprop='brand']"); let circle_text = circle.querySelector("a").textContent; circle.insertAdjacentElement("afterbegin", newCopyButton(circle_text, "Copy")); Object.assign(formatted_data, { id: sitedata.id, title_original: sitedata.name, title_formatted: stringFormatter(sitedata.name), circle: stringFormatter(circle_text), Year: Y, year: y, month: m, day: d, }); //------------------------------------------------------ let datapart = document.getElementById("work_right_inner").querySelectorAll("th"); let parselist = { series: ["Series name", "シリーズ名", "系列名", "系列名"], author: ["Author", "作者", "作者", "作者"], scenario: ["Scenario", "シナリオ", "剧情", "劇本"], illust: ["Illustration", "イラスト", "插画", "插畫"], cv: ["Voice Actor", "声優", "声优", "聲優"], age: ["Age", "年齢指定", "年龄指定", "年齡指定"], type: ["Product format", "作品形式", "作品类型", "作品形式"], }; let release = ["Release date", "販売日", "贩卖日", "販賣日"]; let text; let all = []; datapart.forEach(th => { for (let key in parselist) { text = th.textContent; if (isInList(text, parselist[key], formatted_data[key])) { all = []; th.parentNode.querySelectorAll("a").forEach(a => all.push(a.textContent)); formatted_data[key] = stringFormatter(all.join(separator)); insertCopyDataButton(th, formatted_data[key]); delete parselist[key]; break; } else if (release) { if (release.some(t => text.includes(t))) { let date = `${Y}${m}${d}`; insertCopyDataButton(th, date, date); date = `${y}${m}${d}`; insertCopyDataButton(th, date, date); release = false; } } } }); //------------------------------------------------------ let tagpart = document .getElementById("work_right_inner") .querySelector("div.main_genre"); let insertpos = tagpart; tagpart = tagpart.querySelectorAll("a"); let tags = []; tagpart.forEach(a => tags.push(a.textContent)); formatted_data.tags = stringFormatter(tags.join(separator)); insertCopyDataButton(insertpos, formatted_data.tags); console.timeEnd(getData.name); } function insertCopyDataButton(ele, copytext = "", btext = "Copy") { ele = searchNodeNameInParents(ele, "TR"); if (!ele) return; let pos = ele.querySelector("div"); if (!pos) pos = ele.querySelector("td"); if (!pos) return; pos.insertAdjacentElement("afterbegin", newCopyButton(copytext, btext)); } function searchNodeNameInParents(ele, nodename = "") { if (!ele || !nodename) return false; nodename = nodename.toUpperCase(); let count = 0; while (true) { ele = ele.parentNode; count++; if (!ele || count > 100) return false; if (ele.nodeName == nodename) break; } return ele; } function isInList(text, list, data) { if (!data) { if (list.some(t => text.includes(t))) return true; } return false; } function stringFormatter(text) { text = removeExcess(text); text = toHalfWidth(text); text = repalceForbiddenChar(text); return text; } function removeExcess(text) { // remove excess text 【...】 let count = 0; while (text.indexOf("【") != -1 && count < 999) { let start = text.indexOf("【"); let end = text.indexOf("】") + 1; let removestr = ""; if (end) { removestr = text.substring(start, end); } else { removestr = text.slice(start); } text = text.replace(removestr, "").trim(); count++; } // remove『』if it at start & end if (text.indexOf("『" === 0 && text.indexOf("』") === text.length - 1)) { text = text.replace("『", "").replace("』", "").trim(); } return text; } function toHalfWidth(text) { for (let index in half) { let h = half[index]; let f = full[index]; let count = 0; while (text.indexOf(f) != -1 && count < 999) { text = text.replace(f, h); count++; } } return text; } function repalceForbiddenChar(text) { for (let index in forbidden) { let fb = forbidden[index]; let rp = replacer[index]; let count = 0; while (text.indexOf(fb) != -1 && count < 999) { text = text.replace(fb, rp); count++; } } return text; } function updateSetting() { let s = document.getElementById("format_title_setting"); let p = document.getElementById("format_title_preview"); let cs = document.getElementById("format_title_custom_span"); let cb = document.getElementById("format_title_custom_button"); if (s.value.length > 0) { if (format_setting != s.value) { format_setting = s.value; let formatted = parseFormatString(format_setting); cs.textContent = p.value = formatted; cb.onclick = () => navigator.clipboard.writeText(formatted); } } } function parseFormatString(string = "") { let formatted_text = string; data_list.forEach(key => { let count = 0; while (formatted_text.includes(`%${key}%`) && count < 999) { formatted_text = formatted_text.replace(`%${key}%`, formatted_data[key]); count++; } }); formatted_text = repalceForbiddenChar(formatted_text); return formatted_text; } function setting() { console.time(setting.name); //------------------------------------------------------ let pos = document.getElementById("work_name"); let button = document.createElement("button"); Object.assign(button, { textContent: "open format setting", value: "open", onclick: function () { let ele = document.getElementById("format_setting_ui"); if (this.value === "close") { ele.style.display = "none"; this.value = "open"; this.textContent = "open format setting"; clearInterval(updateid); } else { ele.style.display = ""; this.value = "close"; this.textContent = "close format setting"; updateid = setInterval(updateSetting, 100); } }, }); pos.appendChild(button); appendNewLine(pos); //------------------------------------------------------ let box = document.createElement("div"); Object.assign(box, { id: "format_setting_ui", className: "dtr_setting_box", }); box.style.display = "none"; //------------------------------------------------------ button = document.createElement("button"); let mode = adv ? "on" : "off"; Object.assign(button, { className: "dtr_textsize05", id: "format_title_setting_advance_model", textContent: `advance mode: ${mode}`, value: mode, onclick: function () { let t = document.getElementById("format_title_setting"); if (this.value === "off") { Object.assign(this, { value: "on", textContent: "advance mode: on", }); t.readOnly = false; adv = true; } else { Object.assign(this, { value: "off", textContent: "advance mode: off", }); t.readOnly = true; adv = false; } } }); box.appendChild(button); box.appendChild(newSpan(" (enable this to direct edit format setting. if you don't know what is this, don't touch it.)")); appendNewLine(box); appendNewLine(box); //------------------------------------------------------ data_list.forEach(s => box.appendChild(newDataButton(`+${s}`, `%${s}%`))); appendNewLine(box); //------------------------------------------------------ let textarea; textarea = document.createElement("textarea"); Object.assign(textarea, { className: "dtr_textsize05 dtr_max_width", id: "format_title_setting", rows: 1, value: format_setting, }); textarea.readOnly = !adv; box.appendChild(newSpan("format setting:")); appendNewLine(box); box.appendChild(textarea); appendNewLine(box); textarea = document.createElement("textarea"); Object.assign(textarea, { className: "dtr_textsize05 dtr_max_width", id: "format_title_preview", readOnly: true, rows: 1, value: parseFormatString(format_setting), }); box.appendChild(newSpan("format preview:")); appendNewLine(box); box.appendChild(textarea); appendNewLine(box); //------------------------------------------------------ box.appendChild(newButton("save", saveSetting)); box.appendChild(newSeparate()); box.appendChild(newButton("default", () => { document.getElementById("format_title_setting").value = default_format; })); box.appendChild(newSeparate()); box.appendChild(newButton("clear", () => { document.getElementById("format_title_setting").value = ""; })); appendNewLine(box); appendNewLine(box); //------------------------------------------------------ textarea = document.createElement("textarea"); Object.assign(textarea, { className: "dtr_textsize05", id: "format_title_all_data", readOnly: true, }); box.appendChild(textarea); pos.append(box); listAllData(); updateSetting(); console.timeEnd(setting.name); } function listAllData() { let textbox = document.getElementById("format_title_all_data"); textbox.value = ""; let count = 0; let maxlength = 0; let s; for (let key in formatted_data) { s = `%${key}%: ${formatted_data[key]}\n`; textbox.value += s; count++; if (formatted_data[key]) { if (s.length > maxlength) maxlength = s.length; } } Object.assign(textbox, { rows: count + 1, cols: maxlength * 2, }); } function newButton(btext, onclick) { let _button = document.createElement("button"); Object.assign(_button, { textContent: btext, onclick: onclick, }); return _button; } function newDataButton(btext, format_string) { return newButton(btext, () => { updateSettingString("format_title_setting", format_string); }); } function updateSettingString(id, format_string) { let textarea = document.getElementById(id); let list = [ "year", "Year", "month", "day", ]; let o = textarea.value; if (list.some(s => format_string.includes(s)) && list.some(s => o.endsWith(`%${s}%`))) { textarea.value += format_string; } else { textarea.value += ` ${format_string}`; } textarea.value = textarea.value.trim(); } function main() { getData(); myCss(); setting(); console.time(main.name); //------------------------------------------------------ let pos = document.querySelector("#work_name").querySelector("a"); pos.style.display = "none"; pos = pos.parentNode; let id = formatted_data.id; let title_o = formatted_data.title_original; let title_f = formatted_data.title_formatted; let title_id_c = parseFormatString(format_setting); let title_id_o = `${id} ${title_o}`; let title_id_f = `${id} ${title_f}`; let notSame_o_c = title_id_o != title_id_c; let notSame_f_c_o = title_id_f != (title_id_c || title_id_o); //------------------------------------------------------ // ID + original title if (notSame_o_c && oldUI_original_title) { pos.append(newSpan(title_id_o, "")); appendNewLine(pos); } //------------------------------------------------------ // ID + formatted title if (notSame_f_c_o && oldUI_default_format_title) { pos.append(newSpan(title_id_f, "")); appendNewLine(pos); } //------------------------------------------------------ // custom title let span = newSpan(title_id_c, ""); span.id = "format_title_custom_span"; pos.append(span); appendNewLine(pos); //------------------------------------------------------ // add copy ID button pos.append(newCopyButton(id)); pos.append(newSeparate()); //------------------------------------------------------ // add copy custom format button let custom_button = newCopyButton(title_id_c, "Custom"); custom_button.id = "format_title_custom_button"; pos.append(custom_button); pos.append(newSeparate()); //------------------------------------------------------ // add copy Original / ID+Original button if (notSame_o_c && oldUI_original_title) { pos.append(newCopyButton(title_o, "Original")); pos.append(newCopyButton(title_id_o, "ID+Original")); } //------------------------------------------------------ // add copy Formatted / ID+Formatted button if (notSame_f_c_o && oldUI_default_format_title) { pos.append(newSeparate()); pos.append(newCopyButton(title_f, "DefaultFormat")); pos.append(newCopyButton(title_id_f, "ID+DefaultFormat")); } //------------------------------------------------------ // creat track list if any let list = gettracklist(); if (list) addTracklist(list); console.timeEnd(main.name); } function addTracklist(list) { let pos = document.querySelector("[itemprop='description']").childNodes[2]; let textbox = document.createElement("textarea"); let count = 0; let maxlength = 0; list.forEach(line => { textbox.value += `${line}\n`; count++; if (line.length > maxlength) maxlength = line.length; }); Object.assign(textbox, { name: "mytracklist", rows: count + 1, cols: maxlength * 2, }); pos.insertAdjacentElement("afterbegin", textbox); let copyall = document.createElement("button"); copyall.textContent = "Copy All"; copyall.onclick = function () { textbox.select(); textbox.setSelectionRange(0, 99999); document.execCommand("copy"); }; textbox.insertAdjacentElement("afterend", newLine()); textbox.insertAdjacentElement("afterend", copyall); textbox.insertAdjacentElement("afterend", newLine()); } function gettracklist() { let list = document.querySelector(".work_tracklist"); if (list) { let tracklist = []; list = list.querySelectorAll(".work_tracklist_item"); list.forEach((ele, index) => { tracklist.push(`${index + 1}. ${ele.querySelector(".title").textContent}`); }); return tracklist; } else { return false; } } function appendNewLine(ele) { ele.appendChild(document.createElement("br")); } function newLine() { return document.createElement("br"); } function newSeparate() { return newSpan(" / "); } function newCopyButton(copytext, btext = "") { if (btext === "") { return newButton(copytext, () => { navigator.clipboard.writeText(copytext); }); } else { return newButton(btext, () => { navigator.clipboard.writeText(copytext); }); } } function newSpan(text = "", className = "dtr_textsize05") { let span = document.createElement("span"); Object.assign(span, { className: className, textContent: text, }); return span; } function myCss() { let s = document.createElement("style"); s.className = "myCssSheet"; document.head.appendChild(s); s.textContent = ` .dtr_textsize05 { font-size: 0.5rem; } .dtr_setting_box { border: 0.2rem; border-style: solid; padding: 0.5rem; } .dtr_max_width { width: 100%; } `; } function print(...any) { if (debug) console.log(...any); } })();