您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
为csp的素材商店网页-我的下载页面 增加“按素材类型排序”和按素材类型筛选快捷按钮
当前为
- // ==UserScript==
- // @name ecsa
- // @namespace boni
- // @version 1.07
- // @description 为csp的素材商店网页-我的下载页面 增加“按素材类型排序”和按素材类型筛选快捷按钮
- // @match https://assets.clip-studio.com/*/download-list
- // @match https://assets.clip-studio.com/*/download-list?*
- // @match https://assets.clip-studio.com/*/starred*
- // @grant none
- // @license GPL-3.0-only
- // @description:zh-CN 为csp的素材商店网页-我的下载页面 增加“按素材类型排序”和按素材类型筛选快捷按钮
- // @description:en Support sorting and filtering on Clip Studio Assets favorites and downloads page
- // @description:ja-JP Clip Studio Assetsのマイリストとマイダウンロードページでのソートとフィルタリングをサポート
- // @description:de-DE Für die Favoriten und Downloads Seite von Clip Studio Assets Unterstützung für das Sortieren und Filtern hinzufügen
- // @description:es-ES Agregar soporte para ordenar y filtrar en la página de favoritos y descargas de Clip Studio Assets
- // @description:fr-FR Ajouter la prise en charge du tri et du filtrage sur la page des favoris et des téléchargements de Clip Studio Assets
- // @description:ko-KR Clip Studio Assets의 즐겨찾기 및 다운로드 페이지에서 정렬 및 필터링 지원
- // ==/UserScript==
- (function() {
- 'use strict';
- const getSortBtnLabel = () => {
- // Get the current URL
- const currentURL = window.location.href;
- const withoutProtocol = currentURL.replace("https://", "");
- // Split by "/"
- const urlSegments = withoutProtocol.split("/");
- // Get the first part
- const lang = urlSegments[1];
- const translations = {
- "zh-tw": {
- category: "按素材类别排序",
- time: "按下载时间排序",
- },
- "ja-jp": {
- category: "素材タイプ別に並べ替え",
- time: "ダウンロード時間別に並べ替え",
- },
- "en-us": {
- category: "Sort by Category",
- time: "Sort by Download Time"
- },
- "de-de": {
- category: "Nach Kategorie sortieren",
- time: "Nach Download-Zeit sortieren"
- },
- "es-es": {
- category: "Ordenar por categoría",
- time: "Ordenar por tiempo de descarga"
- },
- "fr-fr": {
- category: "Trier par catégorie",
- time: "Trier par heure de téléchargement"
- },
- "ko-kr": {
- category: "카테고리별 정렬",
- time: "다운로드 시간별 정렬"
- }
- };
- return translations[lang]
- }
- // text for "all" option
- const getAllText = () => {
- if (window.location.href.includes("starred")) {
- // Find the first <a> element inside the .btn-group.selectFilter
- const selectFilter = document.querySelector('.btn-group.selectFilter');
- if (selectFilter) {
- const firstOption = selectFilter.querySelector('a');
- if (firstOption) {
- const firstOptionText = firstOption.textContent.trim();
- return firstOptionText
- }
- }
- } else {
- // Find the <ul> element inside the .dropdown.selectFilter
- const dropdown = document.querySelector('.dropdown.selectFilter');
- if (dropdown) {
- const ul = dropdown.querySelector('ul.dropdown-menu');
- if (ul) {
- const firstOption = ul.querySelector('li:first-child a');
- if (firstOption) {
- const firstOptionText = firstOption.textContent.trim();
- return firstOptionText
- }
- }
- }
- }
- }
- // Define liElementsByType in the global scope
- const liElementsByType = {};
- let container = document.querySelector("ul.layput__cardPanel");
- let sortAsset = false;
- let orig = container.innerHTML;
- let types = []
- let allText = getAllText()
- let sortBtnText = getSortBtnLabel()
- let currentLocation = ''
- if (window.location.href.includes("starred")) {
- currentLocation = 's'
- } else {
- currentLocation = 'd'
- }
- const toggleSort = (sort) => {
- // Set a value in localStorage
- localStorage.setItem( currentLocation +'sorted', sort === true ? 1 : 0);
- sortAsset = sort
- const sortButton = document.getElementById("sortButton");
- sortButton.textContent = sortAsset ? sortBtnText.time : sortBtnText.category;
- // sortButton.disabled = type !== allText;
- if (sort) {
- // Clear the existing content on the page
- container.innerHTML = '';
- // Sort the <li> elements by type value (custom sorting logic)
- const sortedTypes = Object.keys(liElementsByType).sort();
- // Reconstruct the sorted list of <li> elements
- const sortedLiElements = [];
- sortedTypes.forEach((type) => {
- sortedLiElements.push(...liElementsByType[type]);
- });
- // Append the sorted <li> elements back to the container
- sortedLiElements.forEach((li) => {
- container.appendChild(li);
- });
- } else {
- container.innerHTML = orig;
- }
- }
- // Function to sort the <li> elements by type
- const preprocessAssets = () => {
- const liElements = document.querySelectorAll("li.materialCard");
- liElements.forEach((li) => {
- const materialTypeLink = li.querySelector("a[href*='/search?type=']");
- if (materialTypeLink) {
- const type = materialTypeLink.textContent.trim(); // Get the text content of the <a> tag
- if (!types.includes(type)) {
- types.push(type)
- }
- if (type) {
- if (!liElementsByType[type]) {
- liElementsByType[type] = [];
- }
- liElementsByType[type].push(li);
- }
- }
- });
- // Find the existing button element
- const existingButton = document.querySelector(".btn.btn-default.operationButton.favoriteButton");
- if (existingButton) {
- // Create a new button element
- const sortButton = document.createElement("button");
- sortButton.type = "button";
- sortButton.className = "btn btn-primary ";
- sortButton.id = "sortButton";
- sortButton.textContent = sortBtnText.category;
- sortButton.style.marginLeft = '10px'
- // Add an event listener to the new button if needed
- sortButton.addEventListener("click", function() {
- // Handle button click event
- sortAsset = !sortAsset
- sortButton.textContent = sortAsset ? sortBtnText.time : sortBtnText.category;
- toggleSort(sortAsset)
- });
- // Insert the new button after the existing button
- existingButton.parentNode.insertBefore(sortButton, existingButton.nextSibling);
- const options = [...types];
- options.unshift(allText)
- const dropdown = createDropdown(options);
- existingButton.parentNode.insertBefore(dropdown, sortButton.nextSibling);
- }
- const filterBtn = document.getElementById("filterButton");
- if(filterBtn.textContent === getAllText()) {
- // Read a value from localStorage
- const sorted = localStorage.getItem(currentLocation + 'sorted');
- // Check if the value exists
- if (sorted == 1) {
- // Use the value
- toggleSort(true)
- } else {
- }
- }
- };
- // Create a function to generate the dropdown HTML
- function createDropdown(types) {
- const dropdown = document.createElement("div");
- dropdown.className = "dropdown selectFilter ";
- dropdown.style.display = 'inline-block'
- dropdown.style.marginLeft = '10px'
- dropdown.style.marginTop = '0px'
- const button = document.createElement("button");
- button.className = "btn btn-default dropdown-toggle filterButton";
- button.id = "filterButton"
- button.type = "button";
- button.setAttribute("data-toggle", "dropdown");
- button.setAttribute("aria-haspopup", "true");
- button.setAttribute("aria-expanded", "true");
- const filterOption = localStorage.getItem(currentLocation + 'filtered');
- // set sort button text but only allow change when 'all' option is selected
- const sorted = localStorage.getItem(currentLocation +'sorted');
- sortButton.textContent = sorted ? sortBtnText.time : sortBtnText.category;
- // toggleSort()
- if( types.includes(filterOption) && filterOption !== getAllText() ) {
- const sortButton = document.getElementById("sortButton");
- // sortButton.textContent = sorted ? sortBtnText.time : sortBtnText.category;
- sortButton.disabled = true
- button.textContent =filterOption
- container.innerHTML = '';
- liElementsByType[filterOption].forEach((li) => {
- container.appendChild(li);
- });
- } else {
- button.textContent = types[0]; // Set the default text
- }
- button.style.borderRadius = '0px'
- button.style.textAlign = 'left'
- const caret = document.createElement("span");
- caret.className = "caret";
- caret.style.position = "absolute";
- if (window.location.href.includes("starred")) {
- // The URL contains "starred"
- caret.style.top = "15px"
- } else {
- // The URL does not contain "starred"
- }
- caret.style.right = "10px";
- const ul = document.createElement("ul");
- ul.className = "dropdown-menu";
- // Create options from the 'types' array
- types.forEach((type) => {
- const li = document.createElement("li");
- const a = document.createElement("a");
- a.textContent = type;
- li.appendChild(a);
- ul.appendChild(li);
- li.addEventListener("click", function(event) {
- localStorage.setItem(currentLocation + 'filtered', type);
- // Prevent the default behavior of following the link (if it's an anchor)
- event.preventDefault();
- container.innerHTML = 'xs';
- // Enable or disable the new button based on the selected option
- const sortButton = document.getElementById("sortButton");
- sortButton.disabled = type !== allText;
- button.firstChild.textContent = type;
- const h4Element = document.querySelector("h4.text-right");
- if (type !== allText) {
- liElementsByType[type].forEach((li) => {
- container.appendChild(li);
- });
- localStorage.setItem(currentLocation +'filtered', type);
- } else {
- container.innerHTML = orig;
- const sorted = localStorage.getItem(currentLocation + 'sorted');
- // Check if the value exists
- if (sorted == 1) {
- // Use the value
- toggleSort(true)
- } else {
- }
- }
- });
- });
- // Append elements to the dropdown
- button.appendChild(caret);
- dropdown.appendChild(button);
- dropdown.appendChild(ul);
- return dropdown;
- }
- // Wait for the page to fully load before executing the sorting function
- window.onload = function() {
- preprocessAssets();
- };
- })();