/* jshint esversion: 6 */
// ==UserScript==
// @name maskNGwordsOnFANZA (experimental)
// @namespace https://greasyfork.org/ja/users/289387-unagionunagi
// @version 0.1
// @description 検索文字列からFANZA独自のNGワードを伏せ字化
// @author unagiOnUnagi
// @match *://www.dmm.co.jp/*
// @grant GM_setValue
// @grant GM_getValue
// @license GPL-2.0-or-later
// @run-at document-start
// ==/UserScript==
function _mask(phrase) {
const _NGwords = [
['犯され', '犯●れ'],
[/犯す([\s\d])/g, '犯●$1'],
['犯す', '●す'],
[/強(制|姦)/g, '強●'],
['ロリータ', 'ロ●ータ'],
['レイプ', 'レ●プ'],
['陵辱', '陵●'],
['凌辱', '凌●'],
['夜這い', '夜●い'],
['酔っ払', '●っ払'],
['酔っぱら', '●っぱら'],
['痴漢', '痴●'],
['輪姦', '輪●'],
['催眠', '催●'],
['泥酔', '泥●'],
['奴隷', '奴●'],
['ショタ', 'シ●タ'],
['PTA', 'P●A'],
['無修正', '無●正'],
['昏睡', '昏●'],
['折檻', '折●'],
];
const origin = phrase;
for (let [ng, mask] of _NGwords) {
phrase = phrase.replaceAll(ng, mask);
}
if (origin != phrase) console.log(`mask NGwords:\n${origin} =>\n${phrase}`);
return phrase;
}
function maskFromSearchStr(matched) {
// console.log(matched);
let searchstr = matched[1];
let decoded = decodeURIComponent(searchstr);
let masked = _mask(decoded);
let encoded = encodeURIComponent(masked);
let maskedURL = matched[0].replace(searchstr, encoded);
window.location.href = maskedURL;
}
function createElement(tag, attrs) {
// Elementの作成
let elem = document.createElement(tag);
for (let [a, v] of attrs) elem.setAttribute(a, v);
return elem;
}
function control2Mask() {
let searchBox = document.querySelector('#naviapi-search-text');
if (!searchBox) return;
let mu = document.querySelector('#mu,.d-area:last-child');
if (!mu) return;
let maskSpan = createElement(
'span',
[['title',
'検索文字列にFANZA検閲ワードがあればFANZA形式で伏せ字化します'],
['style', 'margin-left: 10px;']]);
mu.appendChild(maskSpan);
let maskCb = createElement('input',
[['type', 'checkbox'],
['id', 'mask-ngwords-cb'],
['name', 'mask-ngwords-cb']]);
maskSpan.appendChild(maskCb);
let maskLabel = createElement('label',
[['for', 'mask-ngwords-cb']]);
maskLabel.innerText = '検索文字列からNGワードを伏せ字化';
maskSpan.appendChild(maskLabel);
maskCb.checked = GM_getValue('checked', true);
maskCb.addEventListener('change', (ev) => {
let isChecked = ev.target.checked;
GM_setValue('checked', isChecked);
});
searchBox.addEventListener('paste', (ev) => {
if (GM_getValue('checked', true)) {
let phrase = ev.clipboardData.getData('text');
ev.preventDefault();
searchBox.value = _mask(phrase);
}
});
searchBox.addEventListener('compositionend', (ev) => {
if (GM_getValue('checked', true)) {
searchBox.value = _mask(searchBox.value);
}
});
}
(function() {
'use strict';
if (window.frameElement) return;
let matched = document.referrer.indexOf('://www.dmm.co.jp/') < 0 && document.URL.match(/.+\/searchstr=(.+?)\//);
if (matched && GM_getValue('checked', false)) {
maskFromSearchStr(matched);
}
window.addEventListener('load', control2Mask);
})();