Compare commits
7 Commits
7d6c478c9c
...
10fca6af34
Author | SHA1 | Date | |
---|---|---|---|
10fca6af34 | |||
15451be030 | |||
80424d2854 | |||
f5a03f4d05 | |||
99ad21b850 | |||
8aa43e81fc | |||
c4581f3fd5 |
97
config.h
97
config.h
|
@ -16,7 +16,6 @@
|
|||
// Plugins
|
||||
#define LIBRE_REDIRECT_ENABLED true
|
||||
#define READABILITY_ENABLED true
|
||||
#define CUSTOM_STYLE_ENABLED true
|
||||
#define CUSTOM_USER_AGENT false
|
||||
/*
|
||||
To disable plugins:
|
||||
|
@ -51,25 +50,33 @@ You could also look into commit afe93518a for an approach using stand-in code.
|
|||
|
||||
// Shortcuts
|
||||
typedef enum {
|
||||
goback,
|
||||
goforward,
|
||||
refresh,
|
||||
refresh_force,
|
||||
back_to_home,
|
||||
toggle_fullscreen,
|
||||
zoomin,
|
||||
zoomout,
|
||||
zoom_reset,
|
||||
new_tab,
|
||||
next_tab,
|
||||
prev_tab,
|
||||
close_tab,
|
||||
show_searchbar,
|
||||
show_finder,
|
||||
finder_next,
|
||||
finder_prev,
|
||||
prettify,
|
||||
hide_bar
|
||||
goback,
|
||||
goforward,
|
||||
|
||||
refresh,
|
||||
refresh_force,
|
||||
|
||||
back_to_home,
|
||||
|
||||
toggle_fullscreen,
|
||||
toggle_custom_style,
|
||||
|
||||
zoomin,
|
||||
zoomout,
|
||||
zoom_reset,
|
||||
|
||||
new_tab,
|
||||
next_tab,
|
||||
prev_tab,
|
||||
close_tab,
|
||||
|
||||
show_searchbar,
|
||||
hide_bar,
|
||||
show_finder,
|
||||
finder_next,
|
||||
finder_prev,
|
||||
|
||||
prettify,
|
||||
} func;
|
||||
|
||||
|
||||
|
@ -78,27 +85,35 @@ static struct {
|
|||
unsigned key;
|
||||
func id;
|
||||
} shortcut[] = {
|
||||
{ CTRL, KEY(h), goback },
|
||||
{ CTRL, KEY(j), goforward },
|
||||
{ CTRL, KEY(r), refresh },
|
||||
{ CTRL, KEY(R), refresh_force },
|
||||
{ CTRL, KEY(H), back_to_home },
|
||||
{ CTRL, KEY(equal), zoomin },
|
||||
{ CTRL, KEY(minus), zoomout },
|
||||
{ CTRL, KEY(0), zoom_reset },
|
||||
{ CTRL, KEY(KP_Page_Up), prev_tab },
|
||||
{ CTRL, KEY(KP_Page_Down), next_tab },
|
||||
{ CTRL, KEY(Page_Up), prev_tab }, // working hypothesis: Page_UP vs KP_Page_Up might depend on whether the user has a numpad
|
||||
{ CTRL, KEY(Page_Down), next_tab },
|
||||
{ CTRL, KEY(t), new_tab },
|
||||
{ CTRL, KEY(w), close_tab },
|
||||
{ 0x0, KEY(F11), toggle_fullscreen },
|
||||
{ CTRL, KEY(l), show_searchbar },
|
||||
{ CTRL, KEY(semicolon), hide_bar },
|
||||
{ CTRL, KEY(f), show_finder },
|
||||
{ CTRL, KEY(n), finder_next },
|
||||
{ CTRL, KEY(N), finder_prev },
|
||||
{ CTRL, KEY(p), prettify }
|
||||
{ CTRL, KEY(h), goback },
|
||||
{ CTRL, KEY(j), goforward },
|
||||
|
||||
{ CTRL, KEY(r), refresh },
|
||||
{ CTRL, KEY(R), refresh_force },
|
||||
|
||||
{ CTRL, KEY(H), back_to_home },
|
||||
|
||||
{ 0x0, KEY(F11), toggle_fullscreen },
|
||||
{ CTRL, KEY(S), toggle_custom_style },
|
||||
|
||||
{ CTRL, KEY(equal), zoomin },
|
||||
{ CTRL, KEY(minus), zoomout },
|
||||
{ CTRL, KEY(0), zoom_reset },
|
||||
|
||||
{ CTRL, KEY(KP_Page_Up), prev_tab },
|
||||
{ CTRL, KEY(KP_Page_Down), next_tab },
|
||||
{ CTRL, KEY(Page_Up), prev_tab }, // working hypothesis: Page_UP vs KP_Page_Up might depend on whether the user has a numpad
|
||||
{ CTRL, KEY(Page_Down), next_tab },
|
||||
{ CTRL, KEY(t), new_tab },
|
||||
{ CTRL, KEY(w), close_tab },
|
||||
|
||||
{ CTRL, KEY(l), show_searchbar },
|
||||
{ CTRL, KEY(semicolon), hide_bar },
|
||||
{ CTRL, KEY(f), show_finder },
|
||||
{ CTRL, KEY(n), finder_next },
|
||||
{ CTRL, KEY(N), finder_prev },
|
||||
|
||||
{ CTRL, KEY(p), prettify }
|
||||
};
|
||||
|
||||
/* Old controls: {
|
||||
|
|
7
makefile
7
makefile
|
@ -22,7 +22,8 @@ ADBLOCK='-L/usr/lib/wyebrowser/adblock.so' # optional adblocking; depends on htt
|
|||
|
||||
## Formatter
|
||||
STYLE_BLUEPRINT="{BasedOnStyle: webkit, AllowShortIfStatementsOnASingleLine: true, IndentCaseLabels: true, AllowShortEnumsOnASingleLine: true}"
|
||||
FORMATTER=clang-format -i -style=$(STYLE_BLUEPRINT)
|
||||
FORMATTER_C=clang-format -i -style=$(STYLE_BLUEPRINT)
|
||||
FORMATTER_JS=npx prettier -w
|
||||
|
||||
# Runtime files
|
||||
MAINTAINER_CACHE_DIR=/home/nuno/.cache/rosenrot
|
||||
|
@ -68,7 +69,9 @@ clean:
|
|||
rm $(USER_CACHE_DIR)
|
||||
|
||||
format: $(SRC) $(PLUGINS)
|
||||
$(FORMATTER) $(SRC) $(PLUGINS) $(rosenrot.h)
|
||||
$(FORMATTER_C) $(SRC) $(PLUGINS) $(rosenrot.h)
|
||||
$(FORMATTER_JS) plugins/readability/readability.js
|
||||
$(FORMATTER_JS) plugins/style/style.js
|
||||
|
||||
lint:
|
||||
clang-tidy $(SRC) $(PLUGINS) -- -Wall -O3 $(INCS) -o rosenrot $(LIBS)
|
||||
|
|
|
@ -17,6 +17,7 @@ int libre_redirect(const char* uri, char* output)
|
|||
} else {
|
||||
char* annoying_sites[] = {
|
||||
"https://www.reddit.com",
|
||||
"https://vitalik.ca",
|
||||
"https://www.youtube.com",
|
||||
"https://google.com",
|
||||
"https://medium.com",
|
||||
|
@ -29,12 +30,15 @@ int libre_redirect(const char* uri, char* output)
|
|||
};
|
||||
|
||||
char* alternatives[] = {
|
||||
"https://old.reddit.com", // "https://teddit.nunosempere.com",
|
||||
"https://redlib.ducks.party",
|
||||
// previously: "https://old.reddit.com", "https://teddit.nunosempere.com",
|
||||
// https://github.com/redlib-org/redlib-instances/blob/main/instances.md
|
||||
"https://vitalik.eth.limo",
|
||||
"https://invidious.private.coffee",
|
||||
"https://search.nunosempere.com",
|
||||
"https://scribe.rip",
|
||||
"https://translate.riverside.rocks",
|
||||
"https://archive.is/https://www.bloomberg.com",
|
||||
"https://archive.ph/https://www.bloomberg.com",
|
||||
"https://royalread.nunosempere.com",
|
||||
"https://dumb.vern.cc",
|
||||
// "https://wayback.nunosempere.com",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define READABILITY_N 88067 + 1000
|
||||
#define READABILITY_N 88097 + 1000
|
||||
|
||||
void read_readability_js(char* string)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#define READABILITY_N 88067 + 1000
|
||||
#define READABILITY_N 88097 + 1000
|
||||
|
||||
void read_readability_js(char* string);
|
||||
|
|
|
@ -32,7 +32,7 @@ function Readability(doc, options) {
|
|||
options = arguments[2];
|
||||
} else if (!doc || !doc.documentElement) {
|
||||
throw new Error(
|
||||
"First argument to Readability constructor should be a document object."
|
||||
"First argument to Readability constructor should be a document object.",
|
||||
);
|
||||
}
|
||||
options = options || {};
|
||||
|
@ -53,7 +53,7 @@ function Readability(doc, options) {
|
|||
options.nbTopCandidates || this.DEFAULT_N_TOP_CANDIDATES;
|
||||
this._charThreshold = options.charThreshold || this.DEFAULT_CHAR_THRESHOLD;
|
||||
this._classesToPreserve = this.CLASSES_TO_PRESERVE.concat(
|
||||
options.classesToPreserve || []
|
||||
options.classesToPreserve || [],
|
||||
);
|
||||
this._keepClasses = !!options.keepClasses;
|
||||
this._serializer =
|
||||
|
@ -405,7 +405,7 @@ Readability.prototype = {
|
|||
tagNames.map(function (tag) {
|
||||
var collection = node.getElementsByTagName(tag);
|
||||
return Array.isArray(collection) ? collection : Array.from(collection);
|
||||
})
|
||||
}),
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -517,7 +517,7 @@ Readability.prototype = {
|
|||
this.REGEXPS.srcsetUrl,
|
||||
function (_, p1, p2, p3) {
|
||||
return toAbsoluteURI(p1) + (p2 || "") + p3;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
media.setAttribute("srcset", newSrcset);
|
||||
|
@ -545,7 +545,7 @@ Readability.prototype = {
|
|||
for (var i = 0; i < node.attributes.length; i++) {
|
||||
child.setAttribute(
|
||||
node.attributes[i].name,
|
||||
node.attributes[i].value
|
||||
node.attributes[i].value,
|
||||
);
|
||||
}
|
||||
node.parentNode.replaceChild(child, node);
|
||||
|
@ -574,7 +574,7 @@ Readability.prototype = {
|
|||
// If they had an element with id "title" in their HTML
|
||||
if (typeof curTitle !== "string")
|
||||
curTitle = origTitle = this._getInnerText(
|
||||
doc.getElementsByTagName("title")[0]
|
||||
doc.getElementsByTagName("title")[0],
|
||||
);
|
||||
} catch (e) {
|
||||
/* ignore exceptions setting the title. */
|
||||
|
@ -599,7 +599,7 @@ Readability.prototype = {
|
|||
// could assume it's the full title.
|
||||
var headings = this._concatNodeLists(
|
||||
doc.getElementsByTagName("h1"),
|
||||
doc.getElementsByTagName("h2")
|
||||
doc.getElementsByTagName("h2"),
|
||||
);
|
||||
var trimmedTitle = curTitle.trim();
|
||||
var match = this._someNode(headings, function (heading) {
|
||||
|
@ -755,7 +755,7 @@ Readability.prototype = {
|
|||
try {
|
||||
replacement.setAttribute(
|
||||
node.attributes[i].name,
|
||||
node.attributes[i].value
|
||||
node.attributes[i].value,
|
||||
);
|
||||
} catch (ex) {
|
||||
/* it's possible for setAttribute() to throw if the attribute name
|
||||
|
@ -825,7 +825,7 @@ Readability.prototype = {
|
|||
// replace H1 with H2 as H1 should be only title that is displayed separately
|
||||
this._replaceNodeTags(
|
||||
this._getAllNodesWithTag(articleContent, ["h1"]),
|
||||
"h2"
|
||||
"h2",
|
||||
);
|
||||
|
||||
// Remove extra paragraphs
|
||||
|
@ -840,7 +840,7 @@ Readability.prototype = {
|
|||
var totalCount = imgCount + embedCount + objectCount + iframeCount;
|
||||
|
||||
return totalCount === 0 && !this._getInnerText(paragraph, false);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this._forEachNode(
|
||||
|
@ -848,7 +848,7 @@ Readability.prototype = {
|
|||
function (br) {
|
||||
var next = this._nextNode(br.nextSibling);
|
||||
if (next && next.tagName == "P") br.parentNode.removeChild(br);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Remove single-cell tables
|
||||
|
@ -866,12 +866,12 @@ Readability.prototype = {
|
|||
cell,
|
||||
this._everyNode(cell.childNodes, this._isPhrasingContent)
|
||||
? "P"
|
||||
: "DIV"
|
||||
: "DIV",
|
||||
);
|
||||
table.parentNode.replaceChild(cell, table);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -1032,7 +1032,7 @@ Readability.prototype = {
|
|||
while (true) {
|
||||
this.log("Starting grabArticle loop");
|
||||
var stripUnlikelyCandidates = this._flagIsActive(
|
||||
this.FLAG_STRIP_UNLIKELYS
|
||||
this.FLAG_STRIP_UNLIKELYS,
|
||||
);
|
||||
|
||||
// First, node prepping. Trash nodes that look cruddy (like ones with the
|
||||
|
@ -1066,7 +1066,7 @@ Readability.prototype = {
|
|||
this.log(
|
||||
"Removing header: ",
|
||||
node.textContent.trim(),
|
||||
this._articleTitle.trim()
|
||||
this._articleTitle.trim(),
|
||||
);
|
||||
shouldRemoveTitleHeader = false;
|
||||
node = this._removeAndGetNext(node);
|
||||
|
@ -1093,7 +1093,7 @@ Readability.prototype = {
|
|||
"Removing content with role " +
|
||||
node.getAttribute("role") +
|
||||
" - " +
|
||||
matchString
|
||||
matchString,
|
||||
);
|
||||
node = this._removeAndGetNext(node);
|
||||
continue;
|
||||
|
@ -1285,7 +1285,7 @@ Readability.prototype = {
|
|||
0.75
|
||||
) {
|
||||
alternativeCandidateAncestors.push(
|
||||
this._getNodeAncestors(topCandidates[i])
|
||||
this._getNodeAncestors(topCandidates[i]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1302,8 +1302,8 @@ Readability.prototype = {
|
|||
) {
|
||||
listsContainingThisAncestor += Number(
|
||||
alternativeCandidateAncestors[ancestorIndex].includes(
|
||||
parentOfTopCandidate
|
||||
)
|
||||
parentOfTopCandidate,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (listsContainingThisAncestor >= MINIMUM_TOPCANDIDATES) {
|
||||
|
@ -1367,7 +1367,7 @@ Readability.prototype = {
|
|||
|
||||
var siblingScoreThreshold = Math.max(
|
||||
10,
|
||||
topCandidate.readability.contentScore * 0.2
|
||||
topCandidate.readability.contentScore * 0.2,
|
||||
);
|
||||
// Keep potential top candidate's parent node to try to get text direction of it later.
|
||||
parentOfTopCandidate = topCandidate.parentNode;
|
||||
|
@ -1382,11 +1382,11 @@ Readability.prototype = {
|
|||
sibling,
|
||||
sibling.readability
|
||||
? "with score " + sibling.readability.contentScore
|
||||
: ""
|
||||
: "",
|
||||
);
|
||||
this.log(
|
||||
"Sibling has score",
|
||||
sibling.readability ? sibling.readability.contentScore : "Unknown"
|
||||
sibling.readability ? sibling.readability.contentScore : "Unknown",
|
||||
);
|
||||
|
||||
if (sibling === topCandidate) {
|
||||
|
@ -1529,7 +1529,7 @@ Readability.prototype = {
|
|||
if (parseSuccessful) {
|
||||
// Find out text direction from ancestors of final top candidate.
|
||||
var ancestors = [parentOfTopCandidate, topCandidate].concat(
|
||||
this._getNodeAncestors(parentOfTopCandidate)
|
||||
this._getNodeAncestors(parentOfTopCandidate),
|
||||
);
|
||||
this._someNode(ancestors, function (ancestor) {
|
||||
if (!ancestor.tagName) return false;
|
||||
|
@ -1582,7 +1582,7 @@ Readability.prototype = {
|
|||
function (_, hex, numStr) {
|
||||
var num = parseInt(hex || numStr, hex ? 16 : 10);
|
||||
return String.fromCharCode(num);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -1605,7 +1605,7 @@ Readability.prototype = {
|
|||
// Strip CDATA markers if present
|
||||
var content = jsonLdElement.textContent.replace(
|
||||
/^\s*<!\[CDATA\[|\]\]>\s*$/g,
|
||||
""
|
||||
"",
|
||||
);
|
||||
var parsed = JSON.parse(content);
|
||||
if (
|
||||
|
@ -1898,7 +1898,7 @@ Readability.prototype = {
|
|||
scriptNode.nodeValue = "";
|
||||
scriptNode.removeAttribute("src");
|
||||
return true;
|
||||
}
|
||||
},
|
||||
);
|
||||
this._removeNodes(this._getAllNodesWithTag(doc, ["noscript"]));
|
||||
},
|
||||
|
@ -2310,7 +2310,7 @@ Readability.prototype = {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -2323,7 +2323,7 @@ Readability.prototype = {
|
|||
var children = this._getAllNodesWithTag(e, tags);
|
||||
this._forEachNode(
|
||||
children,
|
||||
(child) => (childrenLength += this._getInnerText(child, true).length)
|
||||
(child) => (childrenLength += this._getInnerText(child, true).length),
|
||||
);
|
||||
return childrenLength / textLength;
|
||||
},
|
||||
|
@ -2354,7 +2354,7 @@ Readability.prototype = {
|
|||
var listNodes = this._getAllNodesWithTag(node, ["ul", "ol"]);
|
||||
this._forEachNode(
|
||||
listNodes,
|
||||
(list) => (listLength += this._getInnerText(list).length)
|
||||
(list) => (listLength += this._getInnerText(list).length),
|
||||
);
|
||||
isList = listLength / this._getInnerText(node).length > 0.9;
|
||||
}
|
||||
|
@ -2554,7 +2554,7 @@ Readability.prototype = {
|
|||
var numTags = this._doc.getElementsByTagName("*").length;
|
||||
if (numTags > this._maxElemsToParse) {
|
||||
throw new Error(
|
||||
"Aborting parsing document; " + numTags + " elements found"
|
||||
"Aborting parsing document; " + numTags + " elements found",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,9 +22,11 @@ int shortcut_expand(const char* uri, char* output)
|
|||
"!blog",
|
||||
"!fnf",
|
||||
"!fnc",
|
||||
"!fs",
|
||||
"!hn",
|
||||
"!hnb"
|
||||
"!x",
|
||||
"!hnb",
|
||||
"!ww",
|
||||
"!x"
|
||||
};
|
||||
|
||||
char* expansions[] = {
|
||||
|
@ -32,9 +34,11 @@ int shortcut_expand(const char* uri, char* output)
|
|||
"https://nunosempere.com/blog",
|
||||
"https://forum.nunosempere.com/frontpage",
|
||||
"https://forum.nunosempere.com/comments",
|
||||
"https://forecasting.substack.com",
|
||||
"https://news.ycombinator.com",
|
||||
"https://news.ycombinator.com/best",
|
||||
"https://twitter.com",
|
||||
"https://web.whatsapp.com",
|
||||
"https://twitter.com"
|
||||
};
|
||||
|
||||
// len = sizeof(shortcuts) / sizeof(shortcuts[0]);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define STYLE_N 7827 + 1000
|
||||
#define STYLE_N 7831 + 1000
|
||||
|
||||
void read_style_js(char* string)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#define STYLE_N 7827 + 1000
|
||||
#define STYLE_N 7831 + 1000
|
||||
|
||||
void read_style_js(char* string);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
// Main part of the code: switch on the domain and select the corresponding style
|
||||
var styles = null;
|
||||
console.log(document.domain)
|
||||
console.log(document.domain);
|
||||
switch (document.domain) {
|
||||
case "forum.effectivealtruism.org":
|
||||
styles = `
|
||||
|
|
11
rosenrot.c
11
rosenrot.c
|
@ -17,6 +17,7 @@ static struct {
|
|||
Bar_entry_mode entry_mode;
|
||||
} bar;
|
||||
static int num_tabs = 0;
|
||||
static int custom_style_enabled = 1;
|
||||
|
||||
/* Forward declarations */
|
||||
void toggle_bar(GtkNotebook* notebook, Bar_entry_mode mode);
|
||||
|
@ -71,7 +72,7 @@ void redirect_if_annoying(WebKitWebView* view, const char* uri)
|
|||
}
|
||||
void set_custom_style(WebKitWebView* view)
|
||||
{
|
||||
if (CUSTOM_STYLE_ENABLED) {
|
||||
if (custom_style_enabled) {
|
||||
char* style_js = malloc(STYLE_N + 1);
|
||||
read_style_js(style_js);
|
||||
webkit_web_view_evaluate_javascript(view, style_js, -1, NULL, "rosenrot-style-plugin", NULL, NULL, NULL);
|
||||
|
@ -251,6 +252,12 @@ int handle_shortcut(func id, GtkNotebook* notebook)
|
|||
webkit_web_view_go_forward(view);
|
||||
break;
|
||||
|
||||
case toggle_custom_style: /* Ctrl s + Ctrl Shift R to reload */
|
||||
if (custom_style_enabled)
|
||||
custom_style_enabled = 0;
|
||||
else
|
||||
custom_style_enabled = 1;
|
||||
// break; passthrough
|
||||
case refresh:
|
||||
webkit_web_view_reload(view);
|
||||
break;
|
||||
|
@ -302,7 +309,6 @@ int handle_shortcut(func id, GtkNotebook* notebook)
|
|||
}
|
||||
|
||||
break;
|
||||
|
||||
case toggle_fullscreen:
|
||||
if (is_fullscreen)
|
||||
gtk_window_unfullscreen(window);
|
||||
|
@ -310,7 +316,6 @@ int handle_shortcut(func id, GtkNotebook* notebook)
|
|||
gtk_window_fullscreen(window);
|
||||
is_fullscreen = !is_fullscreen;
|
||||
break;
|
||||
|
||||
case show_searchbar:
|
||||
toggle_bar(notebook, _SEARCH);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue
Block a user