您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
增进 Greasyfork 浏览体验。
当前为
- // ==UserScript==
- // @name Greasy Fork Enhance
- // @name:zh-CN Greasy Fork 增强
- // @namespace http://tampermonkey.net/
- // @version 0.4.0
- // @description Enhance your experience at Greasyfork.
- // @description:zh-CN 增进 Greasyfork 浏览体验。
- // @author PRO
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_registerMenuCommand
- // @grant GM_unregisterMenuCommand
- // @match https://greasyfork.org/*
- // @require https://greasyfork.org/scripts/470224-tampermonkey-config/code/Tampermonkey%20Config.js?version=1216049
- // @icon https://greasyfork.org/vite/assets/blacklogo16-bc64b9f7.png
- // @license gpl-3.0
- // ==/UserScript==
- (function() {
- 'use strict';
- // Judge if the script should run
- let no_run = [".json", ".user.js"];
- let is_run = true;
- no_run.forEach((suffix) => {
- if (window.location.href.endsWith(suffix)) {
- is_run = false;
- }
- });
- if (!is_run) return;
- // Config
- let config_desc = {
- "opacity/default": {
- name: "Default opacity",
- value: 0.2,
- processor: parseFloat
- },
- "opacity/hover": {
- name: "Hover opacity",
- value: 0.8,
- processor: parseFloat
- },
- "opacity/none": {
- name: "None-hover opacity",
- value: 0.8,
- processor: parseFloat
- }
- };
- let config = GM_config(config_desc);
- let body = document.querySelector("body");
- function sanitify(s) {
- // Remove emojis (such a headache)
- s = s.replaceAll(/([\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2580-\u27BF]|\uD83E[\uDD10-\uDEFF]|\uFE0F)/g, "");
- // Trim spaces and newlines
- s = s.trim();
- // Replace spaces
- s = s.replaceAll(" ", "-");
- s = s.replaceAll("%20", "-");
- // No more multiple "-"
- s = s.replaceAll(/-+/g, "-");
- return s;
- }
- function process(node) { // Add anchor and assign id to given node; Add to outline. Return true if node is actually processed.
- if (node.childElementCount > 1 || node.classList.length > 0) return false; // Ignore complex nodes
- let text = node.textContent;
- node.id = sanitify(text); // Assign id
- // Add anchors
- let node_ = document.createElement('a');
- node_.className = 'anchor';
- node_.href = '#' + node.id;
- node.appendChild(node_);
- let list_item = document.createElement("li");
- outline.appendChild(list_item);
- let link = document.createElement("a");
- link.href = "#" + node.id;
- link.text = text;
- list_item.appendChild(link);
- return true;
- }
- // Css
- let css = document.createElement("style");
- css.textContent = `
- html {
- scroll-behavior: smooth;
- }
- a.anchor::before {
- content: "#";
- }
- a.anchor {
- opacity: 0;
- text-decoration: none;
- padding: 0px 0.5em;
- -moz-transition: all 0.25s ease-in-out;
- -o-transition: all 0.25s ease-in-out;
- -webkit-transition: all 0.25s ease-in-out;
- transition: all 0.25s ease-in-out;
- }
- h1:hover>a.anchor,
- h2:hover>a.anchor,
- h3:hover>a.anchor,
- h4:hover>a.anchor,
- h5:hover>a.anchor,
- h6:hover>a.anchor {
- opacity: 1;
- -moz-transition: all 0.25s ease-in-out;
- -o-transition: all 0.25s ease-in-out;
- -webkit-transition: all 0.25s ease-in-out;
- transition: all 0.25s ease-in-out;
- }
- a.button {
- margin: 0.5em 0 0 0;
- display: flex;
- align-items: center;
- justify-content: center;
- text-decoration: none;
- color: black;
- background-color: #a42121ab;
- border-radius: 50%;
- width: 2em;
- height: 2em;
- font-size: 1.8em;
- font-weight: bold;
- }
- div.lum-lightbox {
- z-index: 2;
- }
- div#float-buttons {
- position: fixed;
- bottom: 1em;
- right: 1em;
- display: flex;
- flex-direction: column;
- user-select: none;
- z-index: 1;
- }
- aside.panel {
- display: none;
- }
- .dynamic-opacity {
- transition: opacity 0.2s ease-in-out;
- opacity: ${config["opacity/default"]};
- }
- .dynamic-opacity:hover {
- opacity: ${config["opacity/hover"]};
- }
- input[type=file] {
- border-style: dashed;
- border-radius: 0.5em;
- padding: 0.5em;
- background: rgba(169, 169, 169, 0.4);
- }
- @media (any-hover: none) {
- .dynamic-opacity {
- opacity: ${config["opacity/none"]};
- }
- .dynamic-opacity:hover {
- opacity: ${config["opacity/none"]};
- }
- }
- @media screen and (min-width: 767px) {
- aside.panel {
- display: contents;
- line-height: 1.5;
- }
- ul.outline {
- position: sticky;
- float: right;
- padding: 0 0 0 0.5em;
- margin: 0 0.5em;
- max-height: 80vh;
- border: 1px solid #BBBBBB;
- border-left: 2px solid #F2E5E5;
- box-shadow: 0 0 5px #ddd;
- background: linear-gradient(to right, #fcf1f1, #FFF 1em);
- list-style: none;
- width: 10.5%;
- color: gray;
- border-radius: 5px;
- overflow-y: scroll;
- z-index: 1;
- }
- ul.outline > li {
- overflow: hidden;
- text-overflow: ellipsis;
- }
- ul.outline > li > a {
- color: gray;
- white-space: nowrap;
- text-decoration: none;
- }
- }`;
- document.querySelector("head").appendChild(css); // Inject css
- // Aside panel & Anchors
- let outline;
- let is_script = /^\/[^\/]+\/scripts/;
- let is_specific_script = /^\/[^\/]+\/scripts\/\d+/;
- let is_disccussion = /^\/[^\/]+\/discussions/;
- let path = window.location.pathname;
- if ((!is_script.test(path) && !is_disccussion.test(path)) || is_specific_script.test(path)) {
- let panel = document.createElement("aside");
- panel.className = "panel";
- body.insertBefore(panel, document.querySelector("body > div.width-constraint"));
- let reference_node = document.querySelector("body > div.width-constraint > section");
- outline = document.createElement("ul");
- outline.classList.add("outline");
- outline.classList.add("dynamic-opacity");
- outline.style.top = reference_node ? getComputedStyle(reference_node).marginTop : "1em";
- outline.style.marginTop = outline.style.top;
- panel.appendChild(outline);
- let flag = false;
- document.querySelectorAll("body > div.width-constraint h1, h2, h3, h4, h5, h6").forEach((node) => {
- flag = process(node) || flag; // Not `flag || process(node)`!
- });
- if (!flag) {
- panel.remove();
- }
- }
- // Navigate to hash
- let hash = window.location.hash.slice(1);
- if (hash) {
- let ele = document.getElementById(decodeURIComponent(hash));
- if (ele) {
- ele.scrollIntoView();
- }
- }
- // Buttons
- let buttons = document.createElement("div");
- buttons.id = "float-buttons";
- let to_top = document.createElement("a");
- to_top.classList.add("button");
- to_top.classList.add("dynamic-opacity");
- to_top.href = "#top";
- to_top.text = "↑";
- buttons.appendChild(to_top);
- body.appendChild(buttons);
- // Double click to get to top
- body.addEventListener("dblclick", (e) => {
- if (e.target == body) {
- to_top.click();
- }
- });
- // Fix current tab link
- let tab = document.querySelector("ul#script-links > li.current");
- if (tab) {
- let link = document.createElement("a");
- link.href = window.location.pathname;
- let orig_child = tab.firstChild;
- link.appendChild(orig_child);
- tab.appendChild(link);
- }
- let parts = window.location.pathname.split("/");
- if (parts.length <= 2 || (parts.length == 3 && parts[2] === '')) {
- let banner = document.querySelector("header#main-header div#site-name");
- let img = banner.querySelector("img");
- let text = banner.querySelector("#site-name-text > h1");
- let link1 = document.createElement("a");
- link1.href = window.location.pathname;
- img.parentNode.replaceChild(link1, img);
- link1.appendChild(img);
- let link2 = document.createElement("a");
- link2.href = window.location.pathname;
- link2.textContent = text.textContent;
- text.textContent = "";
- text.appendChild(link2);
- }
- })();