Wallhaven壁纸一键下载加标签屏蔽

Wallhaven壁纸一键下载,标签屏蔽

// ==UserScript==
// @name         Wallhaven壁纸一键下载加标签屏蔽
// @namespace    http://tampermonkey.net/
// @version      0.7
// @description  Wallhaven壁纸一键下载,标签屏蔽
// @author       乃木流架
// @match        https://wallhaven.cc/*
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAADKElEQVR4nO2YTWgTQRTHt6CCgkW9iJ8XD5aePHhQBKvepb16sr30KnjwIMhs/MCIgopUiBYPVqrMbEmatmmy29T6QRpt0522gQoqoiLag1+tdWe32TzZTWtTmsY2nexa2D88CNl9s//fzNuZnREET548efLkyZMnT44LEK4GRM4CwmFAmIKIxwGRb4BwI8eHtO0EkRBAeAIQ7uXWrkjOASIZEAnMC0Qwb/Nf5xqfA4Dw4AamDNUyhd7TFKoyWf2syWqWKRQWi9x1ddxoffJ+gXHRbj8LCO/jB2D1vN047rJg7P9wep2mqI1MVr/km/NX1i4prHvNG10LzYv2c0a5mbfNWmVj90zOPIsP79UUdaxQ7y4HIOsPFQQw/e0KXwCR/JwZ2t1ajB7TFPqjWIksNcxrHQUBppt7skwePsUPAOGQ3bg/GNBk+p2HeSsMqR/AJy0EePDUfk90efgEJwCpCkTyQQ8PfORlfjb09heQaYpC9nIQ4LwE2asdoHenci+7QqcYTlZzgdBjqUu8zS9plFqfTa54RoJoeovdGw4aP3ySQE09AaaoYPqDJiDyCFDbgZIANFltcLrna+oJHKmX7N+ZQE/+O9JUAgANuVE+bLaMSCJ/hf5dygi8chNAD7+cN0uVAjDhJgCLDq0YYHJVAzCFvl7VJcQU2ucmgEH68z/0ppYPIFPkJkDmbt40ivCdZQMYcmq/mwDmlZC1PwiBTzoklCIAqLA3K27Uf1vCAJ90VFipWIwedwXgfrxB4CVNViOOAshqs8BT0DmymcnqGyfMawqlkEisF3iLRUeqmELfldm8OiWntgvl0q/uwW16eOBTWWo+mHwLz8c2CuUW+PCZzO0Y6F2DfIx3DIB5K2LN86fLbn4G4KC9sPgkMG9G7H2sHkqCHkkBk2eMxdSoFh/dY90/2TOylcm0N2dYtcGNYBKmW/rAvN45t1D5cI0zACi4qfCZTv4BVe4Y5m/OhYe7/plzEe9wCODxmuLmiVE4jxjF81oqnQEQoKK4EZwuDIDTRfMCgbWOANhmRBJf5GhwHJBUVxhAqrOvF87rd8y8J0+ehP9OfwDBJGLFiOaZxAAAAABJRU5ErkJggg==
// @run-at       document-end
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @grant        GM_listValues
// @license      GPL-3.0 License
// ==/UserScript==


(function () {
  // "use strict";

  GM_addStyle(`
      header .bantag:hover {
      background-color: #5a0a0a;
    }
  `)

  const static = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAADKElEQVR4nO2YTWgTQRTHt6CCgkW9iJ8XD5aePHhQBKvepb16sr30KnjwIMhs/MCIgopUiBYPVqrMbEmatmmy29T6QRpt0522gQoqoiLag1+tdWe32TzZTWtTmsY2nexa2D88CNl9s//fzNuZnREET548efLkyZMnT44LEK4GRM4CwmFAmIKIxwGRb4BwI8eHtO0EkRBAeAIQ7uXWrkjOASIZEAnMC0Qwb/Nf5xqfA4Dw4AamDNUyhd7TFKoyWf2syWqWKRQWi9x1ddxoffJ+gXHRbj8LCO/jB2D1vN047rJg7P9wep2mqI1MVr/km/NX1i4prHvNG10LzYv2c0a5mbfNWmVj90zOPIsP79UUdaxQ7y4HIOsPFQQw/e0KXwCR/JwZ2t1ajB7TFPqjWIksNcxrHQUBppt7skwePsUPAOGQ3bg/GNBk+p2HeSsMqR/AJy0EePDUfk90efgEJwCpCkTyQQ8PfORlfjb09heQaYpC9nIQ4LwE2asdoHenci+7QqcYTlZzgdBjqUu8zS9plFqfTa54RoJoeovdGw4aP3ySQE09AaaoYPqDJiDyCFDbgZIANFltcLrna+oJHKmX7N+ZQE/+O9JUAgANuVE+bLaMSCJ/hf5dygi8chNAD7+cN0uVAjDhJgCLDq0YYHJVAzCFvl7VJcQU2ucmgEH68z/0ppYPIFPkJkDmbt40ivCdZQMYcmq/mwDmlZC1PwiBTzoklCIAqLA3K27Uf1vCAJ90VFipWIwedwXgfrxB4CVNViOOAshqs8BT0DmymcnqGyfMawqlkEisF3iLRUeqmELfldm8OiWntgvl0q/uwW16eOBTWWo+mHwLz8c2CuUW+PCZzO0Y6F2DfIx3DIB5K2LN86fLbn4G4KC9sPgkMG9G7H2sHkqCHkkBk2eMxdSoFh/dY90/2TOylcm0N2dYtcGNYBKmW/rAvN45t1D5cI0zACi4qfCZTv4BVe4Y5m/OhYe7/plzEe9wCODxmuLmiVE4jxjF81oqnQEQoKK4EZwuDIDTRfMCgbWOANhmRBJf5GhwHJBUVxhAqrOvF87rd8y8J0+ehP9OfwDBJGLFiOaZxAAAAABJRU5ErkJggg==`;

  const animate = `https://i.postimg.cc/13Vdn4Cb/save.gif`;

  const tagBlacklist = 'https://wallhaven.cc/settings/browsing#blacklist'

  function log(...args) {
    const name = "WLS";
    const logPrefix = [
      "%c" + name,
      `background:#ff80ab;border-radius: 0.5em;color: white;font-weight: bold;padding: 2px 0.5em`,
    ];
    console.log(...logPrefix, ...args);
  }

  function vueInject() {
    let script = document.createElement("script");
    script.setAttribute("type", "text/javascript");
    // script.src = "https://unpkg.com/vue@3/dist/vue.global.js";
    script.src = "https://unpkg.com/vue@3.2.36/dist/vue.global.prod.js";
    document.documentElement.appendChild(script);

    let link = document.createElement("link");
    link.setAttribute("rel", "stylesheet");
    link.href =
      "https://gcore.jsdelivr.net/gh/NogiRuka/images@main/script/Wallhaven%20Like%20%26%20Save/save.css";
    document.documentElement.appendChild(link);
  }

  // https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=835&page=1#pid4661
  Element.prototype.matches = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.mozMatchesSelector;
  function getElement(parent, selector, timeout = 0) {
    return new Promise(resolve => {
      let result = parent.querySelector(selector);
      if (result) return resolve(result);
      let timer;
      const mutationObserver = window.MutationObserver || window.WebkitMutationObserver || window.MozMutationObserver;
      if (mutationObserver) {
        const observer = new mutationObserver(mutations => {
          for (let mutation of mutations) {
            for (let addedNode of mutation.addedNodes) {
              if (addedNode instanceof Element) {
                result = addedNode.matches(selector) ? addedNode : addedNode.querySelector(selector);
                if (result) {
                  observer.disconnect();
                  timer && clearTimeout(timer);
                  return resolve(result);
                }
              }
            }
          }
        });
        observer.observe(parent, {
          childList: true,
          subtree: true
        });
        if (timeout > 0) {
          timer = setTimeout(() => {
            observer.disconnect();
            return resolve(null);
          }, timeout);
        }
      } else {
        const listener = e => {
          if (e.target instanceof Element) {
            result = e.target.matches(selector) ? e.target : e.target.querySelector(selector);
            if (result) {
              parent.removeEventListener('DOMNodeInserted', listener, true);
              timer && clearTimeout(timer);
              return resolve(result);
            }
          }
        };
        parent.addEventListener('DOMNodeInserted', listener, true);
        if (timeout > 0) {
          timer = setTimeout(() => {
            parent.removeEventListener('DOMNodeInserted', listener, true);
            return resolve(null);
          }, timeout);
        }
      }
    });
  }
  /**
   * 调用示例
    function example1() {
      getElement(document, '#test').then(element => {
        //...
      });
    }
   * 推荐
    async function example2() {
      const element = await getElement(document, '#test');
      //...
    }
   */

  function banInit() {
    let ban = document.createElement("li");
    ban.innerHTML = `<a class="bantag" href="${tagBlacklist}" style="color: #a3a3a3" one-link-mark="yes"><i class="far fa-ban "></i><span>Bantag</span></a>`

    return ban
  }
  
  function tagsHandle() {
    const tags = document.querySelectorAll('#tags a[rel="tag"]');

    // log('tags---->', tags)

    // 处理标签
    tags.forEach(t => {

      var tagName = t.innerText;

      let confirmStr = '你确定要把 <strong style="color:#ff80ab">' + t.innerText + '</strong> 标签\n加入屏蔽名单吗?'

      let banIcon = document.createElement("a");
      banIcon.setAttribute("class", 'jsAnchor tag-rm tag-ban')
      banIcon.setAttribute("original-title", 'Ban tag')
      banIcon.innerHTML = `<i class="fal fa-ban"></i>`

      t.insertAdjacentElement('beforebegin', banIcon);

      // log(t);

      banIcon.addEventListener("click", (e) => {
        log("banIcon clicked---->", e.target);

        Swal.fire({
          title: confirmStr,
          icon: "warning",
          showCancelButton: true,
          confirmButtonColor: "#3085d6",
          cancelButtonColor: "#d33",
          confirmButtonText: "别废话",
          cancelButtonText: "手滑了",
          reverseButtons: true
        }).then((result) => {
          if (result.isConfirmed) {

            // log(GM_getValue('storedTagsArr'))
            // GM_setValue('storedTagsArr', '[]')

            let storedTagsArr = JSON.parse(GM_getValue('storedTagsArr') === undefined ? '[]' : GM_getValue('storedTagsArr'))

            if (!storedTagsArr.includes(tagName)) {
              storedTagsArr.push(tagName);
            }

            GM_setValue('storedTagsArr', JSON.stringify(storedTagsArr))
            log('storedTagsArr---->', storedTagsArr)

            const Toast = Swal.mixin({
              html: '<p style="font-weight: bold;">屏蔽名单:</p>' + GM_getValue('storedTagsArr') + '<p style="font-weight: bold;">屏蔽名单历史:</p>' + GM_getValue('storedTagsArrLast'),
              toast: true,
              position: "top-end",
              showConfirmButton: false,
              timer: 3000,
              timerProgressBar: true,
              didOpen: (toast) => {
                toast.onmouseenter = Swal.stopTimer;
                toast.onmouseleave = Swal.resumeTimer;
              }
            });
            Toast.fire({
              icon: "success",
              title: "<h1 style='font-size: large;'>加入成功</h1>"
            });
          }
        });

      })

      t.addEventListener("mouseover", function (e) {
        log('Tag---->', e.target.innerText);

      });
      
      // 添加鼠标移出事件处理程序
      t.addEventListener("mouseout", function () {

      });
    })

  }

  async function banAdd1(ban) {
    const startpageMenu = await getElement(document, '.startpage-menu');
    // log('startpageMenu---->', startpageMenu)
    startpageMenu.append(ban);

  }
  async function banAdd2(ban) {
    const topmenuPrimary = await getElement(document, '.topmenu-primary');
    // log('topmenuPrimary---->', topmenuPrimary)
    topmenuPrimary.append(ban);

  }
  async function tagBlacklistHandle() {

    let script1 = document.createElement("script");
    script1.setAttribute("type", "text/javascript");
    script1.src = "https://cdn.jsdelivr.net/npm/sweetalert2@11";
    document.documentElement.appendChild(script1);

    if (/wallhaven.cc\/settings\/browsing/.test(window.location.href)) {
      
      // 清空屏蔽名单历史
      // GM_setValue('storedTagsArrLast', '[]')
      
      const tagBlacklist = await getElement(document, '#blacklist');
      let storedTagsArr = JSON.parse(GM_getValue('storedTagsArr'))
      let storedTagsArrLast = JSON.parse(GM_getValue('storedTagsArrLast') === undefined ? '[]' : GM_getValue('storedTagsArrLast'))
      let bl = tagBlacklist.innerHTML
      log('原始黑名单---->', bl)
      log('屏蔽名单---->', storedTagsArr)
      log('屏蔽名单历史---->', storedTagsArrLast)
      
      storedTagsArr = storedTagsArr.filter(function (element) {
        return !storedTagsArrLast.includes(element);
      });
      storedTagsArr.forEach(tag => {
        bl = tag + '\n' + bl
      })
      log('处理后黑名单---->', bl)
      tagBlacklist.innerHTML = bl

      // storedTagsArrLast = storedTagsArrLast.concat(storedTagsArr)
      storedTagsArrLast = Array.from(new Set([...storedTagsArrLast, ...storedTagsArr]));

      GM_setValue('storedTagsArrLast', JSON.stringify(storedTagsArrLast))
      GM_setValue('storedTagsArr', '[]')
      log('处理后屏蔽名单历史---->', JSON.parse(GM_getValue('storedTagsArrLast')))
      log('处理后屏蔽名单---->', JSON.parse(GM_getValue('storedTagsArr')))

      setTimeout(() => {
        const Toast = Swal.mixin({
          html: '<p>屏蔽名单已清空,请点击<button class="green button" ><i class="far fa-fw fa-check"></i>Update</button>按钮屏蔽标签</p><p style="font-weight: bold;">屏蔽名单:</p>' + GM_getValue('storedTagsArr') + '<p style="font-weight: bold;">屏蔽名单历史:</p>' + GM_getValue('storedTagsArrLast'),
          toast: true,
          position: "top-end",
          showConfirmButton: false,
          timer: 3000,
          timerProgressBar: true,
          didOpen: (toast) => {
            toast.onmouseenter = Swal.stopTimer;
            toast.onmouseleave = Swal.resumeTimer;
          }
        });
        Toast.fire({
          icon: "success",
          title: "<h1 style='font-size: large;'>屏蔽标签添加成功</h1>"
        });
      }, 1000);
    }
  }
  async function pigAdd() {
    let text = `
        <div id="app" style="position: fixed;bottom: 100px;right: 100px;z-index: 999">
          <img id='save' src='${static}' alt="WLS" style="width: 60px;height: 60px;cursor: pointer;border-radius:50%;background: white;" @click="save"/>
        </div>
      `;
    //图片阴影
    let style = document.createElement("style");
    style.innerHTML = `
        #save:hover {
          box-shadow: 0 0 10px #ff80ab;
        }
        .tag > .tag-ban{
          font-color: white;
          right: 1.5em
        }
        .tag>.tag-rm+.tagname {
          padding-right: 3.5em;
        }   
      `;

    document.head.append(style);
    // 添加小猪图标
    let el = document.createElement("div");
    el.innerHTML = text;
    
    const element = await getElement(document, 'body');
    element.append(el);
  }

  log("[Wallhaven壁纸一键下载加标签屏蔽] userscript is running...");

  vueInject();

  banAdd1(banInit())
  banAdd2(banInit())
  pigAdd()
  tagBlacklistHandle()

  window.onload = () => {
    tagsHandle()

    const { createApp } = Vue;
    createApp({
      data() {
        return {
          message: "Hello Vue!",
          // 🥚彩蛋
          emoticons: ["⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄", "(*/ω\*)", "(▼ヘ▼#)", "(ฅωฅ*)", "(๑′ᴗ‵๑)I Lᵒᵛᵉᵧₒᵤ❤", "(•ॢ◡-ॢ)-♡", "(`⌒´メ)", "\(^▽^)/", "T^T", "༼༎ຶᴗ༎ຶ༽", "(ಥ﹏ಥ)", "٩(๑❛ᴗ❛๑)۶", "(~ ̄▽ ̄)~ ", "(◕ᴗ◕✿)", "✧*。٩(ˊᗜˋ*)و✧*。", "(o°ω°o)", "(〃'▽'〃)", "ー=≡Σ( ε¦) 0", "(´・ω・)ノ(._.`)", "(ง •_•)ง,加油", "\(>0<)/ 加油", "Hi~ o(* ̄▽ ̄*)ブ", "|。•ω•)っ◆ 我喜欢你♪", "(〃 ̄ω ̄〃)ゞ你是变态", "(σ°∀°)σ..:*☆哎哟不错哦", "(*^▽^*)", "(^_−)☆", "*✧⁺˚⁺ପ(๑・ω・)੭ु⁾⁾ 好好学习天天向上", "( • ̀ω•́ )✧", "(〃'▽'〃)", "(づ ̄3 ̄)づ╭❤~", "(✪ω✪)", "✧*。٩(ˊᗜˋ*)و✧*。"]
        };
      },
      methods: {
        save() {
          log("Pig clicked");
          
          if (!/wallhaven.cc\/w\//.test(window.location.href)) {
            const Toast = Swal.mixin({
              toast: true,
              position: "bottom-end",
              showConfirmButton: false,
              timer: 3000,
              timerProgressBar: false,
              didOpen: (toast) => {
                toast.onmouseenter = Swal.stopTimer;
                toast.onmouseleave = Swal.resumeTimer;
              }
            });
            Toast.fire({
              iconHtml: '<img src="' + static + '" style="width: 50px; height: 50px; cursor: pointer; border-radius: 50%; background: white;" />',
              html: this.emoticons[Math.floor(Math.random() * this.emoticons.length)]
            });
          }
          
          // Change icon
          let img = document.querySelector("#save");
          img.src = animate;
          setTimeout(() => {
            img.src = static;
          }, 1500);

          if (/wallhaven.cc\/w\//.test(window.location.href)) {
            
            // Add to Favorites
            this.add();

            // Download
            this.download();
          }
        },
        add() {
          let add = document.querySelector(".add-fav");
          log(`output->add`, add);
          if (add != null) {
            add.click();
          }
        },
        download() {
          let img = document.querySelector("#wallpaper");
          if (img != null) {
            imgUrl = img.src
            log(`output->imgUrl`, imgUrl);
          }
          
          // 下载图片
          fetch(imgUrl).then((res) =>
            res.blob().then((blob) => {
              // 动态创建a标签,防止下载大文件时,用户没看到下载提示连续点击
              const a = document.createElement("a"),
                url = window.URL.createObjectURL(blob),
                filename = imgUrl.substring(imgUrl.lastIndexOf("/") + 1);
              log(`output->filename`, filename);
              a.href = url;
              a.download = filename;
              a.click();
              window.URL.revokeObjectURL(url);
            })
          );
          document.querySelector("#header").click();
        },
      },
    }).mount("#app");
  };

})();