fc2 show all products

show full list of products in 1 page and sort by id / show full title

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         fc2 show all products
// @namespace    https://github.com/x94fujo6rpg/SomeTampermonkeyScripts
// @version      0.3
// @description  show full list of products in 1 page and sort by id / show full title
// @author       x94fujo6
// @match        https://adult.contents.fc2.com/*
// @grant        none
// ==/UserScript==
/* jshint esversion: 9 */

(function () {
    'use strict';
    let msgid = "fc2_script_message";
    let listener = false;

    window.document.body.onload = () => {
        startScript();
    };

    function dPrint(...any) {
        console.log(`[${msgid}]: `, ...any);
    }

    function startScript() {
        if (document.visibilityState == "visible") {
            if (listener) {
                document.removeEventListener("visibilitychange", startScript);
                //dPrint("remove event listener");
            } else {
                //dPrint("normal start");
            }
            setReload();
            checkLink();
        } else {
            document.addEventListener("visibilitychange", startScript);
            //dPrint("document not visible, set event listener");
            listener = true;
        }
    }

    function setReload() {
        let menu = document.querySelector("[data-menulist]");
        if (!menu) return;
        let links = menu.querySelectorAll("a");
        links.forEach(a => {
            if (a.getAttribute("reload")) return;
            a.onclick = (event) => {
                event.preventDefault();
                document.location.href = a.href;
            };
            a.setAttribute("reload", true);
        });
    }

    function checkLink() {
        let link = document.location.href;
        //dPrint(`link: ${link}`);
        if (link.match(/users\/[^\/]+\/articles\?sort=date&order=desc/)) {
            let regtest = link.match(/page=(\d+)/);
            let page = regtest ? regtest[1] : false;
            if (regtest) page = (page == 1) ? true : false;
            if (!regtest || page) {
                dPrint("listview");
                dPrint(`script start, link: ${link}`);
                sortList();
            }
        } else if (link.match(/article_search.php\?id=\d+/) || link.match(/\/article\/\d+\//)) {
            dPrint("productpage");
            productpage();
        }
    }

    function updateMessage(text = "") {
        document.getElementById(msgid).textContent = text;
        dPrint(text);
    }

    function sortList() {
        let pos = document.querySelector("section.seller_user_articlesList");
        let products;
        let list;
        
        if (!pos) return;

        dPrint("sortList");
        products = [...pos.children];
        list = products.map(div => processDiv(div));

        document.querySelector(".c-pager-101").remove();
        list.sort((a, b) => b.id - a.id);

        products.forEach(e => e.remove());
        list.forEach(data => { pos.appendChild(data.ele); });

        let message = Object.assign(document.createElement("span"), {
            id: msgid,
            textContent: "script start",
            style: `
                    display: inline-block;
                    margin: 0.5rem;
                    color: gold;
                `,
        });
        document.querySelector("div.seller_user_articles_pageHeader").appendChild(message);
        getAllProduct();

        async function getAllProduct() {
            let total = document.querySelector(".seller_user_articles_pageHeaderCount");
            if (!total) return;
            total = total.textContent.match(/\((\d*)\)/)[1];
            total = parseInt(total, 10);

            let max_page = Math.ceil(total / 30);
            if (max_page == 1) {
                updateMessage(`only 1 page, abort`);
            } else {
                let user = document.location.href.match(/users\/([^\/]*)\/articles/)[1];
                let url = `https://adult.contents.fc2.com/users/${user}/articles?sort=date&order=desc&deal=&page=`;
                updateMessage(`max page = ${max_page}, start to retrieve data`);

                for (let page = 2; page <= max_page; page++) {
                    updateMessage(`processing... please wait [page: ${page}, total: ${max_page}]`);
                    await getPage(url, page)
                        .then(async (resolve) => {
                            await resort(resolve, page);
                        })
                        .catch((reject) => {
                            updateMessage(`somthing went wrong...script stopped`);
                            dPrint(reject);
                            return;
                        });
                }
            }
            updateMessage(`done`);

            function getPage(rq_url, page) {
                return new Promise((resolve, reject) => {
                    let rq = new XMLHttpRequest();
                    rq.open("GET", `${rq_url}${page}`);
                    rq.onreadystatechange = function () {
                        if (rq.readyState == 4) {
                            return (rq.status == 200) ? setTimeout(resolve, 500, rq.responseText) : reject(rq.responseText);
                        }
                    };
                    rq.send(null);
                });
            }

            function resort(data) {
                return new Promise((resolve, reject) => {
                    let current = getCurrentProduct();
                    if (!current) return reject(false);

                    data = extractProducts(data);
                    current.push(...data);
                    current.sort((a, b) => b.id - a.id);

                    let pos = document.querySelector("section.seller_user_articlesList");
                    [...pos.children].forEach(e => e.remove());

                    current.forEach(p => pos.appendChild(p.ele));

                    data = null;
                    current = null;
                    return resolve(true);
                });

                function getCurrentProduct() {
                    let pos = document.querySelector("section.seller_user_articlesList");
                    if (pos) {
                        return [...pos.children].map(ele => {
                            return {
                                id: ele.querySelector("a").href.match(/id=(\d*)/)[1],
                                ele: ele.cloneNode(true),
                            };
                        });
                    } else {
                        return false;
                    }
                }

                function extractProducts(domtext) {
                    let parser = new DOMParser();
                    let new_document = parser.parseFromString(domtext, "text/html");
                    let pos = new_document.querySelector("section.seller_user_articlesList");
                    let products = [...pos.children];
                    let list = products.map(div => processDiv(div));
                    parser = null; // release memory
                    new_document = null;
                    return list;
                }
            }
        }
    }

    function processDiv(div) {
        let id = div.querySelector("a").href.match(/id=(\d*)/)[1];
        let box = div.querySelector(".c-cntCard-110-f_indetail");
        let title_ele = div.querySelector(".c-cntCard-110-f_itemName");
        let title_span = convertToSpan(title_ele);
        let id_span = Object.assign(document.createElement("span"), {
            textContent: id,
            style: `font-size: 1.5rem;`,
        });
        let all_link;
        let remove_ele = [
            ".items_article_SmapleVideo",
            "span.c-cntCard-110-f_thumb_type",
            "button",
            "section.c-tooltip-107",
            ".detail-layout",
            ".c-cntCard-110-f_seller",
        ];
        box.insertAdjacentElement("afterbegin", title_span);
        box.insertAdjacentElement("afterbegin", id_span);
        title_ele.remove();

        div.querySelector("img").setAttribute("loading", "lazy");
        remove_ele.forEach(css_selector => {
            removeFromEle(div, css_selector);
        });

        all_link = div.querySelectorAll("a");
        if (all_link) all_link.forEach(a => { a.target = "_blank"; });
        return { id: id, ele: div.cloneNode(true) };

        function removeFromEle(ele, css_selector) {
            let target = ele.querySelector(css_selector);
            if (target) target.remove();
        }

        function convertToSpan(ele) {
            return Object.assign(document.createElement("span"), {
                textContent: ele.textContent,
                className: ele.className,
                style: `
                    overflow: visible;
                    display: inline-block;
                    width: auto;
                `,
            });
        }
    }

    function productpage() {
        let data = document.querySelector("[type='application/ld+json']").textContent;
        data = JSON.parse(data);
        let id = data.productID;
        let title = data.name;
        let pos = document.querySelector(".items_article_headerInfo h3");
        let e = newButton(`Copy [${id} ${title}]`, `${id} ${title}`);
        pos.insertAdjacentElement("afterend", e);
    }

    function newButton(text, copy) {
        let e = document.createElement("a");
        e.style = "color: deeppink; font-size: 1.5rem;";
        e.textContent = text;
        e.onclick = function () {
            navigator.clipboard.writeText(repalceForbiddenChar(copy));
        };
        return e;
    }

    function repalceForbiddenChar(string = "") {
        let forbidden = `<>:"/|?*\\`;
        let replacer = `<>:”/|?*\`;
        for (let index of forbidden) {
            string = string.replaceAll(forbidden[index], replacer[index]);
        }
        return string.trim();
    }
})();