Greasy Fork

Greasy Fork is available in English.

微博超话图片下载

提供超话内原图下载,优化超话浏览体验

当前为 2023-03-20 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         微博超话图片下载
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  提供超话内原图下载,优化超话浏览体验
// @author       乃木流架
// @match        https://weibo.com/p/*
// @icon         https://weibo.com/favicon.ico
// @license      GPL-3.0 License
// @grant        GM_download
// @run-at       document-end
// ==/UserScript==

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

  /**
   * @desc 属性改变监听,属性被set时出发watch的方法,类似vue的watch
   * @author Jason
   * @study https://www.jianshu.com/p/00502d10ea95
   * @data 2018-04-27
   * @constructor
   * @param {object} opts - 构造参数. @default {data:{},watch:{}};
   * @argument {object} data - 要绑定的属性
   * @argument {object} watch - 要监听的属性的回调
   * watch @callback (newVal,oldVal) - 新值与旧值
   */

  class watcher {
    constructor(opts) {
      this.$data = this.getBaseType(opts.data) === "Object" ? opts.data : {};
      this.$watch = this.getBaseType(opts.watch) === "Object" ? opts.watch : {};
      for (let key in opts.data) {
        this.setData(key);
      }
    }

    getBaseType(target) {
      const typeStr = Object.prototype.toString.apply(target);

      return typeStr.slice(8, -1);
    }

    setData(_key) {
      Object.defineProperty(this, _key, {
        get: function () {
          return this.$data[_key];
        },
        set: function (val) {
          const oldVal = this.$data[_key];
          if (oldVal === val) return val;
          this.$data[_key] = val;
          this.$watch[_key] &&
            typeof this.$watch[_key] === "function" &&
            this.$watch[_key].call(this, val, oldVal);
          return val;
        },
      });
    }
  }

  // export default watcher;

  const picImpl = "https://weibo.com/ajax/statuses/show?id=";
  let length = 15;
  let wm = new watcher({
    data: {
      len: length,
    },
    watch: {
      len(newVal, oldVal) {
        console.log("length: ", length);
        console.log("newVal: ", newVal);
        console.log("oldVal: ", oldVal);
        if (newVal > length) {
          let faces = document.getElementsByClassName("WB_info");
          let i = length;
          length = faces.length;
          while (i < length) {
            let btn = initBtn();
            faces[i].appendChild(btn);
            //   console.log(i);
            //   console.log(faces[i]);
            handleBtn(btn);
            i++;
          }
        }
      },
    },
  });

  // 发起ajax的请求用get方法
  // 有3个参数
  function sendAjax(type, url) {
    let xhr = new XMLHttpRequest();
    // 拼接所需要的的值
    // 所要拼接的值 + 里面填获取值的参数+ "&或者的意思"  最后拼接的直接+获取值的参数
    xhr.open(type, url, false);
    xhr.send();
    // xhr.onreadystatechange = function () {
    //   if (xhr.readyState == 4 && xhr.readyState == 200) {
    //     // 这个是转化为字符串的形式
    //     let data = JSON.parse(xhr.responseText);
    //     callback(data);
    //   }
    // };
    return JSON.parse(xhr.responseText);
  }

  function initBtn() {
    let btn = document.createElement("button");
    btn.className = "nogiruka-button";
    btn.innerHTML = "图片下载";
    btn.setAttribute(
      "style",
      "border:1px solid transparent;background-color:#ffffff;padding:0;font-size: 12px;margin-top:1px;"
    );
    let div = document.createElement("div");
    let div2 = document.createElement("div2");
    let img = document.createElement("img");
    let p = document.createElement("p");
    // img.src = "https://i.jpg.dog/72dbffd3545cb15b148682beaf0fb64a.png";
    // img.src = "https://i.jpg.dog/d5380c9048e6ee303f188da9ec574399.png";
    img.src =
      "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEMAAABDCAYAAADHyrhzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFMElEQVR4nO2baYgcRRTHKzGJqFlFvDDRL16RCB6sG3f7vdnxQ+KBB3gEL4R8cVFUZN0se8x7U4giqIj4TZB4bEAJKIpCUBA0+SCaLwoKUYOKmCBoNEYYp6vGWFJzrLs7PTO93V3dk539Q8F8merXv36vjveqhFhWd8iMDp5kZP7MssQLygXvwpL01hm56VSxlGWkWKmkd6UmHNUEM4rhc0VwRDOaoKYYfM34tWZ8WxE+WSngZgtOHM8AKgxbai+Ph1u9eNhmASmCjxTltplxr08cDzITm0/ThAXNeDAugJZgCEua4BWfvA2iG2XGvT7F8JRi+NMVhAAoxzTjrq6C4jPcogl/SgtCcwihVgQvGplfmxkEMzlwhmJ4PysITY3we81DA6mD0NO5TZrhh8wBNIUOVDThhBFiRSogfILb69Of6eL2upH5VU5B6AI8XB+4sn7ZMGHznrP1iWZ4xI1r4zFFUHbU924z0r86URCK8G43HgHflWT+PCM3rtEMO914CMwkNoZo9oYUoXJkKP8PHK5wGDIyNggziadrgh+dGcmwvfEsn4YvdvUc69V2jxMLhmZ4xx2I9GDUgMAvdpccCYTPuTvcgkgXRr3tWDQII/tPdhse2cBQjP9qxvyiYGjGYgpfKQvPsOPHvvBeMbblFEXw21KFYVul4F0X0itge1pGZQVDEe7t7BVCrKjt/pY2jCoQiZe394pCbjhNgzKFwfBspxB5uVdgaMJDNlfbBgYe7BkYtdYfCMKXQ5emb0zGMCg33sIrvAd7DYbd4gfCUIwv9RoMO260gvFxz8FgNIElTU14qBdh6Gnv6qbFlmL4pxdhVDh3U/MulTP4Kl0Aw6Y058OYuuacnoVRxAfmwShJb12vwrBLivmeMe719SoMVfTuWzBmiJX1LFDEugfuVoSfpg7DZuMI3lKMf0SF4ZN3a9A643CkDglHZ6dnhsm0YNjDK3bgr/3X2xBjNoRmGBTly9p5Ggbn9mMLv65hVEEsKB0qhl+j2G+m8KwmGJrwtWhk4dWAviZcwQgCYYvhUWxXhL83gYib7lOEL4hIQBYHIwhEheHGqKcCWqb/NA8NRIXRALKwpqkJxpKCoRj22GT1fBC56+MUrRXBE4EwzNatJ7Q7kugGSDgYLkDYVinAtYEwrOw0FafzBhAROmQ6w0g6NObYedQ8esOJopV8htviwlich7SH4cojQpUajdy4JqkCUjggrWE4BtE+RBpSBM8n8bBwIRMMw1VozDaCb9tmxhsy07lzkzxW1N5DmmG49oiaTbltIqxUwvnQlkAIxubCSAOEPcBrh4PQMErTg+sV419JA1n4HCOHzp79Pe71OQ2Nhh1FvCc0iIY04+NJGtHKQ1opcY9ohGCUw25G5ldpwi9cAOkMwoFHEJRtoUxElW/jmPBomh7iwiPqbUTElSp6dzkwLBCIQxC7YoNoSDE+7RqIi9Coh8dnC2eoWDL2EAvjDjdA4BPN8Gb1RkDS/RPuj3zcsfOACjMugDhphPv/LuTOF65kbOWN4JnMX7Sjt+G+wHSeC+kCPtS9d05gZyNRnJoUDV+lCQ90jzdAWRM8JrKSkfm1ivA5e2kuUxCMH9o1kegGKYLLFMEHqYMgPOAT3im6UdomlQnedX51i/ArRXCvzduKbldpenC9jV/N+GWCY8IRO7VX78andTsxaZXl4EV2X6AJ3tCM34QeXwh+roYewZSt2jm/jZiFzEj/al/iJTYHWSG8uXr/rYj322S0/er2elamt5eXtSwxV/8B8CHKT9TokA8AAAAASUVORK5CYII=";
    img.setAttribute(
      "style",
      "width:12px;height:12px;margin-top:5px;margin-right:2px;"
    );
    p.innerHTML = "图片下载";
    p.setAttribute(
      "style",
      "padding:0;font-size: 12px;margin-top:1px;color:#333333;margin-top: 3px;"
    );
    div.appendChild(img);
    div.appendChild(p);
    // a.appendChild(btn);

    div.setAttribute(
      "style",
      "display: inline-flex;position:absolute;box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1);border:1px solid #d9d9d9;height:21px;width:80px;background-color:#ffffff;font-color:#333333;font-size: 12px;text-align: center;border-radius: 2px;cursor: pointer;margin-left:5px;margin-bottom:5px;justify-content: center;"
    );
    // a.setAttribute("style", "position:absolute;");
    return div;
  }

  function addBtn() {
    let faces = document.getElementsByClassName("WB_info");
    let i = 0;
    length = faces.length;
    console.log("first-length: " + length);
    while (i < length) {
      let btn = initBtn();
      faces[i].appendChild(btn);
      //   console.log(i);
      //   console.log(faces[i]);
      handleBtn(btn);
      i++;
    }
  }

  function handleBtn(btn) {
    btn.addEventListener("click", function (e) {
      let detail = e.target.parentNode.parentNode;
      let from = detail.nextElementSibling;
      let href = from.firstElementChild.href;
      //   console.log(detail);
      //   console.log(from);
      //   console.log(href);
      let mblogid = href.split("/")[href.split("/").length - 1];
      let url = picImpl + mblogid;
      console.log(mblogid);
      console.log(url);
      let response = sendAjax("GET", url);
      console.log(response);
      const picInfos = response.pic_infos;
      const userName = response.user.screen_name;
      const text = response.text_raw;
      let downloadList = [];
      if (picInfos) {
        console.log("downloading images");
        let index = 0;
        for (const [id, pic] of Object.entries(picInfos)) {
          index += 1;
          let largePicUrl = pic.largest.url;
          let picName = largePicUrl
            .split("/")
            [largePicUrl.split("/").length - 1].split("?")[0];
          let ext = picName.split(".")[1];
          let dlName = userName + "-" + mblogid + "-" + index + "." + ext;
          downloadList.push({
            url: largePicUrl,
            name: dlName,
            headerFlag: true,
          });
        }
        console.log(downloadList);
        handleDownloadList(downloadList);
      }
    });
  }

  function handleDownloadList(downloadList) {
    for (const item of downloadList) {
      downloadWrapper(item.url, item.name, item.headerFlag);
    }
  }

  function downloadWrapper(url, name, headerFlag) {
    textContent = name + " [0%]";
    const download = GM_download({
      url,
      name,
      headers: headerFlag
        ? {
            Referer: "https://weibo.com/",
            Origin: "https://weibo.com/",
          }
        : null,
      onprogress: (e) => {
        // e = { int done, finalUrl, bool lengthComputable, int loaded, int position, int readyState, response, str responseHeaders, responseText, responseXML, int status, statusText, int total, int totalSize }
        const percent = (e.done / e.total) * 100;
        textContent = name + " [" + percent.toFixed(0) + "%]";
        console.log(textContent);
      },
      onload: ({ status, response }) => {
        // console.log("下载中。。。");
      },
      onerror: (e) => {
        console.log(e);
      },
      ontimeout: (e) => {
        console.log(e);
      },
    });
  }

  function handleQ() {
    //搜索处理
    let username = document.getElementsByClassName("username")[0].innerText;
    let input = document.getElementsByClassName("W_input")[0];
    let q = username + "超话 ";
    let ph = document.getElementsByClassName("placeholder")[0];
    if (ph != null) {
      ph.remove();
    }
    // console.log(input.value);
    if (input.value != q) {
      input.value = q;
    }
  }

  setInterval(() => {
    handleQ();

    //翻页
    let nextPage = document.getElementsByClassName(
      "page next S_txt1 S_line1"
    )[0];
    // console.log(nextPage);
    if (nextPage != undefined) {
      console.log("下一页出现。。。");
      hr = nextPage.href;
      nextPage.addEventListener("click", function () {
        console.log("前往:", hr);
        window.location.href = hr;
      });
    }

    let temp = document.getElementsByClassName("WB_info").length;
    if (temp != length && temp > length) {
      wm.len = temp;
    }
  }, 2000);

  window.onload = function () {
    //去除扫描二维码进入手机超话
    let qr = document.getElementById("Pl_Core_PicText__265");
    qr.remove();

    setTimeout(() => {
      addBtn();
    }, 1000);

    // addBtn();
  };
  // Your code here...
})();