Skip to content

Instantly share code, notes, and snippets.

@nideii
Last active May 6, 2023 03:13
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nideii/e28876549ac60a0d1cb3693e4cadcf88 to your computer and use it in GitHub Desktop.
Save nideii/e28876549ac60a0d1cb3693e4cadcf88 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name DLSite page search
// @namespace https://www.south-plus.net/
// @version 0.2
// @description add sp search link to item page
// @author nideii
// @match https://www.dlsite.com/*/work/=/product_id/*.html
// @require https://cdn.jsdelivr.net/npm/jquery@2.2.4/dist/jquery.min.js
// @require https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js
//
// @run-at document-idle
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @run-at document-idle
// @connect *
// ==/UserScript==
// v0.2
// 新增多个样式按钮
// 新增自定义格式支持
// 优化排版
// v0.1
// 初始版本
// 换成自己能访问的链接
var sp_url = 'https://www.south-plus.net/search.php';
function addJS(code) {
let js = document.createElement("script");
js.type = 'text/javascript';
js.onload = function () { }
js.text = code;
// document.getElementsByTagName("head")[0].appendChild(js);
document.body.appendChild(js);
}
async function sleep(sec) {
return new Promise(resolve => setTimeout(resolve, sec * 1000));
}
function openpost(url, id, bg = false) {
var tempForm = document.createElement("form");
tempForm.id = "tempForm1";
tempForm.method = "post";
tempForm.action = url;
tempForm.target = id;
let formdata = {};
formdata.step = 2;
formdata.keyword = id;
formdata.method = 'OR';
formdata.pwuser = '';
formdata.sch_area = 0;
formdata.f_fid = 'all';
formdata.sch_time = 'all';
formdata.orderway = 'postdate';
formdata.asc = 'DESC';
let data = '';
for (let k in formdata) {
data += '<input type="hidden" name="' + k + '" value="' + formdata[k] + '" />\n';
}
tempForm.innerHTML = data;
tempForm.addEventListener("onsubmit", function () {
let child = window.open('about:blank', id);
if (bg) {
child.blur();
window.focus();
}
});
document.body.appendChild(tempForm);
tempForm.dispatchEvent(new Event("onsubmit"));
tempForm.submit();
document.body.removeChild(tempForm);
}
function addHTML() {
GM_addStyle(`
.tooltip {
position: relative;
}
.tooltip:hover::before {
position: absolute;
z-index: 1000000;
padding: 5px 8px;
color: #fff;
display: block;
text-align: center;
text-decoration: none;
text-shadow: none;
text-transform: none;
letter-spacing: normal;
font-size: 14px;
word-wrap: break-word;
white-space: pre;
pointer-events: none;
content: attr(aria-label);
background: rgba(0, 0, 0, .8);
border-radius: 3px;
-webkit-font-smoothing: subpixel-antialiased;
top: 24px;
left: 50%;
transform: translateX(-50%);
}
.modal {
display: none;
position: fixed;
z-index: 100000;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
font-family: Microsoft YaHei;
line-height: 1.5;
}
.modal-content {
position: relative;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
width: 80%;
pointer-events: auto;
background-color: #fff;
background-clip: padding-box;
border: 1px solid rgba(0, 0, 0, .2);
border-radius: .3rem;
outline: 0;
margin: auto;
}
.modal-header {
display: flex;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: flex-start;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
padding: .8rem;
border-bottom: 1px solid #e9ecef;
border-top-left-radius: .3rem;
border-top-right-radius: .3rem;
}
.modal-body {
position: relative;
-webkit-box-flex: 1;
flex: 1 1 auto;
padding: 1rem;
}
.modal-footer {
display: flex;
align-items: center;
justify-content: flex-end;
padding: 1rem;
border-top: 1px solid #e9ecef;
}
.close {
color: #aaaaaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.modal-btn {
margin-left: .2rem;
margin-right: .2rem;
}
.modal input[type=text],
select {
width: 100%;
padding: 12px 12px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
.modal .small-table hr {
width: 70px;
}
.modal li {
margin-top: 1rem;
}
pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f6f8fa;
border-radius: 3px;
}
pre>code {
font-size: 100%;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
display: inline;
max-width: auto;
padding: 0;
margin: 0;
overflow: visible;
line-height: inherit;
word-wrap: normal;
background-color: initial;
}
code {
padding: .2em .4em;
margin: 0;
font-size: 85%;
background-color: rgba(27, 31, 35, .05);
border-radius: 3px;
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
}
`);
$('body').append(`
<div id="myModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>DLSite 页面小帮手</h3>
<span class="close">&times;</span>
</div>
<div class="modal-body">
<table class="small-table">
<tr>
<th>名称</th>
<th>变量名</th>
<th></th>
<th>名称</th>
<th>变量名</th>
</tr>
<tr>
<td>RJ号</td>
<td><code>{rjid}</code></td>
<td></td>
<td>作品名</td>
<td><code>{title}</code></td>
</tr>
<tr>
<td>社团名</td>
<td><code>{maker}</code></td>
<td></td>
<td>声优列表</td>
<td><code>{cvlist}</code></td>
</tr>
<tr>
<td>声优</td>
<td><code>{cv}</code></td>
<td style="width: 30px;"></td>
</tr>
</table>
<hr style="margin: 1rem 0 1rem 0;">
<label for="prefix">前缀</label>
<input type="text" id="prefix" placeholder="C:\\new foler\\">
<label for="cv-format">声优格式</label>
<input type="text" id="cvlist_format" placeholder="[{cv}]">
<hr style="margin: 1rem 0 1rem 0;">
<table style="width: 100%;">
<tr>
<th style="width: 30%;">格式名</th>
<th style="width: 8px;"></th>
<th>格式</th>
</tr>
<tr>
<td><input type="text" id="min_format_name" placeholder="复制RJ标题"></td>
<td></td>
<td><input type="text" id="min_format" placeholder="{rjid} {title}"></td>
</tr>
<tr>
<td><input type="text" id="maker_format_name" placeholder="复制社团"></td>
<td></td>
<td><input type="text" id="maker_format" placeholder="[{maker}][{rjid}] {title}"></td>
</tr>
<tr>
<td><input type="text" id="all_format_name" placeholder="复制社团+声优"></td>
<td></td>
<td><input type="text" id="all_format" placeholder="[{maker}][{rjid}]{cvlist} {title}"></td>
</tr>
</table>
<hr style="margin: 1rem 0 1rem 0;">
<label>样例: </label>
<ul>
<li id="min-sample">
<label for="min_format_name"></label>:
<pre><code></code></pre>
</li>
<li id="maker-sample">
<label for="maker_format_name"></label>:
<pre><code></code></pre>
</li>
<li id="all-sample">
<label for="all_format_name"></label>:
<pre><code></code></pre>
</li>
<li id="cvlist-sample">
<label for="cvlist_format">声优格式</label>:
<pre><code></code></pre>
</li>
</ul>
</div>
<div class="modal-footer">
<h4>格式修改全部页面自动同步,但是其名字并不会同步</h4>
<button type="button" class="modal-btn" id="modal-close">关闭</button>
<button type="button" class="modal-btn" id="modal-save">保存修改</button>
</div>
</div>
</div>
`);
}
function warpstr(str) {
return "'" + str + "'";
}
function replace(str) {
var dict = {
'<': '',
'>': '',
':': ':',
'"': '”',
':': ':',
'/': '',
'\\': '',
'|': '',
'?': '?',
'*': '*',
};
for (let k in dict) {
str = str.replace(k, dict[k]);
}
return str;
}
function dict_replace(str, obj) {
for (var key in obj) {
str = str.replace(`{${key}}`, obj[key]);
}
return replace(str);
}
var item_data = {
'rjid': '',
'title': '',
'maker': '',
cv: [],
'cvlist': '',
}
function save_obj(obj) {
for (let prop in obj) {
GM_setValue(prop, obj[prop]);
}
}
function get_formatname() {
return {
min_format_name: GM_getValue('min_format_name', '复制RJ标题'),
maker_format_name: GM_getValue('maker_format_name', '复制社团RJ标题'),
all_format_name: GM_getValue('all_format_name', '复制社团RJ声优标题'),
}
}
function get_format() {
let prefix = GM_getValue('prefix', '');
let min_format = GM_getValue('min_format', '{rjid} {title}');
let maker_format = GM_getValue('maker_format', '[{maker}][{rjid}] {title}');
let all_format = GM_getValue('all_format', '[{maker}][{rjid}]{cvlist} {title}');
let cvlist_format = GM_getValue('cvlist_format', '[{cv}]');
return {
prefix: prefix,
min_format: min_format,
maker_format: maker_format,
all_format: all_format,
cvlist_format: cvlist_format,
}
}
function format_name(format) {
let cvlist = "";
for (let i = 0; i < item_data.cv.length; ++i) {
cvlist += format.cvlist_format.replace('{cv}', item_data.cv[i]);
}
item_data.cvlist = cvlist;
return {
min: format.prefix + dict_replace(format.min_format, item_data),
maker: format.prefix + dict_replace(format.maker_format, item_data),
all: format.prefix + dict_replace(format.all_format, item_data),
cvlist: cvlist,
}
}
(function () {
'use strict';
addHTML();
addJS(openpost.toString());
let work_name = $('#work_name');
let link = work_name.children('a')[0].href;
let match = link.match(/(RJ|BJ|VJ)([0-9]+)/);
if (match == null || match.length < 3) {
console.log('link does not match: ' + link);
return;
}
item_data.rjid = match[0];
item_data.title = work_name.children('a').text().trim();
item_data.maker = $('#work_maker > tbody > tr > td > span.maker_name > a').text();
let tags = $('#work_outline > tbody > tr > th');
for (let i = 0; i < tags.length; ++i) {
let tag = $(tags[i])
if (tag.text() != '声優') {
continue;
}
let cvitems = tag.next().children('a');
for (let j = 0; j < cvitems.length; ++j) {
item_data.cv.push($(cvitems[j]).text());
}
}
console.info(item_data);
work_name.html(item_data.rjid + ' ' + replace(item_data.title));
let btnname = get_formatname();
$('div.link_dl_ch').append(`
<button type="button" id="settings" class="btn_default newbtn">设置</button>
<br>
<div id="btngroup">
<button type="button" id="spsearch" class="btn_default newbtn">搜索</button>
<button type="button" id="clipboard-1" class="btn_default newbtn clipboard-btn" data-format="min">${btnname.min_format_name}</button>
<button type="button" id="clipboard-2" class="btn_default newbtn clipboard-btn" data-format="maker">${btnname.maker_format_name}</button>
<button type="button" id="clipboard-3" class="btn_default newbtn clipboard-btn" data-format="all">${btnname.all_format_name}</button>
</div>
`);
$('div.base_title_br h1').css('margin-right', $('#btngroup').width() + 100);
$('#spsearch').click(function () {
openpost(sp_url, match[0], true);
});
$('#settings').css('margin-left', '0.2rem');
$('.newbtn').css('margin-right', '0.2rem');
$('.newbtn').css('margin-top', '0.2rem');
$('.newbtn').on('mouseleave', function () {
$(this).removeClass('tooltip');
$(this).removeAttr('aria-label');
});
$('#settings').on('click', function () {
let format = get_format();
let text = format_name(format);
let btn_name = get_formatname();
for (var name in btn_name) {
$('#'+name).val(btn_name[name]);
$(`label[for=${name}]`).text(btn_name[name]);
}
$('#myModal #prefix').val(format.prefix);
$('#myModal #min_format').val(format.min_format);
$('#myModal #maker_format').val(format.maker_format);
$('#myModal #all_format').val(format.all_format);
$('#myModal #cvlist_format').val(format.cvlist_format);
$('#min-sample > pre > code').text(text.min);
$('#maker-sample > pre > code').text(text.maker);
$('#all-sample > pre > code').text(text.all);
$('#cvlist-sample > pre > code').text(text.cvlist);
$('#myModal').css('display', 'block');
});
$('#myModal input').on('keyup', function () {
let format = {
prefix: $('#myModal #prefix').val(),
min_format: $('#myModal #min_format').val(),
maker_format: $('#myModal #maker_format').val(),
all_format: $('#myModal #all_format').val(),
cvlist_format: $('#myModal #cvlist_format').val(),
};
let btn_name = {
min_format_name: $('#myModal #min_format_name').val(),
maker_format_name: $('#myModal #maker_format_name').val(),
all_format_name: $('#myModal #all_format_name').val(),
};
for (var name in btn_name) {
console.log(name, btn_name[name], `lable[for=${name}]`);
$(`label[for=${name}]`).text(btn_name[name]);
}
let text = format_name(format);
$('#min-sample > pre > code').text(text.min);
$('#maker-sample > pre > code').text(text.maker);
$('#all-sample > pre > code').text(text.all);
$('#cvlist-sample > pre > code').text(text.cvlist);
});
let close_modal = function () {
$('#myModal').css('display', 'none');
};
$('span.close').click(close_modal);
$('#modal-close').click(close_modal);
$('#modal-save').click(function () {
let format = {
prefix: $('#myModal #prefix').val(),
min_format: $('#myModal #min_format').val(),
maker_format: $('#myModal #maker_format').val(),
all_format: $('#myModal #all_format').val(),
cvlist_format: $('#myModal #cvlist_format').val(),
};
save_obj(format);
close_modal();
});
new ClipboardJS('.clipboard-btn', {
text: function (trigger) {
let format = get_format();
let data = format_name(format);
let text = data[$(trigger).attr('data-format')];
$(trigger).addClass('tooltip');
if (text.length > 250) {
$(trigger).attr('aria-label', '已复制,但超过路径最大长度');
} else {
$(trigger).attr('aria-label', '已复制');
}
return text;
}
});
})();
@yoyokirby
Copy link

大佬,似乎用不了了,求更新修复。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment