// ==UserScript==
// @name GreasyFork Code: Syntax Highlight by highlight.js
// @namespace Violentmonkey Scripts
// @grant none
// @version 0.3.1
// @author CY Fung
// @description To syntax highlight GreasyFork Code by highlight.js
// @run-at document-start
// @inject-into page
// @unwrap
// @license MIT
// @match https://greasyfork.org/*
// @match https://sleazyfork.org/*
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/javascript.min.js
// ==/UserScript==
(() => {
let byPass = true;
const resoruces = {
'nnfx-light.css': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/nnfx-light.min.css'
}
const Promise = (async function () { })().constructor;
const documentReady = new Promise(resolve => {
Promise.resolve().then(() => {
if (document.readyState !== 'loading') {
resolve();
} else {
window.addEventListener("DOMContentLoaded", resolve, false);
}
});
});
async function doAction() {
await new Promise(r => setTimeout(r, 1));
document.head.appendChild(document.createElement('style')).textContent = `
.code-container{
height:100vh;
}
.code-container .CodeMirror, .code-container textarea{
height:100%;
}
`;
if (window.requestIdleCallback) await new Promise(r => !!window.requestIdleCallback(r));
else {
await new Promise(r => !!window.requestAnimationFrame(r));
await new Promise(r => !!window.setTimeout(r, 170));
await new Promise(r => !!window.requestAnimationFrame(r));
}
byPass = false;
}
let mgg = 0;
async function mTz() {
if (mgg) return;
mgg = 1;
documentReady.then(doAction);
}
function getElementsByTagName(tag) {
if (byPass) {
if (tag === 'pre' || tag === 'code' || tag === 'xmp') {
if (location.pathname.endsWith('/code')) {
setTimeout(mTz, 100)
return [];
}
}
}
return this.getElementsByTagName331(tag);
}
async function onBodyHeadReadyAsync() {
if (document.body && document.head) {
} else {
const promiseBegin = new Promise(resolve => {
let mo = new MutationObserver(() => {
if (document.body && document.head) {
mo.disconnect();
mo.takeRecords();
mo = null;
resolve();
}
});
mo.observe(document, { subtree: true, childList: true });
});
await promiseBegin.then();
}
}
// Load CSS
function loadCSS(href) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = href;
document.head.appendChild(link);
}
const global_css = `
html {
line-height: 1.5;
-webkit-text-size-adjust: 100%;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
font-family: ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;
font-feature-settings: normal;
font-variation-settings: normal
}
/*
body {
margin: 0;
line-height: inherit
}
hr {
height: 0;
color: inherit;
border-top-width: 1px
}
abbr:where([title]) {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted
}
h1,h2,h3,h4,h5,h6 {
font-size: inherit;
font-weight: inherit
}
b,strong {
font-weight: bolder
}
*/
code,kbd,pre,samp {
font-family: ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;
font-size: 1em
}
/*
small {
font-size: 80%
}
sub,sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline
}
sub {
bottom: -.25em
}
sup {
top: -.5em
}
table {
text-indent: 0;
border-color: inherit;
border-collapse: collapse
}
button,input,optgroup,select,textarea {
font-family: inherit;
font-feature-settings: inherit;
font-variation-settings: inherit;
font-size: 100%;
font-weight: inherit;
line-height: inherit;
color: inherit;
margin: 0;
padding: 0
}
button,select {
text-transform: none
}
:-moz-focusring {
outline: auto
}
:-moz-ui-invalid {
box-shadow: none
}
progress {
vertical-align: baseline
}
::-webkit-inner-spin-button,::-webkit-outer-spin-button {
height: auto
}
[type=search] {
-webkit-appearance: textfield;
outline-offset: -2px
}
::-webkit-search-decoration {
-webkit-appearance: none
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit
}
summary {
display: list-item
}
blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre {
margin: 0
}
fieldset {
margin: 0
}
fieldset,legend {
padding: 0
}
menu,ol,ul {
list-style: none;
margin: 0;
padding: 0
}
textarea {
resize: vertical
}
input::-moz-placeholder,textarea::-moz-placeholder {
opacity: 1;
color: #9ca3af
}
input::placeholder,textarea::placeholder {
opacity: 1;
color: #9ca3af
}
*/
#script-content > .code-container[class] {
width: 100%;
}
.code-container[class] {
border-radius: 0;
}
.code-container[class] {
border-radius: 0;
}
.code-container > pre:only-child{
padding:0;
}
code.language-javascript.hljs[class] {
/*
font-family: ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace !important;
font-size: 9pt;
*/
font-family: monospace;
font-size: 13px;
font-variant-ligatures: contextual;
line-height: normal;
}
.hljs-comment[class], .hljs-quote[class] {
font-style: inherit;
color: #259789;
}
.hljs-add-marker-width .marker-fixed-width[class] {
user-select: none !important;
width: calc(var(--hljs-marker-width, 0em) + 16px);
background: #f4f4f4;
padding-right: 6px;
margin-right: 4px;
}
`;
const cssForCodePage = /\/scripts\/\d+[^\s\/\\]*\/code(\/|$)/.test(location.href) ? `
html:not([dkkfv]) div.code-container {
position: absolute !important;
}
html:not([dkkfv]) div.code-container > pre{
display:none;
}
html:not([dkkfv]) code:only-child {
display:none;
}
.code-container,
.code-container pre:only-child,
.code-container pre:only-child code:only-child {
max-height: calc(100vh + 4px);
max-width: calc(100vw + 4px);
}
` : '';
const cssAdd = `
${global_css}
${cssForCodePage}
.code-container {
max-width: 100%;
display: inline-flex;
flex-direction: column;
overflow: auto;
border-radius: 8px;
max-height: 100%;
overflow: visible;
}
.code-container > pre:only-child {
max-width: 100%;
display: inline-flex;
flex-direction: column;
flex-grow: 1;
height: 0;
}
.code-container > pre:only-child > code:only-child {
max-width: 100%;
flex-grow: 1;
height: 0;
}
.code-container pre code {
padding: 0;
font-family: Consolas;
cursor: text;
overflow: auto;
}
.code-container pre code .marker {
display: inline-block;
color: #636d83;
text-align: right;
padding-right: 20px;
user-select: none;
cursor: auto;
}
`;
HTMLElement.prototype.getElementsByTagName331 = HTMLElement.prototype.getElementsByTagName
Document.prototype.getElementsByTagName331 = Document.prototype.getElementsByTagName
HTMLElement.prototype.getElementsByTagName = getElementsByTagName
Document.prototype.getElementsByTagName = getElementsByTagName
onBodyHeadReadyAsync().then(() => {
loadCSS(resoruces['nnfx-light.css'])
document.head.appendChild(document.createElement('style')).textContent = `${cssAdd}`;
});
documentReady.then(() => {
if (!location.pathname.endsWith('/code')) {
byPass = false;
}
// Code highlighting
for (const pre of document.querySelectorAll('pre.lang-js')) {
for (const li of pre.querySelectorAll('li')) {
li.append(document.createTextNode('\n'));
}
const codeElement = document.createElement('code');
codeElement.classList.add('language-javascript');
codeElement.innerHTML = pre.innerHTML;
// Clearing the original code container and appending the new one
pre.classList = '';
pre.innerHTML = '';
pre.appendChild(codeElement);
const code = pre.querySelector('code:only-child');
if (!code) continue;
// Highlighting
hljs.highlightElement(code);
// Adding line numbers
const html = code.innerHTML || '';
const htmlSplit = html ? html.split('\n') : [];
const totalLines = htmlSplit.length;
if (totalLines >= 1) {
code.classList.add('hljs-add-marker-width');
code.style.setProperty('--hljs-marker-width', `${String(totalLines).length * 0.5}em`);
code.innerHTML = htmlSplit.map((n, i) => `<span class="marker marker-fixed-width">${i + 1}</span>${n}`).join('\n');
} else {
code.classList.remove('hljs-add-marker-width');
code.style.setProperty('--hljs-marker-width', '');
}
}
setTimeout(() => {
document.documentElement.setAttribute('dkkfv', '');
}, 1);
});
})();