粉笔网刷题宝

粉笔网优化布局,清屏快速生成pdf

目前為 2023-11-18 提交的版本,檢視 最新版本

// ==UserScript==
// @name         粉笔网刷题宝
// @namespace    http://tampermonkey.net/
// @version      0.0.47
// @author       binyellow
// @icon         https://nodestatic.fbstatic.cn/weblts_spa_online/page/assets/fenbi32.ico
// @defaulticon  粉笔网优化布局,清屏快速生成pdf
// @match        https://www.fenbi.com/*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @description 粉笔网优化布局,清屏快速生成pdf
// ==/UserScript==

(function ($) {
  'use strict';

  const processCls = `__binyellow__processed__`;
  function processElements(selector, callback) {
    const elements = $(`${selector}:not(.${processCls})`);
    elements.each(function() {
      callback($(this));
      $(this).addClass(processCls);
    });
  }
  const mokao = () => {
    processElements(".exam-post-nav", (node) => {
      $(node).css({ left: 0, top: 0 });
      const detailContent = $(".solution-detail.clear-float");
      $(detailContent).css({ width: "100%" });
      const optionsUl = $(detailContent).find(".options.ng-star-inserted");
      $(optionsUl).css({ display: "flex", "justify-content": "space-between", "flex-wrap": "wrap" });
      optionsUl.children().css("margin", "0");
      $(detailContent).find(".exam-main-content.ng-tns-c3-0.ng-star-inserted").css({ width: "calc(100% - 302px)" });
      $(".practice-header").hide();
      $(detailContent).find(".solu-detail.ng-star-inserted").css({ margin: 0, padding: 0 });
      $(detailContent).find(".nav-coll-divider.solu-divider").css({ margin: "6px 0" });
      $(detailContent).find(".question-content > p:nth-child(2) > img").each(function() {
        var img = $(this);
        var width = img.width() || 0;
        var height = img.height() || 0;
        var newWidth = width * 0.6;
        var newHeight = height * 0.6;
        img.width(newWidth);
        img.height(newHeight);
      });
    });
  };
  function observeDom(container, cbs2) {
    function handleMutation(mutation) {
      if (mutation.type === "childList") {
        mutation.addedNodes.forEach((node) => {
          cbs2.forEach((cb) => cb(node));
        });
      }
    }
    const observer = new MutationObserver((mutations) => {
      mutations.forEach(handleMutation);
    });
    observer.observe(container, { childList: true, subtree: true });
  }
  const caogao = () => {
    const caogao2 = $(".draft-icon");
    if (caogao2 == null ? void 0 : caogao2.length) {
      $(caogao2).on("click", function() {
        console.log("draft-icon 被点击");
        $(document).on("keydown", function(event) {
          if (event.key === "Escape" || event.keyCode === 27) {
            $(".tool-item.exit").trigger("click");
            $(document).off("keydown");
          }
        });
      });
    }
  };
  var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
  const xhrInterceptor = (rules, cb) => {
    var originalXHR = window.XMLHttpRequest;
    window.XMLHttpRequest = function() {
      var xhr = new originalXHR();
      var originalOpen = xhr.open;
      xhr.open = function() {
        const method = arguments[0];
        const url = arguments[1];
        const matchedRule = rules.find((rule) => {
          if (typeof rule.url === "string") {
            return rule.url === url && (!rule.method || rule.method === method);
          } else if (rule.url instanceof RegExp) {
            return rule.url.test(url) && (!rule.method || rule.method === method);
          } else {
            return false;
          }
        });
        if (matchedRule) {
          console.log("XHR request: " + method + " " + url);
          this._url = url;
          this._method = method;
        }
        originalOpen.apply(this, arguments);
      };
      var originalSend = xhr.send;
      xhr.send = function() {
        const body = arguments[0];
        if (this._url) {
          console.log(`send===>`, arguments, this._headers);
          this._body = body;
          console.log("XHR request body: " + body, this._url, this._headers);
          cb({
            url: this._url,
            method: this._method,
            body: this._body,
            headers: this._headers
          });
        }
        originalSend.apply(this, arguments);
      };
      const originalSetRequestHeader = xhr.setRequestHeader;
      xhr.setRequestHeader = function(header, value) {
        if (this._url) {
          if (!this._headers) {
            this._headers = {};
          }
          this._headers[header] = value;
        }
        originalSetRequestHeader.apply(this, arguments);
      };
      return xhr;
    };
  };
  const kuaiSuShuaTiKey = "__kuaiSuShuaTiKey__";
  const jiankong = () => {
    jiankongKuaiSuLianXi();
  };
  const jiankongKuaiSuLianXi = () => {
    const rules = [
      {
        url: "https://tiku.fenbi.com/api/xingce/exercises?app=web&kav=100&av=100&hav=100&version=3.0.0.0",
        method: "POST"
      }
    ];
    const callback = (config) => {
      _GM_setValue(kuaiSuShuaTiKey, config);
    };
    xhrInterceptor(rules, callback);
  };
  const request = (props) => {
    const { body, ...rest } = props;
    return new Promise((resolve) => {
      _GM_xmlhttpRequest({
        onload: (data) => {
          resolve(data);
        },
        method: "POST",
        data: typeof body === "object" && !(body instanceof FormData) ? JSON.stringify(body) : body,
        ...rest
      });
    });
  };
  const lianxiUrl = `https://www.fenbi.com/spa/tiku/exam/practice/xingce/xingce`;
  function shenlun() {
    const leftSubject = $(".zhenti-body-left.zhenti-body-part.bg-color-gray-light5");
    leftSubject.find(".materials-container").css({ width: "100%", padding: 12 });
    leftSubject.find(".material-content.ng-tns-c41-0").css({ width: "100%" });
    leftSubject.find(".material-content.ng-tns-c41-0").find("#material").css({ width: "100%" });
    const rightAnser = $(".zhenti-body-right.zhenti-body-part");
    rightAnser.css({ flex: "none" });
    rightAnser.find(".questions-container").css({ "padding-left": "12px" });
  }
  const kuaisu = (node, did2) => {
    var _a;
    const xingCeTiMu = $(node).find("main.exam-content");
    if ((xingCeTiMu == null ? void 0 : xingCeTiMu.length) && !(did2 == null ? void 0 : did2.xingce)) {
      did2.xingce = true;
      const css = { margin: 0 };
      $("main.exam-content").css(css);
      $(".simple-nav-header.bg-color-gray-bold").hide();
      const optionsCls = ".options.choice-options.font-color-gray-mid";
      $(optionsCls).css({ display: "flex" });
      $(".nav-coll-divider").hide();
      $(".solu-list.border-gray-light4").css({ "margin-top": 0 });
      $(".solu-answer-text.clear-float").hide();
      $(".bg-color-gray-light2.border-gray-light3.font-color-gray-mid.expend-btn").hide();
      $(".solu-list-item.video-item").css({ "margin-bottom": 0 });
      $(".solu-list-item.video-item fb-ng-solution-detail-item").hide();
      $("<style>.fb-collpase-bottom { width: calc(100% - 1024px); right: 0; }</style>").appendTo("head");
      $(".fb-collpase-bottom.bg-color-gray-mid").css({ margin: 0, width: "100%" });
      $(".fixedActions.bg-color-gray-bold").css({ right: 0 });
      did2.xingce = false;
      shenlun();
    }
    if (((_a = $(".fb-question-material")) == null ? void 0 : _a.length) && !did2.zhaiping) {
      did2.zhaiping = true;
      $(".fb-question-material").css({ margin: 12 });
      $(".material-content").css({ padding: 0 });
      $(".ques-options-dry").css({ padding: 0 });
      $(".options.font-color-gray-mid").css({ display: "flex", "flex-flow": "wrap" });
    }
    const collections = $(".solution-item.bg-color-gray-bold");
    if ((collections == null ? void 0 : collections.length) && !did2.collectionDid) {
      collections.each(function() {
        const solution = $(this).find(".solu-list.border-gray-light4");
        $(solution).css({ padding: 8 });
        $(solution).find("fb-ng-solution-detail-answer").hide();
      });
      did2.collectionDid = true;
    }
    const collectionBtn = $(
      ".solution-item.bg-color-gray-bold>app-fb-solution>fb-ng-solution > div[_ngcontent-fenbi-web-exams-c75] > div[_ngcontent-fenbi-web-exams-c75]"
    );
    if ((collectionBtn == null ? void 0 : collectionBtn.length) && !did2.collectionBtnDid) {
      collectionBtn.each(function() {
        $(this).css({ position: "absolute", right: 0 });
        console.log(this);
      });
      did2.collectionBtnDid = true;
    }
    processElements(".options.font-color-gray-mid", (node2) => {
      node2.css({ display: "flex", "flex-flow": "wrap", "justify-content": "space-between" });
    });
    processElements("app-report-header-test .exam-report", () => {
      $(".fixedActions.bg-color-gray-bold").removeClass(processCls);
      processElements(".fixedActions.bg-color-gray-bold", () => {
        var newButton = $("<button>重刷</button>");
        $(".fixedActions.bg-color-gray-bold").children().first().before(newButton);
        newButton.on("click", async function() {
          const requestConfig = await _GM_getValue(kuaiSuShuaTiKey, null);
          const data = await request(requestConfig);
          const { id } = JSON.parse(data == null ? void 0 : data.response);
          location.href = `${lianxiUrl}/${id}/2`;
        });
      });
    });
  };
  const dealWidth = () => {
    const cssRules = `
@media (max-width: 1000px) {
.exam-content {
  width: calc(100% - 45px) !important;
}
#app-practice {
  min-width: 100% !important;
}
.tools-container {
left: 0;
}
.fb-collpase-bottom {
left: 0;
width: 100% !important;
}
}

@media (min-width: 1700px) {
  main.exam-content {
    width: 1600px !important;
  }

  aside.fb-collpase-bottom {
    width: calc(100% - 1600px) !important;
  }
}

.collapse-content {
}

.collapse-title {
  cursor: pointer;
  text-decoration: underline;
  color: blue;
}

.extra-dom {
  position: fixed;
  background-color: #fff;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 4px;
  box-sizing: content-box;
}

.extra-dom input[type=number] {
  width: 100%;
}
`;
    const styleTag = document.createElement("style");
    styleTag.innerHTML = cssRules;
    document.head.appendChild(styleTag);
  };
  const isExam = () => {
    const { pathname } = location;
    return pathname.slice(pathname.lastIndexOf("/") + 1) === "3";
  };
  const fixedActions = () => {
    processElements(".fixedActions.bg-color-gray-bold", () => {
      var newButton = $("<button>清屏</button>");
      const marginLabel = '<label for="ti-jian-ju">题间距</label>';
      var newInput = $('<input id="ti-jian-ju" type="number" value="180">');
      const fontLabel = '<label for="zi-ti">字体</label>';
      const fontInput = $('<input id="zi-ti" type="number" value="20">');
      const $settingContainer = $(`<div class="collapse">
    <a class="collapse-title">设置></a>
    <div class="collapse-content">
    </div>
</div>`);
      $settingContainer.find(".collapse-content").append(marginLabel, newInput, fontLabel, fontInput);
      const options = [
        { label: "常识", range: [1, 20] },
        { label: "言语", range: [21, 60] },
        { label: "数量", range: [61, 70] },
        { label: "判断", range: [71, 105] },
        { label: "资料", range: [106, 120] }
      ];
      const $checkboxContainer = $(`<div class="collapse">
    <a class="collapse-title">题型></a>
    <div class="collapse-content">
    </div>
</div>`);
      options.forEach((option, index) => {
        const isChecked = option.label !== "常识";
        const $checkbox = $(`<input type="checkbox" id="option-${index}" ${isChecked ? "checked" : ""} />`);
        const $label = $(`<label for="option-${index}">${option.label}</label>`);
        $checkboxContainer.find(".collapse-content").append($checkbox, $label);
      });
      if (isExam()) {
        $(".fixedActions.bg-color-gray-bold").children().first().before($checkboxContainer);
      }
      const fixedActions2 = $(".fixedActions.bg-color-gray-bold");
      const position = fixedActions2.position();
      const width = fixedActions2.outerWidth() || 0;
      const extraDom = $("<div>", { class: "extra-dom" });
      extraDom.css({
        left: position.left - width - 15,
        top: "10vh",
        width: width + 6
      });
      extraDom.append(newButton, $settingContainer, $checkboxContainer);
      $("body").append(extraDom);
      $(".collapse-title").on("click", function() {
        $(this).next(".collapse-content").slideToggle();
      });
      newButton.on("click", async function() {
        if (isExam()) {
          $(".exam-detail.bg-color-gray-bold > div").hide();
          options.forEach((option, index) => {
            const $checkbox = $(`#option-${index}`);
            if ($checkbox.prop("checked")) {
              const [start, end] = option.range;
              for (let i = start - 1; i < end; i++) {
                $(".exam-detail.bg-color-gray-bold > div").eq(i).show();
              }
            }
          });
        }
        await scrollToNextImage();
        var examContent = $("main.exam-content");
        var inputValue = newInput.val();
        var fontValue = fontInput.val();
        $("body").empty();
        $("body").append(examContent);
        $("body").append(`<style>
                  .fixedActions.bg-color-gray-bold,.fb-collpase-bottom, app-side-tool,.fb-question > div:last-child[_ngcontent-fenbi-web-exams-c68],div[_ngcontent-fenbi-web-exams-c69] > div[_ngcontent-fenbi-web-exams-c69],.content.font-color-gray-mid>p.ques-type {
                  display: none;
                  }
  
                  .fb-question-options.fenbi-ng-utils > div[_ngcontent-fenbi-web-exams-c40],div.ques-options-dry {
  padding: 16px 0 0 0;
  margin-bottom: ${inputValue}px;
                  }
  
                  .options.font-color-gray-mid {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
                  }
  
                  .options.font-color-gray-mid > li {
  margin: 0 !important;
                  }
                  [_nghost-fenbi-web-exams-c40] p, [_nghost-fenbi-web-exams-c40] .options-material {
                  font-weight: normal;
                  font-size: ${fontValue}px;
                  }
  
                  main.exam-content {
  margin-right: 35px !important;
                  }
                  .material-nav.bg-color-gray-light {
                  display: none;
                  }
                  </style>`);
        $(".nav-coll-divider").hide();
        $(".fb-question>div:last-child > button").hide();
      });
    });
  };
  function isImageLoaded(img) {
    if (!img.complete) {
      return false;
    }
    if (typeof img.naturalWidth !== "undefined" && img.naturalWidth === 0) {
      return false;
    }
    return true;
  }
  function delay(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }
  async function scrollToNextImage() {
    var _a, _b;
    const images = $("#app-practice img").toArray().sort((a, b) => {
      var _a2, _b2;
      const aTop = ((_a2 = $(a).offset()) == null ? void 0 : _a2.top) ?? 0;
      const bTop = ((_b2 = $(b).offset()) == null ? void 0 : _b2.top) ?? 0;
      return aTop - bTop;
    });
    const filteredImages = images.filter((image, index) => {
      var _a2, _b2;
      if (index > 0) {
        const prevImage = images[index - 1];
        return (((_a2 = $(image).offset()) == null ? void 0 : _a2.top) ?? 0) !== (((_b2 = $(prevImage).offset()) == null ? void 0 : _b2.top) ?? 0);
      }
      return true;
    });
    const scrollContainer = $("#fenbi-web-exams");
    for (const image of filteredImages) {
      if (!isImageLoaded(image)) {
        await new Promise((resolve) => {
          $(image).on("load", function() {
            resolve();
          });
        });
      }
      const imagePositionInContainer = (((_a = $(image).offset()) == null ? void 0 : _a.top) ?? 0) - (((_b = scrollContainer.offset()) == null ? void 0 : _b.top) ?? 0) + (scrollContainer.scrollTop() ?? 0);
      await new Promise((resolve) => {
        scrollContainer.animate(
          {
            scrollTop: imagePositionInContainer
          },
          50,
          function() {
            resolve();
          }
        );
      });
      await delay(50);
    }
  }
  let did = {};
  const cbs = [];
  cbs.push((node) => kuaisu(node, did));
  cbs.push(caogao);
  cbs.push(mokao);
  cbs.push(fixedActions);
  const initCbs = [];
  initCbs.push(dealWidth);
  initCbs.push(() => {
  });
  initCbs.forEach((cb) => cb());
  observeDom(document.body, cbs);
  jiankong();

})($);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址