Now a bitbucket addon.
Performs some simple UI enhancements.
This commit is contained in:
parent
577073326a
commit
92fc3dd021
4
Makefile
4
Makefile
|
@ -1,5 +1,5 @@
|
||||||
old-reddit-redirect.zip: *.json *.js img/* *.md *.txt
|
bitbucket-fork-redirect.zip: *.json *.js img/* *.md *.txt
|
||||||
zip -r old-reddit-redirect.zip * -x .git/* -x img/screenshot.png -x .gitignore -x Makefile
|
zip -r bitbucket-fork-redirect.zip * -x .git/* -x img/screenshot.png -x .gitignore -x Makefile
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm *.zip
|
rm *.zip
|
||||||
|
|
|
@ -1,36 +1,14 @@
|
||||||
const oldReddit = "https://old.reddit.com";
|
chrome.webRequest.onBeforeRequest.addListener(details => {
|
||||||
const excludedPaths = [
|
const url = new URL(details.url)
|
||||||
"/poll",
|
|
||||||
"/rpan",
|
|
||||||
"/settings",
|
|
||||||
"/topics",
|
|
||||||
"/community-points",
|
|
||||||
];
|
|
||||||
|
|
||||||
chrome.webRequest.onBeforeRequest.addListener(
|
if (url.hostname !== "git.add123.com") return
|
||||||
function (details) {
|
if (!url.pathname.endsWith("plugins/servlet/search")) return
|
||||||
const url = new URL(details.url);
|
if (details.url.includes("fork:") || details.url.includes("fork%3A")) return
|
||||||
|
|
||||||
if (url.hostname === "old.reddit.com") return;
|
return { redirectUrl: `${details.url}%20fork%3Afalse` }
|
||||||
|
|
||||||
for (const path of excludedPaths) {
|
|
||||||
if (url.pathname.indexOf(path) === 0) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url.pathname.indexOf("/gallery") === 0) {
|
|
||||||
return { redirectUrl: oldReddit + '/comments' + url.pathname.slice("/gallery".length) };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { redirectUrl: oldReddit + url.pathname + url.search + url.hash };
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
urls: [
|
urls: [ "https://git.add123.com/*" ],
|
||||||
"*://reddit.com/*",
|
|
||||||
"*://www.reddit.com/*",
|
|
||||||
"*://np.reddit.com/*",
|
|
||||||
"*://amp.reddit.com/*",
|
|
||||||
"*://i.reddit.com/*",
|
|
||||||
],
|
|
||||||
types: [
|
types: [
|
||||||
"main_frame",
|
"main_frame",
|
||||||
"sub_frame",
|
"sub_frame",
|
||||||
|
@ -43,4 +21,4 @@ chrome.webRequest.onBeforeRequest.addListener(
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
["blocking"]
|
["blocking"]
|
||||||
);
|
)
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
const jsKeywords = new Set([
|
||||||
|
"abstract", "arguments", "await*", "boolean", "break", "byte", "case",
|
||||||
|
"catch", "char", "class*", "const", "continue", "debugger", "default",
|
||||||
|
"delete", "do", "double", "else", "enum*", "eval", "export*", "extends*",
|
||||||
|
"false", "final", "finally", "float", "for", "function", "goto", "if",
|
||||||
|
"implements", "import*", "in", "instanceof", "int", "interface", "let*",
|
||||||
|
"long", "native", "new", "null", "package", "private", "protected", "public",
|
||||||
|
"return", "short", "static", "super*", "switch", "synchronized", "this",
|
||||||
|
"throw", "throws", "transient", "true", "try", "typeof", "var", "void",
|
||||||
|
"volatile", "while", "with", "yield"
|
||||||
|
])
|
||||||
|
|
||||||
|
const csKeywords = new Set([
|
||||||
|
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char",
|
||||||
|
"checked", "class", "const", "continue", "decimal", "default", "delegate",
|
||||||
|
"do", "double", "else", "enum", "event", "explicit", "extern", "false",
|
||||||
|
"finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit",
|
||||||
|
"in", "int", "interface", "internal", "is", "lock", "long", "namespace",
|
||||||
|
"new", "null", "object", "operator", "out", "override", "params", "private",
|
||||||
|
"protected", "public", "readonly", "ref", "return", "sbyte", "sealed",
|
||||||
|
"short", "sizeof", "stackalloc", "static", "string", "struct", "switch",
|
||||||
|
"this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked",
|
||||||
|
"unsafe", "ushort", "using", "virtual", "void", "volatile", "while",
|
||||||
|
])
|
||||||
|
|
||||||
|
const javaKeywords = new Set([
|
||||||
|
"abstract", "continue", "for", "new", "switch", "assert", "default",
|
||||||
|
"goto", "package", "synchronized", "boolean", "do", "if", "private",
|
||||||
|
"this", "break", "double", "implements", "protected", "throw", "byte",
|
||||||
|
"else", "import", "public", "throws", "case", "enum", "instanceof",
|
||||||
|
"return", "transient", "catch", "extends", "int", "short", "try", "char",
|
||||||
|
"final", "interface", "static", "void", "class", "finally", "long",
|
||||||
|
"strictfp", "volatile", "const", "float", "native", "super", "while",
|
||||||
|
])
|
||||||
|
|
||||||
|
const keywordMap = {
|
||||||
|
js: jsKeywords,
|
||||||
|
mjs: jsKeywords,
|
||||||
|
java: javaKeywords,
|
||||||
|
cs: csKeywords,
|
||||||
|
none: new Set()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const bookendedWith = (text, bookend) => text.startsWith(bookend) && text.endsWith(bookend)
|
||||||
|
|
||||||
|
const getClass = (text, keywords) => {
|
||||||
|
if (keywords.has(text)) {
|
||||||
|
return 'hl-keyword'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bookendedWith(text, '"')) {
|
||||||
|
return 'hl-string'
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'hl-variable'
|
||||||
|
}
|
||||||
|
|
||||||
|
const getKeywords = () => keywordMap[getFileName().replace(/.*\./g, '')] || keywordMap.none
|
||||||
|
|
||||||
|
const commentSpan = innerText => {
|
||||||
|
const span = document.createElement('span')
|
||||||
|
span.innerText = innerText
|
||||||
|
span.classList.add('hl-comment')
|
||||||
|
return span
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorCodeInComment = (codeStart = '`', codeEnd) => {
|
||||||
|
codeEnd ??= codeStart
|
||||||
|
const processed = new Set()
|
||||||
|
const keywords = getKeywords()
|
||||||
|
getClassNameElementsArray('hl-comment').forEach(element => {
|
||||||
|
if (!element.innerText?.startsWith(codeStart) || processed.has(element)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const codeStartElement = commentSpan(codeStart)
|
||||||
|
element.replaceWith(codeStartElement, element)
|
||||||
|
element.innerText = element.innerText.replace(codeStart, '')
|
||||||
|
while (element) {
|
||||||
|
if (!element.classList.contains('hl-comment')) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
processed.add(element)
|
||||||
|
element.classList.remove('hl-comment')
|
||||||
|
const text = element.innerText.replaceAll(codeStart, '').replaceAll(codeEnd, '')
|
||||||
|
element.classList.add(getClass(text, keywords))
|
||||||
|
const codeEndIndex = element.innerText.indexOf(codeEnd)
|
||||||
|
if (codeEndIndex > -1) {
|
||||||
|
const codeEndElement = commentSpan(element.innerText.substring(codeEndIndex))
|
||||||
|
element.innerText = element.innerText.substring(0, codeEndIndex)
|
||||||
|
element.replaceWith(element, codeEndElement)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
element = element.nextElementSibling
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const commentCodeFix = () => {
|
||||||
|
colorCodeInComment('`', '`')
|
||||||
|
colorCodeInComment('<code>', '</code>')
|
||||||
|
colorCodeInComment('<pre>', '</pre>')
|
||||||
|
colorCodeInComment('<tt>', '</tt>')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
addFix(commentCodeFix)
|
|
@ -0,0 +1,17 @@
|
||||||
|
const fixCSharpStrings = () => {
|
||||||
|
const hasCSharpFileName = getFileName().endsWith('.cs')
|
||||||
|
if (!hasCSharpFileName) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getClassNameElementsArray('hl-string')
|
||||||
|
.filter(e => e.innerText.includes('@"') || e.innerText.includes('@$""'))
|
||||||
|
.forEach(e => {
|
||||||
|
const s = e.innerHTML
|
||||||
|
const firstQuote = s.indexOf('"') + 1
|
||||||
|
const spanned = s.substring(firstQuote, s.length - 1).replaceAll('""', '<span class="hl-def">""</span>')
|
||||||
|
e.innerHTML = s.substring(0, firstQuote) + spanned + '"'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
addFix(fixCSharpStrings)
|
BIN
img/icon128.png
BIN
img/icon128.png
Binary file not shown.
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 25 KiB |
BIN
img/icon48.png
BIN
img/icon48.png
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 16 KiB |
|
@ -1,27 +1,41 @@
|
||||||
{
|
{
|
||||||
"name": "Old Reddit Redirect",
|
"name": "ADD Git NoFork",
|
||||||
"description": "Ensure Reddit always loads the old design",
|
"description": "Ensure searches don't include forks",
|
||||||
"version": "1.6.1",
|
"version": "1.0.2",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"background": { "scripts": ["background.js"] },
|
"browser_specific_settings": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "svaillancourt@add123.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"background": {
|
||||||
|
"scripts": ["background.js"]
|
||||||
|
},
|
||||||
"icons": {
|
"icons": {
|
||||||
"48": "img/icon48.png",
|
"48": "img/icon48.png",
|
||||||
"128": "img/icon128.png"
|
"128": "img/icon128.png"
|
||||||
},
|
},
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": ["*://old.reddit.com/*"],
|
"matches": ["*://git.add123.com/*"],
|
||||||
"css": ["styles.css"],
|
"css": ["styles.css"],
|
||||||
"run_at": "document_start"
|
"run_at": "document_start"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matches": ["*://git.add123.com/*"],
|
||||||
|
"js": [
|
||||||
|
"utils.js",
|
||||||
|
"csharp-quotes.js",
|
||||||
|
"backtick-comments.js",
|
||||||
|
"var-highlighter.js"
|
||||||
|
],
|
||||||
|
"run_at": "document_start"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"activeTab",
|
||||||
"webRequest",
|
"webRequest",
|
||||||
"webRequestBlocking",
|
"webRequestBlocking",
|
||||||
"*://reddit.com/*",
|
"*://git.add123.com/*"
|
||||||
"*://www.reddit.com/*",
|
|
||||||
"*://np.reddit.com/*",
|
|
||||||
"*://amp.reddit.com/*",
|
|
||||||
"*://i.reddit.com/*"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
const NEW_PAGE_DELAY = 1000
|
||||||
|
const CURRENT_PAGE_DELAY = 300
|
||||||
|
|
||||||
|
const getClassNameElementsArray = className =>
|
||||||
|
Object.values(document.getElementsByClassName(className))
|
||||||
|
|
||||||
|
// Runs on "complete" load and when https://urlurl.url#this-hash-value changes
|
||||||
|
const addFix = fixFunc => {
|
||||||
|
window.addEventListener('load', () => setTimeout(fixFunc, NEW_PAGE_DELAY))
|
||||||
|
addEventListener('hashchange', () => setTimeout(fixFunc, CURRENT_PAGE_DELAY))
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFileName = () => getClassNameElementsArray('file-breadcrumbs-segment-highlighted').map(e => e.innerText)[0]
|
|
@ -0,0 +1,89 @@
|
||||||
|
const getVarElements = () => [
|
||||||
|
...getClassNameElementsArray('hl-variable'),
|
||||||
|
...getClassNameElementsArray('hl-def'),
|
||||||
|
...getClassNameElementsArray('hl-type')
|
||||||
|
]
|
||||||
|
|
||||||
|
let currentSelected
|
||||||
|
|
||||||
|
const selectVar = varName => {
|
||||||
|
if (!varName) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Clear existing colors
|
||||||
|
getClassNameElementsArray(selectedClass)
|
||||||
|
.forEach(e => e.classList.remove(selectedClass))
|
||||||
|
|
||||||
|
// Color vars with matching text
|
||||||
|
getVarElements()
|
||||||
|
.filter(e => e.innerText === varName)
|
||||||
|
.forEach(e => e.classList.add(selectedClass))
|
||||||
|
|
||||||
|
currentSelected = varName
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedClass = 'sages-selected-variable'
|
||||||
|
|
||||||
|
const getTagMatching = (name, matcher) => {
|
||||||
|
const elements = Object.values(document.getElementsByTagName(name)).filter(matcher)
|
||||||
|
return elements.length ? elements[0] : null
|
||||||
|
}
|
||||||
|
|
||||||
|
const addVariableClickers = skipExpandos => {
|
||||||
|
const getSearchButton = () => getTagMatching(
|
||||||
|
'button', e => e.dataset?.testid === 'search-action-button')
|
||||||
|
|
||||||
|
const getSearchBox = () => getTagMatching('input', e => e.name === 'changes-search-input')
|
||||||
|
|
||||||
|
if (!skipExpandos) {
|
||||||
|
getClassNameElementsArray('expand-context-button').forEach(e => {
|
||||||
|
const currentOnClick = e.onclick
|
||||||
|
e.onclick = (...args) => {
|
||||||
|
currentOnClick && currentOnClick(...args)
|
||||||
|
setTimeout(() => {
|
||||||
|
selectVar(currentSelected)
|
||||||
|
addVariableClickers(true)
|
||||||
|
}, CURRENT_PAGE_DELAY)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getVarElements()
|
||||||
|
.forEach(e => {
|
||||||
|
e.onclick = () => selectVar(e.innerText)
|
||||||
|
e.ondblclick = () => {
|
||||||
|
let searchBox = getSearchBox()
|
||||||
|
|
||||||
|
if (!searchBox) {
|
||||||
|
getSearchButton()?.click()
|
||||||
|
searchBox = getSearchBox()
|
||||||
|
}
|
||||||
|
|
||||||
|
searchBox.value = e.innerText
|
||||||
|
searchBox.dispatchEvent(new window.Event('change', { bubbles: true }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
addFix(() => {
|
||||||
|
const styleSheet = document.createElement('style')
|
||||||
|
styleSheet.innerText = `
|
||||||
|
.${selectedClass} {
|
||||||
|
background: rgb(255, 253, 170) !important;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 2px !important;
|
||||||
|
margin: -2px !important;
|
||||||
|
/*
|
||||||
|
padding-left: 2px !important;
|
||||||
|
padding-right: 2px !important;
|
||||||
|
margin-left: -2px !important;
|
||||||
|
margin-right: -2px !important;
|
||||||
|
*/
|
||||||
|
}`
|
||||||
|
|
||||||
|
document.head.appendChild(styleSheet)
|
||||||
|
addVariableClickers()
|
||||||
|
selectVar(currentSelected)
|
||||||
|
})
|
Loading…
Reference in New Issue