diff --git a/.config/qutebrowser/greasemonkey/darkmode-disable.js b/.config/qutebrowser/greasemonkey/darkmode-disable.js new file mode 100644 index 0000000..60c68bb --- /dev/null +++ b/.config/qutebrowser/greasemonkey/darkmode-disable.js @@ -0,0 +1,11 @@ +// ==UserScript== +// @name DarkMode Disable +// @match https://monkeytype.com/* +// @match https://nc.cronyakatsuki.xyz/* +// @match https://company-mode.github.io/* +// ==/UserScript== + +const meta = document.createElement("meta"); +meta.name = "color-scheme"; +meta.content = "dark light"; +document.head.appendChild(meta); diff --git a/.config/qutebrowser/greasemonkey/scrollHelper.js b/.config/qutebrowser/greasemonkey/scrollHelper.js new file mode 100644 index 0000000..6a7cbff --- /dev/null +++ b/.config/qutebrowser/greasemonkey/scrollHelper.js @@ -0,0 +1,83 @@ +// ==UserScript== +// @name Adds scrolling JS that can be used within QB to do smarter scrolling +// @qute-js-world jseval +// @run-at document-start +// ==/UserScript== +unsafeWindow.scrollHelper = (() => { + const scrollableElemOverflowTypes = [ + 'auto', + 'scroll', + ] + + const getFocusedWindow = (nextElem) => { + if (nextElem === null) return null + if (nextElem === undefined) return getFocusedWindow(window.document.activeElement ?? null) + return getFocusedWindow(nextElem.contentDocument?.activeElement ?? null) ?? nextElem.ownerDocument?.defaultView ?? null + } + + const getScrollMaxY = ({ document: { documentElement } }) => documentElement.scrollHeight - documentElement.clientHeight + + const getWindowVisibleArea = ({ document: { documentElement } }) => documentElement.clientHeight * documentElement.clientWidth + + const findVertScrollableWindow = () => { + const focusedWindow = getFocusedWindow() ?? window + if (getScrollMaxY(focusedWindow) > 0) return focusedWindow + if (getScrollMaxY(window) > 0) return window + + return Array + .from(window.frames) + .sort((x, y) => getWindowVisibleArea(y) - getWindowVisibleArea(x)) + .find((frame) => getScrollMaxY(frame) > 0) ?? window + } + + const getScrollTopMax = (elem) => elem.scrollHeight - elem.clientHeight + const isElementVertScrollable = (element) => element.clientHeight !==0 && + scrollableElemOverflowTypes.includes(getComputedStyle(element).overflowY) + + const findVertScrollableAncestor = (delta, nextElem) => { + if (!(nextElem?.parentNode instanceof Element)) return nextElem + + if (isElementVertScrollable(nextElem)) { + if (delta < 0 && nextElem.scrollTop > 0) return nextElem + if (delta > 0 && nextElem.scrollTop < getScrollTopMax(nextElem)) return nextElem + if (delta === 0 && getScrollTopMax(nextElem) > 0) return nextElem + } + + return findVertScrollableAncestor(delta, nextElem.parentNode) + } + + const getSelectionElem = () => { + const selection = getFocusedWindow().getSelection() + return selection.rangeCount !== 0 + ? selection.getRangeAt(0).startContainer + : null + } + + const getParentIfNotElement = (maybeElement) => maybeElement instanceof Element ? maybeElement : maybeElement?.parentNode + + const findVertScrollable = (delta = 0) => { + const selectionScrollableElem = findVertScrollableAncestor(delta, getParentIfNotElement(getSelectionElem())) + if (selectionScrollableElem instanceof Element) return selectionScrollableElem + + const scrollableDoc = findVertScrollableWindow().document + const scrollableElem = scrollableDoc.body || scrollableDoc.getElementsByTagName('body')[0] || scrollableDoc.documentElement + return findVertScrollableAncestor(delta, getParentIfNotElement(scrollableElem)) + } + + return { + scrollTo: (position) => findVertScrollable().scrollTo({top: position}), + scrollToPercent: (percentPosition) => { + const scrollElement = findVertScrollable() + const paneHeight = scrollElement.scrollHeight + scrollElement.scrollTo({top: percentPosition / 100 * paneHeight}) + }, + scrollBy: (delta) => findVertScrollable(delta).scrollBy({top: delta, behavior: 'smooth'}), + scrollPage: (pages) => { + const fakeDelta = pages < 0 ? -10 : 10 + const scrollElement = findVertScrollable(fakeDelta) + const pageHeight = scrollElement.clientHeight + scrollElement.scrollBy({top: pageHeight * pages}) + }, + } + +})() diff --git a/.config/qutebrowser/pyconfig/redirectors.py b/.config/qutebrowser/pyconfig/redirectors.py new file mode 100644 index 0000000..649e75b --- /dev/null +++ b/.config/qutebrowser/pyconfig/redirectors.py @@ -0,0 +1,34 @@ +import operator + +from qutebrowser.api import interceptor, message + +REDIRECT_MAP = { + "reddit.com": operator.methodcaller("setHost", "libreddit.cronyakatsuki.xyz"), + "www.reddit.com": operator.methodcaller("setHost", "libreddit.cronyakatsuki.xyz"), + "twitter.com": operator.methodcaller("setHost", "nitter.cronyakatsuki.xyz"), + "www.twitter.com": operator.methodcaller("setHost", "nitter.cronyakatsuki.xyz"), + "youtube.com": operator.methodcaller("setHost", "piped.cronyakatsuki.xyz"), + "www.youtube.com": operator.methodcaller("setHost", "piped.cronyakatsuki.xyz"), + "music.youtube.com": operator.methodcaller( + "setHost", "hyperpipe.cronyakatsuki.xyz" + ), + "medium.com": operator.methodcaller("setHost", "scribe.cronyakatsuki.xyz"), + "www.medium.com": operator.methodcaller("setHost", "scribe.cronyakatsuki.xyz"), + "twitch.tv": operator.methodcaller("setHost", "safetwitch.cronyakatsuki.xyz"), + "www.twitch.tv": operator.methodcaller("setHost", "safetwitch.cronyakatsuki.xyz"), + "tiktok.com": operator.methodcaller("setHost", "proxytok.cronyakatsuki.xyz"), + "www.tiktok.com": operator.methodcaller("setHost", "proxytok.cronyakatsuki.xyz"), + "imgur.com": operator.methodcaller("setHost", "rimgo.cronyakatsuki.xyz"), + "www.imgur.com": operator.methodcaller("setHost", "rimgo.cronyakatsuki.xyz"), +} + + +def int_fn(info: interceptor.Request): + url = info.request_url + redir = REDIRECT_MAP.get(url.host()) + if redir is not None and redir(url) is not False: + message.info("Redirecting to " + url.toString()) + info.redirect(url) + + +interceptor.register(int_fn) diff --git a/.config/qutebrowser/userscripts/buku b/.config/qutebrowser/userscripts/buku new file mode 100755 index 0000000..9995731 --- /dev/null +++ b/.config/qutebrowser/userscripts/buku @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# Qutebrowser userscript for interacting with buku +# requries buku and dmenu (with list patch) + +get_bookmark() { + buku --nostdin -p -f5 | sed 's/\t/;/g' | column -t -s ';' | dmenu -p "$1 bookmark: " -i -l 10 | awk '{ print $1 }' +} + +get_url() { + buku --nostdin -p "$1" -f10 +} + +get_title() { + buku --nostdin -p "$1" -f30 +} + +fifo() { + printf '%s\n' "$1" >>"$QUTE_FIFO" +} + +add() { + buku --nostdin -a "$QUTE_URL" + $TERMINAL --class badd,badd -e buku -w -1 + fifo "message-info 'Added current url to buku'" +} + +open() { + bookmark=$(get_bookmark "Open") + [ -z "$bookmark" ] && fifo "message-info 'No Bookmark selected!!!'" && exit + if [ "$1" == "-t" ]; then + fifo "open -t $(get_url "$bookmark")" + fifo "message-info 'Opening bookmark $(get_title "$bookmark") in new tab.'" + else + fifo "open $(get_url "$bookmark")" + fifo "message-info 'Opening bookmark $(get_title "$bookmark").'" + fi +} + +delete() { + bookmark=$(get_bookmark "Delete") + title=$(get_title "$bookmark") + buku --nostdin -d "$bookmark" --tacit + fifo "message-info 'Deleted bookmark $title.'" +} + +edit() { + bookmark=$(get_bookmark "Edit") + fifo "message-info 'Editing bookmark $(get_title "$bookmark")'" + $TERMINAL --class badd,badd -e buku -w "$bookmark" +} + +main() { + case "$1" in + "add") + add + exit + ;; + "open") + open "$2" + exit + ;; + "delete") + delete + exit + ;; + "edit") + edit + ;; + esac +} + +main $@ diff --git a/.config/qutebrowser/userscripts/yt-dlp b/.config/qutebrowser/userscripts/yt-dlp new file mode 100755 index 0000000..0c49e32 --- /dev/null +++ b/.config/qutebrowser/userscripts/yt-dlp @@ -0,0 +1,23 @@ +#!/bin/sh + +audio() { + printf "message-info 'Downloding audio for %s'" "$QUTE_URL" >>"$QUTE_FIFO" + yt-dlp -x -f bestaudio --external-downloader aria2c --external-downloader-args "-j 16 -s 16 -x 16 -k 5M" --audio-format vorbis -o "%(title)s.%(ext)s" "$QUTE_URL" + notify-send "QuteBrowser yt-dlp" "Finished downloading audio" +} + +audio_video() { + printf "message-info 'Downloding audio+video for %s'" "$QUTE_URL" >>"$QUTE_FIFO" + yt-dlp --merge-output-format mp4 -f "bestvideo+bestaudio[ext=m4a]/best" --embed-thumbnail --external-downloader aria2c --external-downloader-args "-j 16 -s 16 -x 16 -k 5M" --add-metadata -o "%(title)s.%(ext)s" "$QUTE_URL" + notify-send "QuteBrowser yt-dlp" "Finished downloading audio+video" +} + +case "$1" in +"audio") + audio + exit + ;; +"audio+video") + audio_video + ;; +esac