Sleazy Fork is available in English.

filterSuperfluousOnDMM

DMM・FANZAの通販商品一覧からアウトレット、限定版、および BOD/DOD を除去

À partir de 2020-08-28. Voir la dernière version.

/* jshint esversion: 6 */
// ==UserScript==
// @name         filterSuperfluousOnDMM
// @namespace    https://greasyfork.org/ja/users/289387-unagionunagi
// @version      1.1
// @description  DMM・FANZAの通販商品一覧からアウトレット、限定版、および BOD/DOD を除去
// @author       unagiOnUnagi
// @include      /^https?://\w+\.dmm\.co(m|\.jp)/mono/(\w+/)?-/(list|search)/.*/
// @grant        GM_setValue
// @grant        GM_getValue
// @license      GPL-2.0-or-later
// ==/UserScript==

function resolvePropVal(isChecked) {
    // display プロパティ値を決定
    if (isChecked) return 'none';
    return document.URL.includes('/view=text/') ? 'table-row' : 'list-item';
}

function addStyleSheet() {
    // カスタムスタイルシートの作成
    let styleEl = document.createElement('style');
    styleEl.id = 'filtersuperfluousondmm-css';
    document.head.appendChild(styleEl);

    let styleSheet = styleEl.sheet;

    //  .superfluous {display: none} を追加
    let value = resolvePropVal(GM_getValue('checked', true));
    styleSheet.insertRule(`.superfluous {display: ${value};}`, 0);

    // 全作品フィルター時のラベル点滅ルール
    styleSheet.insertRule(
        '.filtersuperfluousondmm-blink { animation: flash 0.6s linear 3; }', 1);
    styleSheet.insertRule(
        '@keyframes flash { 0%,100% { opacity: 1; } 50% { opacity: 0; } }', 2);
}

function toggleFilter(ev) {
    // チェックボックスの状態を見て表示・非表示を切り換え
    let rule = document.getElementById("filtersuperfluousondmm-css").sheet.rules[0];
    let isChecked = ev.target.checked;
    rule.style.display = resolvePropVal(isChecked);
    GM_setValue('checked', isChecked);
}

function createElement(tag, attrs) {
    // Elementの作成
    let elem = document.createElement(tag);
    attrs.forEach(a => elem.setAttribute(a[0], a[1]));
    return elem;
}

function filterSuperflouous(lineup, itemElm, getTitle) {
    // アウトレット、限定版、BOD/DOD を非表示に

    // カスタムスタイルシートの追加
    addStyleSheet();

    // 対象文字列正規表現
    const pattern = [/【(特選)?アウトレット】/,
                     /【(DMM|FANZA|数量)限定】/,
                     /([BD]OD)$/,
                     /アウトレット(BD)?】$/];

    const items = document.evaluate(itemElm, lineup, null,
                                    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    const itemsLength = items.snapshotLength;

    let nof = 0;
    for (let i=0; i < itemsLength; i++) {
        let item = items.snapshotItem(i);
        let title = getTitle(item);

        // パターンにマッチしたらクラスを追加
        if (pattern.some(re => re.test(title))) {
            item.classList.add('superfluous');
            nof++;
        }
    }

    // フィルターチェックボックス
    let lastSpan = document.querySelectorAll(
        '.d-area .list-capt .list-boxseparate div.list-unit');
    if (lastSpan.length) {
        lastSpan = lastSpan[lastSpan.length - 1];

        let filterSpan = createElement(
            'span',
            [['title',
              `アウトレット、限定版、BOD/DOD を非表示にします (このページに ${nof} 個)`],
             ['style', 'margin-left: 10px;']]);
        lastSpan.insertAdjacentElement('afterend', filterSpan);

        let filterCb = createElement('input',
                                     [['type', 'checkbox'],
                                      ['id', 'filtersuperfluousondmm-cb'],
                                      ['name', 'filtersuperfluousondmm-cb']]);
        filterSpan.appendChild(filterCb);

        let filterLabel = createElement('label',
                                        [['for', 'filtersuperfluousondmm-cb']]);
        filterSpan.appendChild(filterLabel);

        // ページ内全作品が該当したとき
        let addLabel = '';
        if (nof == itemsLength) {
            addLabel = '(全作品が該当)';
            filterLabel.classList.add('filtersuperfluousondmm-blink');
        }

        filterLabel.innerText = `フィルター${addLabel}`;

        filterCb.checked = GM_getValue('checked', true);
        filterCb.addEventListener('change', toggleFilter);

    } else {
        console.log('Breadcrumb list not found');
    }
}

(function() {
    'use strict';
    let lineup;
    if ((lineup = document.getElementById('list'))) {
        // 画像形式表示
        filterSuperflouous(
            lineup, 'li',
            (item) => item.querySelector('div p.tmb a span img').getAttribute('alt'));
    } else if ((lineup = document.querySelector('table[summary=商品一覧] tbody'))) {
        // テキスト形式表示
        filterSuperflouous(
            lineup, 'tr[td]',
            (item) => item.querySelector('td p.ttl a').text.trim());
    }

})();