MFC Buy Links

Adds a box for direct links to shop's searches

目前為 2020-09-11 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         MFC Buy Links
// @namespace    https://myfigurecollection.net/profile/tharglet
// @version      1.1
// @description  Adds a box for direct links to shop's searches
// @author       Tharglet
// @match        https://myfigurecollection.net/item/*
// @require      http://code.jquery.com/jquery-2.1.3.min.js
// @grant        GM_addStyle
// @grant        GM.getValue
// @grant        GM.setValue
// ==/UserScript==

////////LICENCE////////
//This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/.
//Please credit 'Tharglet' for the original code, and provide a link to my MFC profile: https://myfigurecollection.net/profile/tharglet
///////////////////////

//Polyfill for GM_addStyle for Greasemonkey...
if(typeof GM_addStyle == 'undefined') {
    GM_addStyle = (aCss) => {
        'use strict';
        let head = document.getElementsByTagName('head')[0];
        if (head) {
            let style = document.createElement('style');
            style.setAttribute('type', 'text/css');
            style.textContent = aCss;
            head.appendChild(style);
            return style;
        }
        return null;
    };
}

GM_addStyle(`
h4 {
font-style: italic;
padding-bottom: 5px;
padding-top: 10px;
}

.cols {
column-count: 3;
}

.cols .form-field {
break-inside: avoid-column;
}

.form .form-field--nomargin {
margin-top: 0;
}

.buylinks__search-button {
margin-right: 5px;
margin-bottom: 5px;
}

#buylinks__jan-search {
margin-top: 10px;
}

#buylinks__jan-search li {
padding-bottom: 10px;
}

.hidden {
display: none;
}
`);

(async () => {
    'use strict';

    //The added div containing the buy links
    var buyBox = `<section><h2>Buy!<nav class="actions"><a href="#" id="buylinks-save" title="Save selected checkboxes"><span class="tiny-icon-only icon-archive"></span></a></h2>
<div class='form'>
<h3>Keyword search</h3>
<div id='buylinks__keyword-search' class='form-field'></div>
<div>
<h4>Search in English</h4>
<ul id='buylinks__search-buttons-en'></ul>
<h4>Search in Japanese</h4>
<ul id='buylinks__search-buttons-ja'></ul>
<p id='buylinks__keyword-search-error' class='action object-is-alerted hidden'>No data found for keywords selected - please select more and try again</p>
</div>
<h3>JAN search</h3>
<ul id='buylinks__jan-search'></ul></div>
</section>`;
    //Stick above box into the DOM
    $("#wide .wrapper section:first").after(buyBox);

    //References the setting name for which checkboxes the user wants to use as default
    const SAVE_CHECKBOX_PREFERENCE = "buylinks-checkboxes-default";

    //The Big Magic! Store list and its abilities.
    //For the section name, keep to letters, as this is used in element names, and other characters MAY break it.
    //display_name: Name displayed next to the checkbox
    //url: the base URL for the search
    //JAN: The url part used for JAN searching
    //keyword_en: The url param used for searching in English
    //keyword_ja: The url param used for searching in Japanese
    //bonus_params: Other URL params to append to a search (e.g. for setting language, category, anything the site doesn't do by default).
    var shops = {
        "amiami": {
            "display_name": "AmiAmi",
            "url": "https://www.amiami.com/eng/search/list/",
            "JAN" : "?s_keywords",
            "keyword_en" : "s_keywords"
        },
        "mandarakeint": {
            "display_name": "Mandarake",
            "url": "https://order.mandarake.co.jp/order/listPage/serchKeyWord",
            "keyword_en" : "keyword",
            "keyword_ja" : "keyword",
            "bonus_params": "&lang=en"
        },
        "surujp": {
            "display_name": "Suruga-ya.jp",
            "url": "https://www.suruga-ya.jp/search",
            "JAN": "?gtin",
            "keyword_ja" : "search_word"
        },
        "surucom": {
            "display_name": "Suruga-ya.com",
            "url": "https://www.suruga-ya.com/en/products",
            "keyword_en" : "keyword"
        },
        "milestone": {
            "display_name": "Milestone",
            "url": "https://b2b.mile-stone.jp/en/search/0/",
            "JAN": "jan",
            "bonus_params":"/"
        },
        "amazonjp": {
            "display_name": "Amazon JP",
            "url": "https://www.amazon.co.jp/s",
            "keyword_ja": "k"
        }
    }

    var searchParams = {
        origin: {
            label: "Origin"
        },
        character: {
            label: "Character"
        },
        manufacturer: {
            label: "Manufacturer"
        }
    }

    var defaultCheckboxes = ["character", "manufacturer"];
    var savedCheckboxes = await GM.getValue(SAVE_CHECKBOX_PREFERENCE, null);
    if(savedCheckboxes) {
        defaultCheckboxes = JSON.parse(savedCheckboxes);
    }

    const setSearchParams = (searchParams, field, en, ja) => {
        searchParams[field].en = en;
        searchParams[field].ja = ja;
    };

    const performSearch = (shop, lang) => {
        $("#buylinks__keyword-search-error").hide();
        let searchUrl = shops[shop].url + "?" + shops[shop]["keyword_" + lang] + "=";
        let searchFields = $("#buylinks__keyword-search input[type=checkbox]:checked");
        let searchTerms = [];
        searchFields.each((idx, searchField) => {
            let searchTerm = searchParams[$(searchField).attr("data-field")];
            if(searchTerm && searchTerm[lang]) {
                searchTerms.push(encodeURIComponent(searchTerm[lang]));
            }
        });
        if(searchTerms.length > 0) {
            searchUrl += searchTerms.join("%20");
            if(shops[shop].bonus_params) {
                searchUrl += shops[shop].bonus_params;
            }
            window.open(searchUrl, '_blank');
        } else {
            $("#buylinks__keyword-search-error").show();
        }
    };
    GM.getValue(SAVE_CHECKBOX_PREFERENCE, null).then(() => {
        $().ready(function() {
            //Save button event
            $("#buylinks-save").click((evt) => {
                evt.preventDefault();
                let newCheckboxSet = [];
                let searchFields = $("#buylinks__keyword-search input[type=checkbox]:checked");
                searchFields.each((idx, searchField) => {
                    let searchTerm = $(searchField).attr("data-field");
                    newCheckboxSet.push(searchTerm);
                });
                GM.setValue(SAVE_CHECKBOX_PREFERENCE, JSON.stringify(newCheckboxSet));
            });
            //Set JAN
            let JAN = $("meta[itemprop='productID']").attr("content");
            if(JAN) {
                JAN = JAN.substring(4);
            } else {
                $("#buylinks__jan-search").append("<em>No JAN for this item</em>");
            }
            //Set up text search data
            let origin = $(".form-label:contains('Origin')");
            if(origin) {
                let originSpan = origin.parent().find("span");
                setSearchParams(searchParams, "origin", originSpan.text(), originSpan.attr("switch"));
            }
            let char = $(".form-label:contains('Character')");
            if(char) {
                let charSpan = char.parent().find("span").first();
                setSearchParams(searchParams, "character", charSpan.text(), charSpan.attr("switch"));
            }
            let mfr = $("small:contains(As Manufacturer)").first();
            if(mfr) {
                let mfrSpan = mfr.parent().find("span").first();
                setSearchParams(searchParams, "manufacturer", mfrSpan.text(), mfrSpan.attr("switch"));
            }
            //Set up checkboxes
            for(let searchParam in searchParams) {
                let thisSearchParam = searchParams[searchParam];
                let isChecked = "";
                if(defaultCheckboxes.includes(searchParam)) {
                    isChecked = "checked='checked'";
                }
                $("#buylinks__keyword-search").append(`<div class='form-input'><input id='buylinks-search-${searchParam}' data-field="${searchParam}" type='checkbox' ${isChecked}/><label for='buylinks-search-${searchParam}'>${thisSearchParam.label}</label></div>`);
            }
            //Set up shop-related fields
            for(let shop in shops) {
                let thisShop = shops[shop];
                //Add JAN link
                if(thisShop.JAN !== undefined && JAN !== undefined) {
                    $("#buylinks__jan-search").append(`<li><a target="_blank" href="${thisShop.url}${thisShop.JAN}=${JAN}${thisShop.bonus_params ? thisShop.bonus_params : ""}">${thisShop.display_name}</a></li>`);
                }
                if(thisShop.keyword_en) {
                    $("#buylinks__search-buttons-en").append(`<button id='buylinks__search-button-${shop}-en' class='buylinks__search-button'>${thisShop.display_name}</button>`);
                    $(`#buylinks__search-button-${shop}-en`).click(() => {
                        performSearch(shop, "en");
                    });
                }
                if(thisShop.keyword_ja) {
                    $("#buylinks__search-buttons-ja").append(`<button id='buylinks__search-button-${shop}-ja' class='buylinks__search-button'>${thisShop.display_name}</button>`);
                    $(`#buylinks__search-button-${shop}-ja`).click(() => {
                        performSearch(shop, "ja");
                    });
                }
            }
        });
    });
})();