- // ==UserScript==
- // @name Don't Seizi "lazy"
- // @namespace https://github.com/segabito/
- // @version 0.4.0
- // @description ランキング内の「社会・政治・時事」の動画を消すだけ
- // @author segabito macmoto
- // @match *://www.nicovideo.jp/ranking*
- // @grant none
- // @run-at document-body
- // @noframes
- // ==/UserScript==
- (function() {
- if (!document.body.classList.contains('MatrixRanking-body')) {
- return;
- }
-
- const css = `
- [data-genre-name="society_politics_news"] {
- visibility: hidden;
- pointer-events: none;
- user-select: none;
- }
- `;
- const addStyle = function(styles, id) {
- const elm = document.createElement('style');
- elm.type = 'text/css';
- if (id) { elm.id = id; }
-
- var text = styles.toString();
- text = document.createTextNode(text);
- elm.appendChild(text);
- document.documentElement.append(elm);
- return elm;
- };
-
- const dateToString = date => {
- if (typeof date === 'string') {
- const origDate = date;
- date = date.replace(/\//g, '-');
- // 時差とか考慮してない
- const m = /^(\d+-\d+-\d+) (\d+):(\d+):(\d+)/.exec(date);
- if (m) {
- date = new Date(m[1]);
- date.setHours(m[2]);
- date.setMinutes(m[3]);
- date.setSeconds(m[4]);
- } else {
- const t = Date.parse(date);
- if (isNaN(t)) {
- return origDate;
- }
- date = new Date(t);
- }
- } else if (typeof date === 'number') {
- date = new Date(date);
- }
- if (!date || isNaN(date.getTime())) {
- return '1970/01/01 00:00:00';
- }
-
- let [yy, mm, dd, h, m, s] = [
- date.getFullYear(),
- date.getMonth() + 1,
- date.getDate(),
- date.getHours(),
- date.getMinutes(),
- date.getSeconds()
- ].map(n => n.toString().padStart(2, '0'));
- return `${yy}/${mm}/${dd} ${h}:${m}:${s}`;
- };
-
- const parseItem = item => {
- const id = item.querySelector('link').textContent.replace(/^.+\//, '');
- let watchId = id;
- const guid = item.querySelector('guid').textContent;
- const desc = new DOMParser().parseFromString(item.querySelector('description').textContent, 'text/html');
- const [min, sec] = desc.querySelector('.nico-info-length').textContent.split(':');
- const dt = guid.match(/,([\d]+-[\d]+-[\d]+):/)[1];
- const tm = desc.querySelector('.nico-info-date').textContent.replace(/[:]/g, ':').match(/([\d]+:[\d]+:[\d]+)/)[0];
- const date = new Date(`${dt} ${tm}`);
- const thumbnail_url = desc.querySelector('.nico-thumbnail img').src;
- const vm = thumbnail_url.match(/(\d+)\.(\d+)/);
- if (vm && /^\d+$/.test(id)) {
- watchId = `so${vm[1]}`;
- }
-
- const result = {
- _format: 'nicorss',
- id: watchId,
- uniq_id: id,
- title: item.querySelector('title').textContent,
- length_seconds: min * 60 + sec * 1,
- thumbnail_url,
- first_retrieve: dateToString(date),
- description: desc.querySelector('.nico-description').textContent
- };
- if (desc.querySelector('.nico-info-total-res')) {
- Object.assign(result, {
- num_res: parseInt(desc.querySelector('.nico-info-total-res').textContent.replace(/,/g, ''), 10),
- mylist_counter: parseInt(desc.querySelector('.nico-info-total-mylist').textContent.replace(/,/g, ''), 10),
- view_counter: parseInt(desc.querySelector('.nico-info-total-view').textContent.replace(/,/g, ''), 10)
- });
- }
- return result;
- };
-
- const load = url => {
- return fetch(url).then(r => r.text()).then(rssText => {
- const xml = new DOMParser().parseFromString(rssText, 'application/xml');
- const items = Array.from(xml.querySelectorAll('item')).map(i => parseItem(i));
- return {
- title: xml.querySelector('title').textContent,
- items
- }
- });
- };
-
- /**
- *
- * @param {string} genre
- * @param {'hour'|'24h'||'week'|'month'|'total'} term
- * @param {string} tag
- * @returns ItemData[]
- */
- const loadRanking = ({genre = 'all', term = 'hour', tag = ''}) => {
- const url = `https://www.nicovideo.jp/ranking/genre/${genre}?term=${term}${tag ? `&tag=${encodeURIComponent(tag)}` : ''}&rss=2.0`;
- return load(url);
- };
-
- const itemPromise = loadRanking({genre: 'society_politics_news'});
- addStyle(css);
-
- const onload = async function() {
- const items = (await itemPromise).items;
- if (!items.length) {
- return;
- }
- const watchIds = items.map(item => item.id);
-
-
- const onItemInview = item => {
- const link = item.querySelector('.Card-link');
- const href = link.href;
- const match = href.match(/\watch\/([a-z0-9]+)/);
- if (match && watchIds.includes(match[1])) {
- item.dataset.genreName = 'society_politics_news';
- return true;
- }
- return false;
- };
-
- const intersectionObserver = new window.IntersectionObserver(entries => {
- entries.filter(entry => entry.isIntersecting).forEach(entry => {
- const item = entry.target;
- intersectionObserver.unobserve(item);
- onItemInview(item);
- });
- });
-
-
- const onUpdate = target => {
- const items = (target || document).querySelectorAll('.RankingBaseItem:not(.is-dsl-watching)');
- if (!items.length) { return; }
- Array.from(items).forEach(item => {
- item.classList.add('is-dsl-watching');
- if (!onItemInview(item)) {
- intersectionObserver.observe(item);
- }
- });
- };
-
- const mutationObserver = new window.MutationObserver(mutations => {
- if (mutations.some(mutation => mutation.addedNodes && mutation.addedNodes.length > 0)) {
- onUpdate(mutations.target);
- }
- });
-
- Array.from(document.querySelectorAll('.RankingMatrixVideosRow')).forEach(container => {
- mutationObserver.observe(container, {childList: true, characterData: false, attributes: false, subtree: false});
- });
-
- onUpdate();
- };
-
- window.addEventListener('DOMContentLoaded', onload);
-
- })();