Compare commits
7 Commits
b922d15f98
...
9136ab2565
Author | SHA1 | Date | |
---|---|---|---|
9136ab2565 | |||
1438d3037a | |||
fdf688cba2 | |||
82584d6a59 | |||
5e3cab2a63 | |||
2a5f09ce7c | |||
7a54b7bd99 |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
rosenrot
|
rosenrot
|
||||||
# don't save the binary file, as it doesn't play nicely with https://difftastic.wilfred.me.uk
|
# don't save the binary file, as it doesn't play nicely with https://difftastic.wilfred.me.uk
|
||||||
|
webkit/
|
||||||
|
|
2
config.h
2
config.h
|
@ -92,6 +92,7 @@ typedef enum {
|
||||||
show_finder,
|
show_finder,
|
||||||
finder_next,
|
finder_next,
|
||||||
finder_prev,
|
finder_prev,
|
||||||
|
filter,
|
||||||
|
|
||||||
halve_window,
|
halve_window,
|
||||||
rebig_window,
|
rebig_window,
|
||||||
|
@ -134,6 +135,7 @@ static struct {
|
||||||
{ CTRL, KEY(f), show_finder },
|
{ CTRL, KEY(f), show_finder },
|
||||||
{ CTRL, KEY(n), finder_next },
|
{ CTRL, KEY(n), finder_next },
|
||||||
{ CTRL, KEY(N), finder_prev },
|
{ CTRL, KEY(N), finder_prev },
|
||||||
|
{ CTRL, KEY(F), filter },
|
||||||
{ CTRL, KEY(Up), halve_window },
|
{ CTRL, KEY(Up), halve_window },
|
||||||
{ CTRL, KEY(Down), rebig_window },
|
{ CTRL, KEY(Down), rebig_window },
|
||||||
{ CTRL, KEY(p), prettify },
|
{ CTRL, KEY(p), prettify },
|
||||||
|
|
|
@ -22,7 +22,7 @@ int libre_redirect(const char* uri, char* output)
|
||||||
// "https://google.com",
|
// "https://google.com",
|
||||||
"https://medium.com",
|
"https://medium.com",
|
||||||
"https://translate.google.com",
|
"https://translate.google.com",
|
||||||
// "https://www.bloomberg.com",
|
"https://www.bloomberg.com",
|
||||||
"https://www.royalroad.com",
|
"https://www.royalroad.com",
|
||||||
"https://genius.com",
|
"https://genius.com",
|
||||||
// "https://twitter.com"
|
// "https://twitter.com"
|
||||||
|
@ -39,7 +39,7 @@ int libre_redirect(const char* uri, char* output)
|
||||||
// "https://search.nunosempere.com",
|
// "https://search.nunosempere.com",
|
||||||
"https://scribe.rip",
|
"https://scribe.rip",
|
||||||
"https://translate.riverside.rocks",
|
"https://translate.riverside.rocks",
|
||||||
// "https://archive.ph/https://www.bloomberg.com",
|
"https://archive.ph/https://www.bloomberg.com",
|
||||||
"https://royalread.nunosempere.com",
|
"https://royalread.nunosempere.com",
|
||||||
"https://dumb.vern.cc",
|
"https://dumb.vern.cc",
|
||||||
"https://example.com"
|
"https://example.com"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#define STYLE_N 8049 + 1000
|
#define STYLE_N 9278 + 1000
|
||||||
|
|
||||||
void read_style_js(char* string)
|
void read_style_js(char* string)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define STYLE_N 8049 + 1000
|
#define STYLE_N 9278 + 1000
|
||||||
|
|
||||||
void read_style_js(char* string);
|
void read_style_js(char* string);
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
var styles = null;
|
var styles = null;
|
||||||
// console.log(document.domain);
|
// console.log(document.domain);
|
||||||
switch (document.domain) {
|
switch (document.domain) {
|
||||||
case "forum.effectivealtruism.org":
|
case "forum.effectivealtruism.org":
|
||||||
styles = `
|
styles = `
|
||||||
/*
|
/*
|
||||||
.Layout-main {
|
.Layout-main {
|
||||||
margin-left: 100px;
|
margin-left: 100px;
|
||||||
|
@ -25,16 +25,16 @@ switch (document.domain) {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
case "nationstates.net":
|
case "nationstates.net":
|
||||||
styles = `
|
styles = `
|
||||||
.adidentifier {
|
.adidentifier {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
case "mail.proton.me":
|
case "mail.proton.me":
|
||||||
styles = `
|
styles = `
|
||||||
/*
|
/*
|
||||||
.item-container-row.read, .item-container.read {
|
.item-container-row.read, .item-container.read {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
@ -48,24 +48,25 @@ switch (document.domain) {
|
||||||
zoom: 0.625 !important;
|
zoom: 0.625 !important;
|
||||||
*/
|
*/
|
||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
case "forum.nunosempere.com":
|
case "forum.nunosempere.com":
|
||||||
styles = `
|
styles = `
|
||||||
body {
|
body {
|
||||||
zoom: 0.625 !important;
|
zoom: 0.625 !important;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
case "search.brave.com":
|
case "search.brave.com":
|
||||||
styles = `
|
styles = `
|
||||||
.download-button,
|
.download-button,
|
||||||
a[href^="https://brave.com/download/"] {
|
a[href^="https://brave.com/download/"], .download-cta
|
||||||
|
{
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
case "search.nunosempere.com":
|
case "search.nunosempere.com":
|
||||||
styles = `
|
styles = `
|
||||||
/*
|
/*
|
||||||
body {
|
body {
|
||||||
zoom: 1.8;
|
zoom: 1.8;
|
||||||
|
@ -76,11 +77,11 @@ switch (document.domain) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
case "reddit.com":
|
case "reddit.com":
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case "old.reddit.com":
|
case "old.reddit.com":
|
||||||
styles = `
|
styles = `
|
||||||
/* kill sidebar ads */
|
/* kill sidebar ads */
|
||||||
.ad-container,
|
.ad-container,
|
||||||
a[href^="https://alb.reddit.com"]
|
a[href^="https://alb.reddit.com"]
|
||||||
|
@ -98,10 +99,10 @@ switch (document.domain) {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
case "twitter.com":
|
case "twitter.com":
|
||||||
case "x.com":
|
case "x.com":
|
||||||
styles = `
|
styles = `
|
||||||
/* hide promoted tweets */
|
/* hide promoted tweets */
|
||||||
:has(meta[property="og:site_name"][content="Twitter"])
|
:has(meta[property="og:site_name"][content="Twitter"])
|
||||||
[data-testid="cellInnerDiv"]:has(svg + [dir="auto"]) {
|
[data-testid="cellInnerDiv"]:has(svg + [dir="auto"]) {
|
||||||
|
@ -182,25 +183,27 @@ switch (document.domain) {
|
||||||
background: white !important;
|
background: white !important;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
default:
|
case "":
|
||||||
console.log(`Domain: ${document.domain}`);
|
break;
|
||||||
console.log("No custom style");
|
default:
|
||||||
|
console.log(`Domain: ${document.domain}`);
|
||||||
|
console.log("No custom style");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles != null) {
|
if (styles != null) {
|
||||||
var styleSheet = document.createElement("style");
|
var styleSheet = document.createElement("style");
|
||||||
styleSheet.innerText = styles;
|
styleSheet.innerText = styles;
|
||||||
document.head.appendChild(styleSheet);
|
document.head.appendChild(styleSheet);
|
||||||
console.log("Style changed");
|
console.log("Style changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra: Replace default alert with new function
|
// Extra: Replace default alert with new function
|
||||||
// whose style can be changed!
|
// whose style can be changed!
|
||||||
window.alert = (message) => {
|
window.alert = (message) => {
|
||||||
let alertDiv = document.getElementById("customAlert");
|
let alertDiv = document.getElementById("customAlert");
|
||||||
if (!alertDiv) {
|
if (!alertDiv) {
|
||||||
const html = `
|
const html = `
|
||||||
<div id="customAlert" class="custom-alert">
|
<div id="customAlert" class="custom-alert">
|
||||||
<div class="custom-alert-content">
|
<div class="custom-alert-content">
|
||||||
<p id="alertMessage"></p>
|
<p id="alertMessage"></p>
|
||||||
|
@ -232,68 +235,112 @@ window.alert = (message) => {
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
`;
|
`;
|
||||||
document.body.insertAdjacentHTML("beforeend", html);
|
document.body.insertAdjacentHTML("beforeend", html);
|
||||||
alertDiv = document.getElementById("customAlert");
|
alertDiv = document.getElementById("customAlert");
|
||||||
document.getElementById("alertOkButton").onclick = () => {
|
document.getElementById("alertOkButton").onclick = () => {
|
||||||
alertDiv.classList.remove("visible");
|
alertDiv.classList.remove("visible");
|
||||||
document.removeEventListener("keydown", dismissAlert);
|
document.removeEventListener("keydown", dismissAlert);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const dismissAlert = (event) => {
|
const dismissAlert = (event) => {
|
||||||
if (
|
if (
|
||||||
event.key === "Enter" /*&& event.ctrlKey*/ &&
|
event.key === "Enter" /*&& event.ctrlKey*/ &&
|
||||||
alertDiv.classList.contains("visible")
|
alertDiv.classList.contains("visible")
|
||||||
) {
|
) {
|
||||||
alertDiv.classList.remove("visible");
|
alertDiv.classList.remove("visible");
|
||||||
document.removeEventListener("keydown", dismissAlert);
|
document.removeEventListener("keydown", dismissAlert);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("keydown", dismissAlert);
|
document.addEventListener("keydown", dismissAlert);
|
||||||
document.getElementById("alertMessage").textContent = message;
|
document.getElementById("alertMessage").textContent = message;
|
||||||
alertDiv.classList.add("visible");
|
alertDiv.classList.add("visible");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extra: hide video players on twitter
|
// Extra: hide video players on twitter
|
||||||
if (document.domain == "twitter.com" || document.domain == "x.com") {
|
if (document.domain == "twitter.com" || document.domain == "x.com") {
|
||||||
// Function to hide the grandparent of video players
|
// Function to hide the grandparent of video players
|
||||||
// takes 0.014ms to run, so performance is not the concern here.
|
// takes 0.014ms to run, so performance is not the concern here.
|
||||||
// timed with console.time, console.timeEnd
|
// timed with console.time, console.timeEnd
|
||||||
|
|
||||||
function hideVideoPlayerGrandparent() {
|
function hideVideoPlayerGrandparent() {
|
||||||
document
|
document
|
||||||
.querySelectorAll('[data-testid="videoPlayer"]')
|
.querySelectorAll('[data-testid="videoPlayer"]')
|
||||||
.forEach(function (videoPlayer) {
|
.forEach(function (videoPlayer) {
|
||||||
var grandparentElement =
|
var grandparentElement =
|
||||||
videoPlayer.parentElement.parentElement.parentElement.parentElement
|
videoPlayer.parentElement.parentElement.parentElement.parentElement
|
||||||
.parentElement.parentElement;
|
.parentElement.parentElement;
|
||||||
var newTextElement = document.createElement("div");
|
var newTextElement = document.createElement("div");
|
||||||
newTextElement.textContent = " [ twitter video ] ";
|
newTextElement.textContent = " [ twitter video ] ";
|
||||||
newTextElement.style["margin-top"] = "10px";
|
newTextElement.style["margin-top"] = "10px";
|
||||||
newTextElement.style["margin-left"] = "10px";
|
newTextElement.style["margin-left"] = "10px";
|
||||||
newTextElement.style["margin-bottom"] = "10px";
|
newTextElement.style["margin-bottom"] = "10px";
|
||||||
grandparentElement.replaceWith(newTextElement);
|
grandparentElement.replaceWith(newTextElement);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new MutationObserver instance
|
// Create a new MutationObserver instance
|
||||||
var observer = new MutationObserver(function (mutations) {
|
var observer = new MutationObserver(function (mutations) {
|
||||||
mutations.forEach(function (mutation) {
|
mutations.forEach(function (mutation) {
|
||||||
if (mutation.addedNodes.length) {
|
if (mutation.addedNodes.length) {
|
||||||
hideVideoPlayerGrandparent(); // Call the function to hide video players
|
hideVideoPlayerGrandparent(); // Call the function to hide video players
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Options for the observer (which mutations to observe)
|
// Options for the observer (which mutations to observe)
|
||||||
var config = { childList: true, subtree: true };
|
var config = { childList: true, subtree: true };
|
||||||
|
|
||||||
// Start observing the target node for configured mutations
|
// Start observing the target node for configured mutations
|
||||||
observer.observe(document.body, config);
|
observer.observe(document.body, config);
|
||||||
|
|
||||||
// Call the function initially to hide any video players on initial load
|
// Call the function initially to hide any video players on initial load
|
||||||
hideVideoPlayerGrandparent();
|
hideVideoPlayerGrandparent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// document.body.style.visibility = "visible";
|
// document.body.style.visibility = "visible";
|
||||||
|
|
||||||
|
// Add some code to filter out articles for Sentinel
|
||||||
|
|
||||||
|
function filterByKeyword(str) {
|
||||||
|
// e.g., "keyword" (equivalent to "keyword, p, 1")
|
||||||
|
// e.g., "keyword, div, 3"
|
||||||
|
// might not work with level=0, but not sure why
|
||||||
|
const args = str.split(", ");
|
||||||
|
let keword = null;
|
||||||
|
let selector = "p"; /* or "*" for all */
|
||||||
|
let level = 1;
|
||||||
|
if (args.length > 0) {
|
||||||
|
keyword = args[0].trim();
|
||||||
|
}
|
||||||
|
if (args.length > 1) {
|
||||||
|
selector = args[1].trim();
|
||||||
|
}
|
||||||
|
if (args.length > 2) {
|
||||||
|
level = Number(args[2].trim());
|
||||||
|
}
|
||||||
|
console.log(keyword, selector, level);
|
||||||
|
// Get all elements matching the selector
|
||||||
|
const elements = document.querySelectorAll(selector);
|
||||||
|
|
||||||
|
// Convert NodeList to Array to use array methods
|
||||||
|
const elementsArray = Array.from(elements);
|
||||||
|
|
||||||
|
// Filter elements containing the keyword
|
||||||
|
const matchingElements = elementsArray.filter((element) =>
|
||||||
|
element.textContent.toLowerCase().includes(keyword.toLowerCase()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove parent of each matching element
|
||||||
|
matchingElements.forEach((element) => {
|
||||||
|
let ancestor = element; // Start with the current element
|
||||||
|
// Loop to climb up the DOM tree according to the level required
|
||||||
|
for (let i = 0; i < level && ancestor !== null; i++) {
|
||||||
|
ancestor = ancestor.parentNode; // Move up in the DOM tree
|
||||||
|
}
|
||||||
|
if (ancestor) {
|
||||||
|
ancestor.style.display = "none";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
49
rosenrot4.c
49
rosenrot4.c
|
@ -9,7 +9,7 @@
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
static GtkNotebook* notebook;
|
static GtkNotebook* notebook;
|
||||||
static GtkWindow* window;
|
static GtkWindow* window;
|
||||||
typedef enum { _SEARCH, _FIND, _HIDDEN } Bar_entry_mode;
|
typedef enum { _SEARCH, _FIND, _FILTER, _HIDDEN } Bar_entry_mode;
|
||||||
static struct {
|
static struct {
|
||||||
GtkHeaderBar* widget;
|
GtkHeaderBar* widget;
|
||||||
GtkEntry* line;
|
GtkEntry* line;
|
||||||
|
@ -227,6 +227,13 @@ void toggle_bar(GtkNotebook* notebook, Bar_entry_mode mode)
|
||||||
gtk_window_set_focus(window, GTK_WIDGET(bar.line));
|
gtk_window_set_focus(window, GTK_WIDGET(bar.line));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case _FILTER: {
|
||||||
|
gtk_entry_set_placeholder_text(bar.line, "Filter");
|
||||||
|
gtk_entry_buffer_set_text(bar.line_text, "", strlen(""));
|
||||||
|
gtk_widget_set_visible(GTK_WIDGET(bar.widget), 1);
|
||||||
|
gtk_window_set_focus(window, GTK_WIDGET(bar.line));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case _HIDDEN:
|
case _HIDDEN:
|
||||||
gtk_widget_set_visible(GTK_WIDGET(bar.widget), 0);
|
gtk_widget_set_visible(GTK_WIDGET(bar.widget), 0);
|
||||||
}
|
}
|
||||||
|
@ -236,16 +243,35 @@ void toggle_bar(GtkNotebook* notebook, Bar_entry_mode mode)
|
||||||
void handle_signal_bar_press_enter(GtkEntry* self, GtkNotebook* notebook) /* consider passing notebook as the data here? */
|
void handle_signal_bar_press_enter(GtkEntry* self, GtkNotebook* notebook) /* consider passing notebook as the data here? */
|
||||||
{
|
{
|
||||||
WebKitWebView* view = notebook_get_webview(notebook);
|
WebKitWebView* view = notebook_get_webview(notebook);
|
||||||
if (bar.entry_mode == _SEARCH)
|
const char* bar_line_text = gtk_entry_buffer_get_text(bar.line_text);
|
||||||
load_uri(view, gtk_entry_buffer_get_text(bar.line_text));
|
switch (bar.entry_mode) {
|
||||||
else if (bar.entry_mode == _FIND)
|
case _SEARCH: {
|
||||||
webkit_find_controller_search(
|
load_uri(view, bar_line_text);
|
||||||
webkit_web_view_get_find_controller(view),
|
gtk_widget_set_visible(GTK_WIDGET(bar.widget), 0);
|
||||||
gtk_entry_buffer_get_text(bar.line_text),
|
break;
|
||||||
WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | WEBKIT_FIND_OPTIONS_WRAP_AROUND,
|
}
|
||||||
G_MAXUINT);
|
case _FIND: {
|
||||||
|
webkit_find_controller_search(
|
||||||
|
webkit_web_view_get_find_controller(view),
|
||||||
|
bar_line_text,
|
||||||
|
WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | WEBKIT_FIND_OPTIONS_WRAP_AROUND,
|
||||||
|
G_MAXUINT);
|
||||||
|
gtk_widget_set_visible(GTK_WIDGET(bar.widget), 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case _FILTER: {
|
||||||
|
const char* js_template = "filterByKeyword(\"%s\")";
|
||||||
|
char js_command[strlen(js_template) + strlen(bar_line_text) + 2];
|
||||||
|
snprintf(js_command, sizeof(js_command) + 1, js_template, bar_line_text);
|
||||||
|
webkit_web_view_evaluate_javascript(view, js_command, -1, NULL, "rosenrot-filter-plugin", NULL, NULL, NULL);
|
||||||
|
gtk_widget_set_visible(GTK_WIDGET(bar.widget), 0);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case _HIDDEN:
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
|
||||||
gtk_widget_set_visible(GTK_WIDGET(bar.widget), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shortcuts */
|
/* Shortcuts */
|
||||||
|
@ -332,6 +358,9 @@ int handle_shortcut(func id)
|
||||||
case show_finder:
|
case show_finder:
|
||||||
toggle_bar(notebook, _FIND);
|
toggle_bar(notebook, _FIND);
|
||||||
break;
|
break;
|
||||||
|
case filter:
|
||||||
|
toggle_bar(notebook, _FILTER);
|
||||||
|
break;
|
||||||
|
|
||||||
case finder_next:
|
case finder_next:
|
||||||
webkit_find_controller_search_next(webkit_web_view_get_find_controller(view));
|
webkit_find_controller_search_next(webkit_web_view_get_find_controller(view));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user