Last active
July 26, 2016 07:54
-
-
Save FlandreDaisuki/ac26b3178804b067b5f71417373e87e1 to your computer and use it in GitHub Desktop.
let dymy more powerful
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name CustomDYMY | |
// @description Custom your favorite teams for new anime | |
// @namespace FlandreDaisuki | |
// @include https://share.dmhy.org/* | |
// @author FlandreDaisuki | |
// @version 2016.07.16 | |
// @grant none | |
// ==/UserScript== | |
/* jshint esnext: true */ | |
console.log('點擊[新番追番]可以按時間列出所有已追動畫'); | |
console.log('點擊[增加新番],顧名思義'); | |
console.log('左鍵點擊<已追動畫>,可只列出該動畫'); | |
console.log('右鍵點擊<已追動畫>,可刪除該動畫'); | |
console.log('點擊[清除全部追番],清除全部追番'); | |
const qs = document.querySelector.bind(document); | |
const qsa = document.querySelectorAll.bind(document); | |
const jx = 'javascript:;'; | |
const tbody = qs('#topic_list tbody'); | |
const wmap = new WeakMap(); | |
let lsf = lsget(); | |
function el(selector) { | |
const m = selector.match(/[#\.]?[^#\.]+/g); | |
const id = new Set(m.filter(x => x[0] === '#')); | |
const cl = new Set(m.filter(x => x[0] === '.')); | |
const t = new Set(m.filter(x => !id.has(x)).filter(x => !cl.has(x))); | |
let e = document.createElement((t.size) ? ([...t][0]) : ('div')); | |
if (id.size) { | |
e.id = [...id][0].slice(1); | |
} | |
if (cl.size) { | |
e.className = [...cl].map(x => x.slice(1)).join(' '); | |
} | |
return e; | |
} | |
function lsset() { | |
localStorage.setItem('lsf', JSON.stringify(lsf)); | |
} | |
function lsget() { | |
const f = localStorage.getItem('lsf'); | |
return f ? JSON.parse(f) : []; | |
} | |
function rmqsa(s) { | |
Array.from(qsa(s)).forEach(x => x.remove()); | |
} | |
function setupHTML(setupHTMLEvents) { | |
/** li part | |
ul.nav> | |
li#czli> | |
( | |
a#czdes+ | |
ul#flnav> | |
( | |
li.flli> | |
a.fldes | |
)*n+ | |
( | |
li#addli> | |
a#adddes | |
)+ | |
li#clearli> | |
a#cleardes | |
) | |
*/ | |
const ulnav = qs('ul.nav'); | |
const czli = el('li#czli'); | |
ulnav.appendChild(czli); | |
const czdes = el('a#czdes'); | |
czdes.innerHTML = '新番追番'; | |
czdes.href = jx; | |
const flnav = el('ul#flnav'); | |
czli.appendChild(czdes); | |
czli.appendChild(flnav); | |
const addli = el('li#addli'); | |
flnav.appendChild(addli); | |
const adddes = el('a#adddes'); | |
adddes.innerHTML = '增加新番'; | |
adddes.href = jx; | |
addli.appendChild(adddes); | |
reset_flnav(addli); | |
const clearli = el('li#clearli'); | |
ulnav.appendChild(clearli); | |
const cleardes = el('a#cleardes'); | |
cleardes.innerHTML = '清除全部追番'; | |
cleardes.href = jx; | |
clearli.appendChild(cleardes); | |
/** ui part | |
div#czui> | |
( | |
select#czanime+ | |
select#czteam+ | |
a#czadd | |
) | |
*/ | |
const czui = el('#czui.hide'); | |
qs('body').appendChild(czui); | |
const czanime = el('select#czanime'); | |
const czteam = el('select#czteam'); | |
const czenc = el('select#czenc'); | |
const czadd = el('a#czadd'); | |
czui.appendChild(czanime); | |
czui.appendChild(czteam); | |
czui.appendChild(czenc); | |
czui.appendChild(czadd); | |
czadd.href = jx; | |
czadd.innerHTML = '新增'; | |
const czanime_all = el('option'); | |
czanime_all.value = 'keyword='; | |
czanime_all.innerHTML = '全部'; | |
czanime.appendChild(czanime_all); | |
czteam.innerHTML = ` | |
<option value="team_id=0">全部</option> | |
<option value="team_id=58">澄空學園</option> | |
<option value="team_id=88">动音漫影</option> | |
<option value="team_id=185">極影字幕社</option> | |
<option value="team_id=241">幻櫻字幕组</option> | |
<option value="team_id=303">動漫國字幕组</option> | |
<option value="team_id=348">HKACG香港動漫</option> | |
<option value="team_id=407">DHR動研字幕組</option> | |
`; | |
czenc.innerHTML = ` | |
<option value="">繁簡</option> | |
<option value="繁|big5">繁體</option> | |
<option value="簡|GB">簡體</option> | |
`; | |
const jmd_base_trs = Array.from(qsa('table.jmd_base tr')); | |
jmd_base_trs.forEach(tr => { | |
const optgroup = el('optgroup'); | |
optgroup.label = tr.firstChild.innerText; | |
const tds = Array.from(tr.lastChild.children); | |
tds.forEach(td => { | |
const opt = el('option'); | |
opt.value = td.href.match(/keyword=.*/).pop(); | |
opt.innerText = td.innerText; | |
optgroup.appendChild(opt); | |
}); | |
czanime.appendChild(optgroup); | |
}); | |
setupHTMLEvents(); | |
} | |
function setupEvents() { | |
addli.addEventListener('click', function() { | |
czui.classList.remove('hide'); | |
}); | |
czui.addEventListener('click', function(event) { | |
if (event.target === this) { | |
czui.classList.add('hide'); | |
} | |
}); | |
czdes.addEventListener('click', function() { | |
rmqsa('#topic_list tbody tr'); | |
Promise.all(Array.from(qsa('.fldes')).map(a => wmap.get(a))) | |
.then(a => { | |
const trs = a.reduce((a, b) => a.concat(b), []); | |
trssort(trs); | |
trs.forEach(tr => { | |
tbody.appendChild(tr); | |
}); | |
}); | |
}); | |
czadd.addEventListener('click', function() { | |
const as = czanime.selectedOptions[0]; | |
const ss = czteam.selectedOptions[0]; | |
const ens = czenc.selectedOptions[0]; | |
lsf.push({ | |
name: as.innerHTML, | |
team: ss.innerHTML, | |
enc: ens.innerHTML, | |
target: `https://share.dmhy.org/topics/list?${as.value} ${ens.value}&${ss.value}`, | |
}); | |
lsset(); | |
rmqsa('.flli'); | |
reset_flnav(addli); | |
czui.classList.add('hide'); | |
}); | |
cleardes.addEventListener('click', function() { | |
if (confirm("確定清除全部追番?")) { | |
localStorage.clear(); | |
location.href = location.href; | |
} | |
}); | |
} | |
function setupCSS() { | |
const style = document.createElement('style'); | |
document.head.appendChild(style); | |
style.innerHTML = ` | |
#czli, | |
#flnav li { | |
width: initial !important; | |
min-width: 240px; | |
} | |
#czli:hover #flnav{ | |
display: block; | |
} | |
#flnav { | |
display: none; | |
position: absolute; | |
width: initial !important; | |
} | |
#flnav .flli { | |
display: block; | |
float: none; | |
} | |
#flnav a { | |
width: 100%; | |
} | |
#czui> *{ | |
margin: 20px; | |
} | |
#czui { | |
height: 100vh; | |
width: 100vw; | |
background-color: rgba(60, 60, 60, 0.5); | |
position: fixed; | |
top: 0; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
font-size: 18px; | |
} | |
#czui select { | |
font-size: 16px; | |
height: 32px; | |
} | |
#czui optgroup { | |
font-size: 14px; | |
} | |
#czui option { | |
font-size: 16px; | |
} | |
#czui.hide { | |
display: none; | |
} | |
#czadd { | |
padding: 5px 10px; | |
border-radius: 3px; | |
background-color: #9CC; | |
} | |
#adddes { | |
font-size: 1rem; | |
color: #9E334F; | |
font-weight: bold; | |
letter-spacing: 5px; | |
} | |
#clearli { | |
margin-left: 150px; | |
} | |
#cleardes { | |
color: #F00; | |
font-weight: bold; | |
} | |
#topic_list tbody tr:nth-child(odd){ | |
background-color: #CDF; | |
} | |
`; | |
} | |
function reset_flnav(addli) { | |
lsf.forEach(function(rec) { | |
const li = el('li.flli'); | |
const a = el('a.fldes'); | |
wmap.set(a, fetchTargets(rec.target)); | |
li.appendChild(a); | |
a.href = `${jx}`; | |
a.innerHTML = `[${rec.team}] ${rec.name} (${rec.enc})`; | |
a.onmouseup = showordel; | |
a.oncontextmenu = () => false; | |
addli.parentNode.insertBefore(li, addli); | |
}); | |
} | |
function fetchTargets(url) { | |
return fetch(url) | |
.then(res => res.text()) | |
.then(html => (new DOMParser()).parseFromString(html, 'text/html')) | |
.then(doc => { | |
const kws = Array.from(doc.querySelectorAll('span.keyword')); | |
kws.forEach(kw => { | |
kw.outerHTML = kw.innerHTML; | |
}); | |
return Array.from(doc.querySelectorAll('#topic_list tbody tr')); | |
}) | |
.catch(err => { | |
console.log(err); | |
}); | |
} | |
function showordel(event) { | |
const node = event.target; | |
const btn = ['left', 'mid', 'right'][event.button]; | |
if(btn === 'left'){ | |
if (wmap.has(node)) { | |
const p = wmap.get(node); | |
p.then(trs => { | |
rmqsa('#topic_list tbody tr'); | |
trssort(trs); | |
trs.forEach(tr => tbody.appendChild(tr) ); | |
}); | |
} | |
} else if(btn === 'right'){ | |
if (confirm(`確定清除 ${node.innerHTML} ?`)) { | |
const li = node.parentNode; | |
const target_i = [].indexOf.call(li.parentNode.children, li); | |
lsf.splice(target_i, 1); | |
lsset(); | |
location.href = location.href; | |
} | |
} else { | |
return false; | |
} | |
} | |
function trssort(trs) { | |
trs.sort((a, b) => { | |
const aa = new Date(a.firstElementChild.firstElementChild.innerText); | |
const bb = new Date(b.firstElementChild.firstElementChild.innerText); | |
return bb - aa; | |
}); | |
} | |
function removeAd() { | |
[ | |
'#zds_ad', | |
'#mbjx_ad', | |
'#shareman_ad', | |
'iframe', | |
].forEach(x => { | |
qs(x).remove(); | |
}); | |
} | |
setupHTML(setupEvents); | |
setupCSS(); | |
removeAd(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Installation 安裝