增进 Greasyfork 浏览体验。
当前为
// ==UserScript==
// @name Greasy Fork Enhance
// @name:zh-CN Greasy Fork 增强
// @namespace http://tampermonkey.net/
// @version 0.2.1
// @description Enhance your experience at Greasyfork.
// @description:zh-CN 增进 Greasyfork 浏览体验。
// @author PRO
// @match https://greasyfork.org/*
// @icon https://greasyfork.org/vite/assets/blacklogo16-bc64b9f7.png
// @license gpl-3.0
// @grant none
// ==/UserScript==
(function() {
'use strict';
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
node.id = sanitify(node.textContent); // 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 = node.id;
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;
}
@media (any-hover: none) {
a.anchor {
opacity: 1;
}
}
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;
opacity: 0.8;
}
div#float-buttons {
position: fixed;
bottom: 0;
right: 0;
display: flex;
flex-direction: column;
user-select: none;
padding: 1em;
}
aside.panel {
display: none;
}
@media screen and (min-width: 767px) {
aside.panel {
display: block;
line-height: 1.5;
padding: 0;
position: sticky;
top: 0;
height: 0;
}
ul.outline {
float: right;
padding: 0 0 0 0.5em;
margin: 0 0.5em;
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;
}
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;
if (!window.location.pathname.endsWith("scripts/")) {
let panel = document.createElement("aside");
panel.className = "panel";
body.insertBefore(panel, document.querySelector("body > div.width-constraint"));
let fill = document.createElement("div");
let reference_node = document.querySelector("body > div.width-constraint > section");
fill.style.height = reference_node ? getComputedStyle(reference_node).marginTop : "1em";
panel.appendChild(fill);
outline = document.createElement("ul");
outline.className = "outline";
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) {
let placeholder = document.createElement("li");
placeholder.textContent = "Nothing to show.";
outline.appendChild(placeholder);
}
}
// 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.className = "button";
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();
}
});
})();