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 | ||||
| # 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, | ||||
|     finder_next, | ||||
|     finder_prev, | ||||
|     filter, | ||||
| 
 | ||||
|     halve_window, | ||||
|     rebig_window, | ||||
|  | @ -134,6 +135,7 @@ static struct { | |||
|     { CTRL,        KEY(f),             show_finder          }, | ||||
|     { CTRL,        KEY(n),             finder_next          }, | ||||
|     { CTRL,        KEY(N),             finder_prev          }, | ||||
|     { CTRL,        KEY(F),             filter               }, | ||||
|     { CTRL,        KEY(Up),            halve_window         }, | ||||
|     { CTRL,        KEY(Down),          rebig_window         }, | ||||
|     { CTRL,        KEY(p),             prettify             }, | ||||
|  |  | |||
|  | @ -22,7 +22,7 @@ int libre_redirect(const char* uri, char* output) | |||
|             // "https://google.com",
 | ||||
|             "https://medium.com", | ||||
|             "https://translate.google.com", | ||||
|             // "https://www.bloomberg.com",
 | ||||
|             "https://www.bloomberg.com", | ||||
|             "https://www.royalroad.com", | ||||
|             "https://genius.com", | ||||
|             // "https://twitter.com"
 | ||||
|  | @ -39,7 +39,7 @@ int libre_redirect(const char* uri, char* output) | |||
|             // "https://search.nunosempere.com",
 | ||||
|             "https://scribe.rip", | ||||
|             "https://translate.riverside.rocks", | ||||
|             // "https://archive.ph/https://www.bloomberg.com",
 | ||||
|             "https://archive.ph/https://www.bloomberg.com", | ||||
|             "https://royalread.nunosempere.com", | ||||
|             "https://dumb.vern.cc", | ||||
|             "https://example.com" | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #define STYLE_N 8049 + 1000 | ||||
| #define STYLE_N 9278 + 1000 | ||||
| 
 | ||||
| void read_style_js(char* string) | ||||
| { | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #define STYLE_N 8049 + 1000 | ||||
| #define STYLE_N 9278 + 1000 | ||||
| 
 | ||||
| void read_style_js(char* string); | ||||
|  |  | |||
|  | @ -6,8 +6,8 @@ | |||
| var styles = null; | ||||
| // console.log(document.domain);
 | ||||
| switch (document.domain) { | ||||
|   case "forum.effectivealtruism.org": | ||||
|     styles = ` | ||||
| 	case "forum.effectivealtruism.org": | ||||
| 		styles = ` | ||||
|     /* | ||||
| 	    .Layout-main { | ||||
|         margin-left: 100px; | ||||
|  | @ -25,16 +25,16 @@ switch (document.domain) { | |||
|       } | ||||
|     */ | ||||
|     `;
 | ||||
|     break; | ||||
|   case "nationstates.net": | ||||
|     styles = ` | ||||
| 		break; | ||||
| 	case "nationstates.net": | ||||
| 		styles = ` | ||||
|       .adidentifier { | ||||
|         display: none; | ||||
|       } | ||||
|     `;
 | ||||
|     break; | ||||
|   case "mail.proton.me": | ||||
|     styles = ` | ||||
| 		break; | ||||
| 	case "mail.proton.me": | ||||
| 		styles = ` | ||||
| 	  /* | ||||
|       .item-container-row.read, .item-container.read { | ||||
| 		      background-color: white; | ||||
|  | @ -48,24 +48,25 @@ switch (document.domain) { | |||
|       zoom: 0.625 !important; | ||||
| 	  */ | ||||
| 	  `;
 | ||||
|     break; | ||||
|   case "forum.nunosempere.com": | ||||
|     styles = ` | ||||
| 		break; | ||||
| 	case "forum.nunosempere.com": | ||||
| 		styles = ` | ||||
|       body { | ||||
|        zoom: 0.625 !important; | ||||
|       } | ||||
|     `;
 | ||||
|     break; | ||||
|   case "search.brave.com": | ||||
|     styles = ` | ||||
| 		break; | ||||
| 	case "search.brave.com": | ||||
| 		styles = ` | ||||
|       .download-button, | ||||
|       a[href^="https://brave.com/download/"] { | ||||
|       a[href^="https://brave.com/download/"], .download-cta | ||||
| 			{ | ||||
|         display: none !important;  | ||||
|       } | ||||
|     `;
 | ||||
|     break; | ||||
|   case "search.nunosempere.com": | ||||
|     styles = ` | ||||
| 		break; | ||||
| 	case "search.nunosempere.com": | ||||
| 		styles = ` | ||||
|     /*  | ||||
|       body { | ||||
|         zoom: 1.8; | ||||
|  | @ -76,11 +77,11 @@ switch (document.domain) { | |||
|         display: none; | ||||
|       } | ||||
|     `;
 | ||||
|     break; | ||||
|   case "reddit.com": | ||||
|   // fallthrough
 | ||||
|   case "old.reddit.com": | ||||
|     styles = ` | ||||
| 		break; | ||||
| 	case "reddit.com": | ||||
| 	// fallthrough
 | ||||
| 	case "old.reddit.com": | ||||
| 		styles = ` | ||||
| 	    /* kill sidebar ads */ | ||||
| 	    .ad-container, | ||||
| 	    a[href^="https://alb.reddit.com"] | ||||
|  | @ -98,10 +99,10 @@ switch (document.domain) { | |||
| 		    display: none !important; | ||||
| 	    } | ||||
| 	  `;
 | ||||
|     break; | ||||
|   case "twitter.com": | ||||
|   case "x.com": | ||||
|     styles = ` | ||||
| 		break; | ||||
| 	case "twitter.com": | ||||
| 	case "x.com": | ||||
| 		styles = ` | ||||
| 	    /* hide promoted tweets */ | ||||
| 	    :has(meta[property="og:site_name"][content="Twitter"]) | ||||
| 		    [data-testid="cellInnerDiv"]:has(svg + [dir="auto"]) { | ||||
|  | @ -182,25 +183,27 @@ switch (document.domain) { | |||
|         background: white !important; | ||||
|       } | ||||
|     `;
 | ||||
|     break; | ||||
|   default: | ||||
|     console.log(`Domain: ${document.domain}`); | ||||
|     console.log("No custom style"); | ||||
| 		break; | ||||
| 	case "": | ||||
| 		break; | ||||
| 	default: | ||||
| 		console.log(`Domain: ${document.domain}`); | ||||
| 		console.log("No custom style"); | ||||
| } | ||||
| 
 | ||||
| if (styles != null) { | ||||
|   var styleSheet = document.createElement("style"); | ||||
|   styleSheet.innerText = styles; | ||||
|   document.head.appendChild(styleSheet); | ||||
|   console.log("Style changed"); | ||||
| 	var styleSheet = document.createElement("style"); | ||||
| 	styleSheet.innerText = styles; | ||||
| 	document.head.appendChild(styleSheet); | ||||
| 	console.log("Style changed"); | ||||
| } | ||||
| 
 | ||||
| // Extra: Replace default alert with new function
 | ||||
| // whose style can be changed!
 | ||||
| window.alert = (message) => { | ||||
|   let alertDiv = document.getElementById("customAlert"); | ||||
|   if (!alertDiv) { | ||||
|     const html = ` | ||||
| 	let alertDiv = document.getElementById("customAlert"); | ||||
| 	if (!alertDiv) { | ||||
| 		const html = ` | ||||
|       <div id="customAlert" class="custom-alert"> | ||||
|           <div class="custom-alert-content"> | ||||
|               <p id="alertMessage"></p> | ||||
|  | @ -232,68 +235,112 @@ window.alert = (message) => { | |||
|           } | ||||
|       </style> | ||||
|     `;
 | ||||
|     document.body.insertAdjacentHTML("beforeend", html); | ||||
|     alertDiv = document.getElementById("customAlert"); | ||||
|     document.getElementById("alertOkButton").onclick = () => { | ||||
|       alertDiv.classList.remove("visible"); | ||||
|       document.removeEventListener("keydown", dismissAlert); | ||||
|     }; | ||||
|   } | ||||
| 		document.body.insertAdjacentHTML("beforeend", html); | ||||
| 		alertDiv = document.getElementById("customAlert"); | ||||
| 		document.getElementById("alertOkButton").onclick = () => { | ||||
| 			alertDiv.classList.remove("visible"); | ||||
| 			document.removeEventListener("keydown", dismissAlert); | ||||
| 		}; | ||||
| 	} | ||||
| 
 | ||||
|   const dismissAlert = (event) => { | ||||
|     if ( | ||||
|       event.key === "Enter" /*&& event.ctrlKey*/ && | ||||
|       alertDiv.classList.contains("visible") | ||||
|     ) { | ||||
|       alertDiv.classList.remove("visible"); | ||||
|       document.removeEventListener("keydown", dismissAlert); | ||||
|     } | ||||
|   }; | ||||
| 	const dismissAlert = (event) => { | ||||
| 		if ( | ||||
| 			event.key === "Enter" /*&& event.ctrlKey*/ && | ||||
| 			alertDiv.classList.contains("visible") | ||||
| 		) { | ||||
| 			alertDiv.classList.remove("visible"); | ||||
| 			document.removeEventListener("keydown", dismissAlert); | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
|   document.addEventListener("keydown", dismissAlert); | ||||
|   document.getElementById("alertMessage").textContent = message; | ||||
|   alertDiv.classList.add("visible"); | ||||
| 	document.addEventListener("keydown", dismissAlert); | ||||
| 	document.getElementById("alertMessage").textContent = message; | ||||
| 	alertDiv.classList.add("visible"); | ||||
| }; | ||||
| 
 | ||||
| // Extra: hide video players on twitter
 | ||||
| if (document.domain == "twitter.com" || document.domain == "x.com") { | ||||
|   // Function to hide the grandparent of video players
 | ||||
|   // takes 0.014ms to run, so performance is not the concern here.
 | ||||
|   // timed with console.time, console.timeEnd
 | ||||
| 	// Function to hide the grandparent of video players
 | ||||
| 	// takes 0.014ms to run, so performance is not the concern here.
 | ||||
| 	// timed with console.time, console.timeEnd
 | ||||
| 
 | ||||
|   function hideVideoPlayerGrandparent() { | ||||
|     document | ||||
|       .querySelectorAll('[data-testid="videoPlayer"]') | ||||
|       .forEach(function (videoPlayer) { | ||||
|         var grandparentElement = | ||||
|           videoPlayer.parentElement.parentElement.parentElement.parentElement | ||||
|             .parentElement.parentElement; | ||||
|         var newTextElement = document.createElement("div"); | ||||
|         newTextElement.textContent = " [ twitter video ] "; | ||||
|         newTextElement.style["margin-top"] = "10px"; | ||||
|         newTextElement.style["margin-left"] = "10px"; | ||||
|         newTextElement.style["margin-bottom"] = "10px"; | ||||
|         grandparentElement.replaceWith(newTextElement); | ||||
|       }); | ||||
|   } | ||||
| 	function hideVideoPlayerGrandparent() { | ||||
| 		document | ||||
| 			.querySelectorAll('[data-testid="videoPlayer"]') | ||||
| 			.forEach(function (videoPlayer) { | ||||
| 				var grandparentElement = | ||||
| 					videoPlayer.parentElement.parentElement.parentElement.parentElement | ||||
| 						.parentElement.parentElement; | ||||
| 				var newTextElement = document.createElement("div"); | ||||
| 				newTextElement.textContent = " [ twitter video ] "; | ||||
| 				newTextElement.style["margin-top"] = "10px"; | ||||
| 				newTextElement.style["margin-left"] = "10px"; | ||||
| 				newTextElement.style["margin-bottom"] = "10px"; | ||||
| 				grandparentElement.replaceWith(newTextElement); | ||||
| 			}); | ||||
| 	} | ||||
| 
 | ||||
|   // Create a new MutationObserver instance
 | ||||
|   var observer = new MutationObserver(function (mutations) { | ||||
|     mutations.forEach(function (mutation) { | ||||
|       if (mutation.addedNodes.length) { | ||||
|         hideVideoPlayerGrandparent(); // Call the function to hide video players
 | ||||
|       } | ||||
|     }); | ||||
|   }); | ||||
| 	// Create a new MutationObserver instance
 | ||||
| 	var observer = new MutationObserver(function (mutations) { | ||||
| 		mutations.forEach(function (mutation) { | ||||
| 			if (mutation.addedNodes.length) { | ||||
| 				hideVideoPlayerGrandparent(); // Call the function to hide video players
 | ||||
| 			} | ||||
| 		}); | ||||
| 	}); | ||||
| 
 | ||||
|   // Options for the observer (which mutations to observe)
 | ||||
|   var config = { childList: true, subtree: true }; | ||||
| 	// Options for the observer (which mutations to observe)
 | ||||
| 	var config = { childList: true, subtree: true }; | ||||
| 
 | ||||
|   // Start observing the target node for configured mutations
 | ||||
|   observer.observe(document.body, config); | ||||
| 	// Start observing the target node for configured mutations
 | ||||
| 	observer.observe(document.body, config); | ||||
| 
 | ||||
|   // Call the function initially to hide any video players on initial load
 | ||||
|   hideVideoPlayerGrandparent(); | ||||
| 	// Call the function initially to hide any video players on initial load
 | ||||
| 	hideVideoPlayerGrandparent(); | ||||
| } | ||||
| 
 | ||||
| // 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 */ | ||||
| static GtkNotebook* notebook; | ||||
| static GtkWindow* window; | ||||
| typedef enum { _SEARCH, _FIND, _HIDDEN } Bar_entry_mode; | ||||
| typedef enum { _SEARCH, _FIND, _FILTER, _HIDDEN } Bar_entry_mode; | ||||
| static struct { | ||||
|     GtkHeaderBar* widget; | ||||
|     GtkEntry* line; | ||||
|  | @ -227,6 +227,13 @@ void toggle_bar(GtkNotebook* notebook, Bar_entry_mode mode) | |||
|             gtk_window_set_focus(window, GTK_WIDGET(bar.line)); | ||||
|             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: | ||||
|             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? */ | ||||
| { | ||||
|     WebKitWebView* view = notebook_get_webview(notebook); | ||||
|     if (bar.entry_mode == _SEARCH) | ||||
|         load_uri(view, gtk_entry_buffer_get_text(bar.line_text)); | ||||
|     else if (bar.entry_mode == _FIND) | ||||
|         webkit_find_controller_search( | ||||
|             webkit_web_view_get_find_controller(view), | ||||
|             gtk_entry_buffer_get_text(bar.line_text), | ||||
|             WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE | WEBKIT_FIND_OPTIONS_WRAP_AROUND, | ||||
|             G_MAXUINT); | ||||
|     const char* bar_line_text = gtk_entry_buffer_get_text(bar.line_text); | ||||
|     switch (bar.entry_mode) { | ||||
|         case _SEARCH: { | ||||
|             load_uri(view, bar_line_text); | ||||
|             gtk_widget_set_visible(GTK_WIDGET(bar.widget), 0); | ||||
|             break; | ||||
|         } | ||||
|         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 */ | ||||
|  | @ -332,6 +358,9 @@ int handle_shortcut(func id) | |||
|         case show_finder: | ||||
|             toggle_bar(notebook, _FIND); | ||||
|             break; | ||||
|         case filter: | ||||
|             toggle_bar(notebook, _FILTER); | ||||
|             break; | ||||
| 
 | ||||
|         case finder_next: | ||||
|             webkit_find_controller_search_next(webkit_web_view_get_find_controller(view)); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user