Compare commits
44 Commits
f1982d015d
...
aec21c71a6
Author | SHA1 | Date | |
---|---|---|---|
aec21c71a6 | |||
cd2b6a3257 | |||
d65dc93af7 | |||
b87693e4c5 | |||
e2c81f2595 | |||
0253c5e80a | |||
d17fb92bb6 | |||
eefa3cfb45 | |||
16d43ac601 | |||
4784a0ad26 | |||
3beef82ca6 | |||
38cee8fd24 | |||
5b1aab5e0c | |||
98f6d5630f | |||
1cf68bb1fe | |||
a24af4aad1 | |||
8d2811c5f9 | |||
995f455ece | |||
28a28b491d | |||
c08c4f48de | |||
8dc67aaa16 | |||
84df2273eb | |||
6ef555fc44 | |||
a8be16b1ee | |||
c46e2ba398 | |||
5fb7e79ad5 | |||
49a005f929 | |||
c2bffc09ce | |||
00d498851c | |||
98114362d9 | |||
85942a60bd | |||
574cdd30ce | |||
230f472e3a | |||
5331760a83 | |||
6ae0811000 | |||
3734dcd2d1 | |||
4e3bb826ba | |||
0ba58087e0 | |||
52aacc6dac | |||
b129954d4d | |||
b32749aa6e | |||
a4f8ad8ae2 | |||
f8b4e9ff4a | |||
17ff6bb780 |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
rose
|
103
README.md
103
README.md
|
@ -1,58 +1,102 @@
|
|||
## Rosenrot
|
||||
|
||||
A small browser forked from [rose](https://github.com/mini-rose/rose).
|
||||
Rosenrot is a small browser forked from an earlier version of [rose](https://github.com/mini-rose/rose). It has some additional quality of life improvements tailored to my (@NunoSempere) tastes and setup, and detailed installation instructions for Ubuntu 20.04.
|
||||
|
||||
- Rose is a minimal browser based on webkit2gtk which aims to be a "basement for creating your own browser using [the] gtk and webkit libraries".
|
||||
- Rosenrot is my fork from rose. It has accumulated cruft that I like, like a "readability" plugin that simplifies annoying websites like [Matt Levine's Money Stuff newsletter](https://www.bloomberg.com/opinion/articles/2022-10-18/matt-levine-s-money-stuff-credit-suisse-was-a-reverse-meme-stock).
|
||||
- Rosenrot is also a song by the German hardcore rock band [Rammstein](https://www.youtube.com/watch?v=af59U2BRRAU).
|
||||

|
||||
|
||||
You can see some screenshots in the [screenshots](./screenshots) folder.
|
||||
|
||||
### Features
|
||||
|
||||
- tabs, cookies, caching
|
||||
- minimal ui, autohiding elements
|
||||
- ~467L core code (the rose.c file)
|
||||
- custom gtk and websites css
|
||||
- builtin rose-mklink script for in-shell static links
|
||||
- A few quality of life improvements.
|
||||
- Optional adblocking through [wyebadblock](https://github.com/jun7/wyebadblock)
|
||||
- Plugin system:
|
||||
- Libre redirect: Redirect annoying websites to open source frontends
|
||||
- Readability: Strip webpages of unnecessary elements for ease of reading with a custom shortcut
|
||||
- Custom style: Override the css of predetermined websites
|
||||
- Stand in plugin: Mimick function definitions which do nothing for the above plugins so that they can be quickly removed
|
||||

|
||||
|
||||
### Installation
|
||||
|
||||
Install dependencies, then:
|
||||
You can see detailed instructions [here](./user-scripts/ubuntu-20.04/install-with-dependencies.sh), for Ubuntu 20.04 in particular—though they should generalize easily to other distributions. Or a video installing rosenrot in a fresh Ubuntu 20.04 virtual machine [here](https://video.nunosempere.com/w/t3oAvJLPHTSAMViQ6zbwTV).
|
||||
|
||||
The general steps are to install dependencies, and then
|
||||
|
||||
```
|
||||
make build
|
||||
make install # or sudo make install
|
||||
```
|
||||
|
||||
You can also see more detailed instructions [here](./user-scripts/ubuntu-20.04/install-with-dependencies.sh), for Ubuntu 20.04 in particular—though they should generalize trivially. Or a video installing rosenrot in a fresh Ubuntu 20.04 virtual machine [here](https://video.nunosempere.com/w/t3oAvJLPHTSAMViQ6zbwTV).
|
||||
### Usage
|
||||
|
||||
### 👐 Contribute
|
||||
After building:
|
||||
|
||||
```
|
||||
./rose
|
||||
```
|
||||
|
||||
After installing:
|
||||
|
||||
```
|
||||
rose
|
||||
```
|
||||
|
||||
You can also create a rose.desktop file so that it will show up in your desktop environment. You can see this documented [here](./user-scripts/ubuntu-20.04/install-with-dependencies.sh).
|
||||
|
||||
### Features
|
||||
|
||||
- Tabs, cookies, caching
|
||||
- Minimal ui, autohiding elements
|
||||
- ~464L core code (the rose.c file)
|
||||
- Customize appearance of the browser through css
|
||||
- Built-in rose-mklink script for in-shell static links
|
||||
- Optional adblocking through [wyebadblock](https://github.com/jun7/wyebadblock)
|
||||
- Max number of tabs (by default 8), configurable.
|
||||
- Plugin system, seeded with:
|
||||
- Libre redirect: Redirect annoying websites to open source frontends
|
||||
- Readability: Strip webpages of unnecessary elements for ease of reading with a custom shortcut
|
||||
- Custom style: Override the css of predetermined websites
|
||||
- Stand in plugin: Mimick function definitions which do nothing for the above plugins so that they can be quickly removed
|
||||
|
||||
You can see some screenshots in the [screenshots](./screenshots) folder.
|
||||
|
||||
## Relationship with [rose](https://github.com/mini-rose/rose)
|
||||
|
||||
- Rose is a minimal browser based on webkit2gtk. Previously, it described itself as aiming to be a "basement for creating your own browser using [the] gtk and webkit libraries".
|
||||
- Rosenrot is my (@NunoSempere's) fork from rose. It has accumulated quality of life features/cruft that I like, like a "readability" plugin that simplifies annoying websites like [Matt Levine's Money Stuff newsletter](https://www.bloomberg.com/opinion/articles/2022-10-18/matt-levine-s-money-stuff-credit-suisse-was-a-reverse-meme-stock). It also incorporates ad-blocking.
|
||||
- Rosenrot is also a song by the German hardcore rock band [Rammstein](https://www.youtube.com/watch?v=af59U2BRRAU).
|
||||
|
||||
### Contribute
|
||||
|
||||
- Contribute upstream to [github.com/mini-rose/rose](https://github.com/mini-rose/) for core functionality changes.
|
||||
- Contribute here for quality of life improvements, by sending a pull request on Github.
|
||||
|
||||
### Cool things
|
||||
|
||||
I just found out that you can inspect a GTK application with the GTK explorer if you set a certain command-line variable. Try this with `make inspect`.
|
||||
|
||||
### Known bugs/gotchas.
|
||||
|
||||
- [x] ~~Doesn't work with when Spanish is selected as the language, for some reason~~ => Previously misdiagnosed. The real issue was that it freezes when interacting with [Espanso](https://espanso.org/) substitutions, which I had set-up automatically on my machine when using words containing an ñ, like my own name, Nuño.
|
||||
- [ ] At some point, I tried to install libsoup-3 and borked some unknown installation option/paths. So now I need to run rose with `GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/ /bin/rose` (or put `export GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/` in my .bashrc). This won't affect new users though, just double checked on a fresh machine.
|
||||
- [ ] By default the searchbar is pretty gigantic. I've made this so because I'm a bit myopic, but also work with my laptop in a laptop stand. Anyways, if you are a more normal person you can change this in the style.css.
|
||||
- [ ] The style.css usage isn't updated until installation. This is because by default rose uses the theme located in /usr/share/themes/rose/style.css, and that file isn't updated until make install.
|
||||
|
||||
### To do
|
||||
|
||||
- [ ] Look at using relative rather than absolute paths
|
||||
#### Quality of life:
|
||||
|
||||
- [ ] Add css for js alerts
|
||||
- [ ] Figure out if downloading files is doable.
|
||||
- [x] Add custom alert whose css can be customized
|
||||
- [ ] Debug problems, e.g., this version is non-blocking.
|
||||
- [ ] Figure out better way to have plugins
|
||||
- [ ] Double check newtab/next-tab behavior
|
||||
- [ ] Find out what each of the css elements refers to.
|
||||
- [ ] Use something other than Whatsapp as an example syslink.
|
||||
- [ ] Document creating new applications, e.g., as in [Asana for Linux](https://git.nunosempere.com/NunoSempere/asana-for-linux)
|
||||
- [ ] Add list of similar projects: <https://github.com/qutebrowser/qutebrowser#similar-projects>
|
||||
|
||||
#### Maintenance
|
||||
|
||||
- [ ] Set [`webkit_web_context_set_sandbox_enabled`](<https://webkitgtk.org/reference/webkit2gtk/2.36.8/WebKitWebContext.html#webkit-web-context-set-sandbox-enabled>), as recommended [here](<https://blogs.gnome.org/mcatanzaro/2022/11/04/stop-using-qtwebkit/>)
|
||||
- [ ] Use something other than Whatsapp as an example syslink.
|
||||
- [ ] Fix bug about distorted audio. Maybe related to [this pipewire issue](<https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1547>)?
|
||||
- [ ] Upgrade to GTK-4 / Webkitgtk 6.0? Will take a fair amount of time, since these are not available on Ubuntu 20.04.
|
||||
|
||||
Done:
|
||||
#### Previously done
|
||||
|
||||
- [x] Add a shortcut for hiding the search tab. => Already exists: Ctrl+K
|
||||
- [x] Find out what each of the css elements refers to. => done, see make inspect
|
||||
- [x] Figure out if downloading files is doable. => it is
|
||||
- [x] Look at using relative rather than absolute paths for configuration. => now makefile is a bit smarter
|
||||
- [x] Streamline installation a bit
|
||||
- [x] Substitute paths in makefile
|
||||
- [x] Create cache directory automatically
|
||||
|
@ -74,6 +118,3 @@ Done:
|
|||
- And for actually opening links with the href new_tab option.
|
||||
- Links: [1](<https://docs.gtk.org/gobject/func.signal_connect.html>), [2](<https://webkitgtk.org/reference/webkit2gtk/2.37.90/signal.AutomationSession.create-web-view.html>), [3](<https://webkitgtk.org/reference/webkit2gtk/2.26.0/WebKitWebView.html#WebKitWebView-create>), [4](<https://stackoverflow.com/questions/40180757/webkit2gtk-get-new-window-link>)
|
||||
|
||||
### Known bugs
|
||||
|
||||
- [ ] Doesn't work with when Spanish is selected as the language, for some reason.
|
||||
|
|
16
config.h
16
config.h
|
@ -8,19 +8,21 @@
|
|||
"enable-smooth-scrolling", false
|
||||
|
||||
#define GTK "gtk-application-prefer-dark-theme", false, "gtk-enable-animations", false
|
||||
#define ROSE_HOMEPAGE true
|
||||
#define HOME ROSE_HOMEPAGE ? "file:///home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-homepage.png" : "https://lite.duckduckgo.com/html"
|
||||
#define SEARCH "https://lite.duckduckgo.com/html/?q=%s"
|
||||
#define ROSE_HOMEPAGE false
|
||||
#define SEARCH "https://search.nunosempere.com/search?q=%s" // "https://lite.duckduckgo.com/html/?q=%s"
|
||||
#define HOME ROSE_HOMEPAGE ? "file:///home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-homepage.png" : "https://search.nunosempere.com/"
|
||||
// #define HOME ROSE_HOMEPAGE ? "file:///home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-homepage.png" : "https://search.nunosempere.com/"
|
||||
#define CACHE_DIR "/home/loki/.cache/rose"
|
||||
|
||||
#define WIDTH 1920
|
||||
#define WIDTH 1920 // 960 for half-width, 1920 for full width
|
||||
#define HEIGHT 1080
|
||||
#define SEARCH_BAR_SIZE 1200
|
||||
#define KEY(x) GDK_KEY_##x
|
||||
#define ZOOM 1.4 /* Starting zoom level.*/
|
||||
#define ZOOM 1.6 /* Starting zoom level.*/
|
||||
#define ZOOM_VAL .1 /* Zooming value in zoomin/zoomout functions */
|
||||
#define BG_COLOR "#FEFEFE" /* "FEFEFE", "#1E1E2E" */
|
||||
#define DEBUG false
|
||||
#define DEBUG false
|
||||
#define MAX_NUM_TABS 8 // set to 0 or false if you want unlimited tabs, or look at the relevant rose.c code.
|
||||
|
||||
typedef enum {
|
||||
goback,
|
||||
|
@ -67,7 +69,7 @@ static struct {
|
|||
{ CTRL, KEY(w), close_tab },
|
||||
{ 0x0, KEY(F11), toggle_fullscreen },
|
||||
{ CTRL, KEY(l), show_searchbar },
|
||||
{ CTRL, KEY(k), hide_bar },
|
||||
{ CTRL, KEY(semicolon), hide_bar },
|
||||
{ CTRL, KEY(f), show_finder },
|
||||
{ CTRL, KEY(n), finder_next },
|
||||
{ CTRL | SFT, KEY(N), finder_prev },
|
||||
|
|
24
makefile
24
makefile
|
@ -6,7 +6,10 @@
|
|||
# make uninstall
|
||||
|
||||
## C compiler
|
||||
CC=gcc
|
||||
CC=gcc # gcc: more options. Also I don't know whether tcc has error messages/debug options.
|
||||
WARNINGS=-Wall
|
||||
OPTIMIZED=-O3 #-Ofast
|
||||
## CC=tcc # tcc: much faster
|
||||
|
||||
## Main file
|
||||
SRC=rose.c
|
||||
|
@ -20,16 +23,17 @@ LIBS=`pkg-config --libs ${DEPS}`
|
|||
|
||||
## Optional adblocking
|
||||
## depends on https://github.com/jun7/wyebadblock
|
||||
ADBLOCK='-L/usr/lib/wyebrowser/adblock.so'
|
||||
ADBLOCK=#'-L/usr/lib/wyebrowser/adblock.so'
|
||||
|
||||
## Plugins
|
||||
LIBRE_REDIRECT=./plugins/libre_redirect/libre_redirect.c ./plugins/libre_redirect/str_replace_start.c
|
||||
READABILITY=./plugins/readability/readability.c
|
||||
LIBRE_REDIRECT=./plugins/libre_redirect/libre_redirect.c ./plugins/libre_redirect/str_replace_start.c ./plugins/libre_redirect/str_init.c
|
||||
CUSTOM_STYLES=./plugins/style/style.c
|
||||
READABILITY=./plugins/readability/readability.c
|
||||
SHORTCUTS=./plugins/shortcuts/shortcuts.c
|
||||
|
||||
STAND_IN=./plugins/stand_in/stand_in.c # gives function definitions for the above, which do nothing
|
||||
|
||||
PLUGS=$(LIBRE_REDIRECT) $(READABILITY) $(CUSTOM_STYLES)
|
||||
PLUGS=$(LIBRE_REDIRECT) $(READABILITY) $(CUSTOM_STYLES) $(SHORTCUTS)
|
||||
# PLUGS=$(STAND_IN)
|
||||
# Note that if you want some plugins but not others,
|
||||
# You should edit the stand_in.c file
|
||||
|
@ -53,6 +57,9 @@ DEFAULT_DIR=/home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot
|
|||
CURRENT_DIR=`pwd`
|
||||
|
||||
build: $(SRC) $(PLUGS) $(CONFIG)
|
||||
# Recompute constants
|
||||
cd plugins/readability/ && sh recompute_READABILITY_N.sh
|
||||
cd plugins/style && sh recompute_STYLE_N.sh
|
||||
# Make cache
|
||||
mkdir -p $(CURRENT_CACHE_DIR)
|
||||
# Hardcode cache path
|
||||
|
@ -62,9 +69,14 @@ build: $(SRC) $(PLUGS) $(CONFIG)
|
|||
find $(CURRENT_DIR) -type f -not -path "*.git*" -not -path "*makefile*" -exec \
|
||||
sed -i "s|$(DEFAULT_DIR)|$(CURRENT_DIR)|g" {} +
|
||||
# Compile rosenrot
|
||||
$(CC) $(DEBUG) $(INCS) $(PLUGS) $(SRC) -o rose $(LIBS) $(ADBLOCK)
|
||||
GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/
|
||||
$(CC) $(WARNINGS) $(OPTIMIZED) $(DEBUG) $(INCS) $(PLUGS) $(SRC) -o rose $(LIBS) $(ADBLOCK)
|
||||
|
||||
inspect: build
|
||||
GTK_DEBUG=interactive ./rose
|
||||
|
||||
install: rose
|
||||
GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/
|
||||
cp -f rose /usr/bin
|
||||
mkdir -p /usr/share/themes/rose
|
||||
cp style.css /usr/share/themes/rose/
|
||||
|
|
|
@ -2,22 +2,16 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "str_init.h"
|
||||
#include "str_replace_start.h"
|
||||
|
||||
#define LIBRE_N 19
|
||||
#define LIBRE_N 50
|
||||
|
||||
/* Uncomment for debug */
|
||||
/* #define DEBUG */
|
||||
|
||||
/* Inspired by https://libredirect.github.io/, but in C. */
|
||||
|
||||
void str_init(char* str, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
str[i] = ' ';
|
||||
str[n] = '\0';
|
||||
} // could also use <https://manpages.ubuntu.com/manpages/impish/man3/strinit.3pub.html>
|
||||
|
||||
int libre_redirect(const char* uri, char* output)
|
||||
{
|
||||
int l1 = strlen(uri);
|
||||
|
@ -36,23 +30,29 @@ int libre_redirect(const char* uri, char* output)
|
|||
strcpy(tmp_output, output);
|
||||
|
||||
char* annoying_sites[] = {
|
||||
"https://www.youtube.com",
|
||||
"https://www.reddit.com",
|
||||
"https://www.youtube.com",
|
||||
"https://google.com",
|
||||
"https://medium.com",
|
||||
"https://translate.google.com",
|
||||
// "https://forum.effectivealtruism.org",
|
||||
"https://www.bloomberg.com",
|
||||
"https://twitter.com"
|
||||
"https://www.royalroad.com",
|
||||
"https://genius.com",
|
||||
// "https://archive.org",
|
||||
// "https://twitter.com"
|
||||
};
|
||||
|
||||
char* alternatives[] = {
|
||||
"https://old.reddit.com", // "https://teddit.nunosempere.com",
|
||||
"https://yt.artemislena.eu",
|
||||
"https://teddit.nunosempere.com",
|
||||
"https://search.nunosempere.com",
|
||||
"https://scribe.rip",
|
||||
"https://simplytranslate.org/",
|
||||
// "https://ea.greaterwrong.com",
|
||||
"https://translate.riverside.rocks/",
|
||||
"https://archive.is/https://www.bloomberg.com",
|
||||
"https://nitter.net"
|
||||
"https://royalread.nunosempere.com",
|
||||
"https://dumb.vern.cc",
|
||||
// "https://wayback.nunosempere.com",
|
||||
// "https://nitter.net"
|
||||
};
|
||||
|
||||
len = sizeof(annoying_sites) / sizeof(annoying_sites[0]);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#define LIBRE_N 19
|
||||
#define LIBRE_N 50
|
||||
|
||||
int libre_redirect(const char* uri, char* uri_filtered);
|
||||
void str_init(char* str, int n);
|
||||
|
|
6
plugins/libre_redirect/str_init.c
Normal file
6
plugins/libre_redirect/str_init.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
void str_init(char* str, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
str[i] = ' ';
|
||||
str[n] = '\0';
|
||||
} // could also use <https://manpages.ubuntu.com/manpages/impish/man3/strinit.3pub.html>
|
1
plugins/libre_redirect/str_init.h
Normal file
1
plugins/libre_redirect/str_init.h
Normal file
|
@ -0,0 +1 @@
|
|||
void str_init(char* str, int n);
|
|
@ -1,7 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define READABILITY_N 85133 + 1000
|
||||
#define READABILITY_N 85314 + 1000
|
||||
|
||||
void read_readability_js(char* string)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef READABILITY
|
||||
#define READABILITY
|
||||
|
||||
#define READABILITY_N 85133 + 1000
|
||||
#define READABILITY_N 85314 + 1000
|
||||
|
||||
void read_readability_js(char* string);
|
||||
|
||||
|
|
|
@ -2386,10 +2386,17 @@ if (document.domain == "archive.is" ){
|
|||
display: none !important;
|
||||
}
|
||||
|
||||
/* Matt Levine's Money Stuff specific stuff: */
|
||||
|
||||
p > span > em {
|
||||
display: none !important;
|
||||
}
|
||||
/* ^ deletes the subscribe prompt in Matt Levine's Money Stuff. */
|
||||
iframe {
|
||||
display: none;
|
||||
}
|
||||
#div[id^='stickypbModal'] {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
#!/bin/bash
|
||||
function sedr(){
|
||||
#!/bin/sh
|
||||
sed_wrapper()
|
||||
{
|
||||
find ./ -type f -exec sed -i -e "$1" {} \;
|
||||
} ## e.g., sedr "s/target/replacement/g"
|
||||
|
||||
READABILITY_N=$(wc -c readability.js | cut -d " " -f 1)
|
||||
sedr "s/^#define READABILITY_N .*/#define READABILITY_N $READABILITY_N + 1000/g"
|
||||
READABILITY_N=`wc -c readability.js | cut -d " " -f 1`
|
||||
sed_wrapper "s/^#define READABILITY_N .*/#define READABILITY_N $READABILITY_N + 1000/g"
|
||||
|
||||
|
|
7
plugins/shortcuts/README.md
Normal file
7
plugins/shortcuts/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
## About
|
||||
|
||||
This code automatically redirects shortcuts to their longer expansions. Similar to DuckDuckGo's bangs (<https://duckduckgo.com/bangs>)
|
||||
|
||||
Note that Whoogle (the default search engine) also has its own bangs!
|
||||
- See: https://github.com/benbusby/whoogle-search/blob/main/app/utils/bangs.py
|
||||
- and https://duckduckgo.com/bang.v255.js
|
74
plugins/shortcuts/shortcuts.c
Normal file
74
plugins/shortcuts/shortcuts.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../libre_redirect/str_init.h"
|
||||
#include "../libre_redirect/str_replace_start.h"
|
||||
|
||||
#define SHORTCUT_N 41
|
||||
|
||||
/* Uncomment for debug */
|
||||
/* #define DEBUG */
|
||||
|
||||
/* Inspired by https://duckduckgo.com/bangs */
|
||||
|
||||
int shortcut_expand(const char* uri, char* output)
|
||||
{
|
||||
printf("SHORTCUT EXPAND!\n");
|
||||
int l1 = strlen(uri);
|
||||
int l2 = strlen(output);
|
||||
int len;
|
||||
char tmp_uri[l2++];
|
||||
char tmp_output[l2++];
|
||||
|
||||
if ((l2 - l1) < SHORTCUT_N) {
|
||||
#ifdef DEBUG
|
||||
printf("Not enough memory\n");
|
||||
#endif
|
||||
return 1; // not enough memory.
|
||||
} else {
|
||||
strcpy(tmp_uri, uri); // strcpy also copies the terminating '\0'
|
||||
strcpy(tmp_output, output);
|
||||
|
||||
char* shortcuts[] = {
|
||||
"!fnf",
|
||||
"!fnc",
|
||||
"!hn",
|
||||
"!hnb"
|
||||
};
|
||||
|
||||
char* expansions[] = {
|
||||
"https://forum.nunosempere.com/frontpage",
|
||||
"https://forum.nunosempere.com/comments",
|
||||
"https://news.ycombinator.com",
|
||||
"https://news.ycombinator.com/best",
|
||||
};
|
||||
|
||||
// len = sizeof(shortcuts) / sizeof(shortcuts[0]);
|
||||
len = sizeof(shortcuts) / sizeof(char*);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
int replace_check = str_replace_start(tmp_uri, shortcuts[i],
|
||||
expansions[i], output);
|
||||
if (replace_check == 2) {
|
||||
#ifdef DEBUG
|
||||
printf("tmp_uri: %s\n", tmp_uri);
|
||||
printf("output: %s\n", output);
|
||||
#endif
|
||||
return 2;
|
||||
} else if (replace_check == 1) {
|
||||
#ifdef DEBUG
|
||||
printf("replace_check failed\n");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
strcpy(tmp_uri, output);
|
||||
str_init(output, l2);
|
||||
}
|
||||
strcpy(output, tmp_uri);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("No match found\n\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
5
plugins/shortcuts/shortcuts.h
Normal file
5
plugins/shortcuts/shortcuts.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#define SHORTCUT_N 41
|
||||
|
||||
int shortcut_expand(const char* uri, char* output);
|
|
@ -1,8 +1,9 @@
|
|||
#!/bin/bash
|
||||
function sedr(){
|
||||
#!/bin/sh
|
||||
sed_wrapper()
|
||||
{
|
||||
find ./ -type f -exec sed -i -e "$1" {} \;
|
||||
} ## e.g., sedr "s/target/replacement/g"
|
||||
|
||||
STYLE_N=$(wc -c style.js | cut -d " " -f 1)
|
||||
sedr "s/^#define STYLE_N .*/#define STYLE_N $STYLE_N + 1/g"
|
||||
STYLE_N=`wc -c style.js | cut -d " " -f 1`
|
||||
sed_wrapper "s/^#define STYLE_N .*/#define STYLE_N $STYLE_N + 100/g"
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#define STYLE_N 1393 + 1
|
||||
#define STYLE_N 4748 + 100
|
||||
|
||||
void read_style_js(char* string)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef STYLE
|
||||
#define STYLE
|
||||
|
||||
#define STYLE_N 1393 + 1
|
||||
#define STYLE_N 4748 + 100
|
||||
|
||||
void read_style_js(char* string);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ if (document.domain == "forum.effectivealtruism.org"){
|
|||
|
||||
if (document.domain == "mail.proton.me" ){
|
||||
styles = `
|
||||
/*
|
||||
.item-container-row.read, .item-container.read {
|
||||
background-color: white;
|
||||
}
|
||||
|
@ -36,6 +37,66 @@ if (document.domain == "mail.proton.me" ){
|
|||
.selection .item-container-row.item-is-selected, .item-container.item-is-selected {
|
||||
background-color: var(--selection-background-color) !important;
|
||||
}
|
||||
zoom: 0.625 !important;
|
||||
*/
|
||||
`
|
||||
}
|
||||
if (document.domain == "forum.nunosempere.com" ){
|
||||
styles = `
|
||||
body {
|
||||
zoom: 0.625 !important;
|
||||
}
|
||||
`
|
||||
}
|
||||
if (document.domain == "search.nunosempere.com" ){
|
||||
styles = `
|
||||
body {
|
||||
/* zoom: 1.8; */
|
||||
}
|
||||
|
||||
footer {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
}
|
||||
if (document.domain == "twitter.com" ){
|
||||
styles = `
|
||||
/* hide promoted tweets */
|
||||
:has(meta[property="og:site_name"][content="Twitter"])
|
||||
[data-testid="cellInnerDiv"]:has(svg + [dir="auto"]) {
|
||||
display: none;
|
||||
}
|
||||
[data-testid^="placementTracking"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* hide what's happening section */
|
||||
:has(meta[property="og:site_name"][content="Twitter"])
|
||||
[aria-label="Timeline: Trending now"] {
|
||||
display: none !important;
|
||||
}
|
||||
[data-testid^="sidebarColumn"] {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
if (document.domain == "reddit.com" || document.domain == "old.reddit.com"){
|
||||
styles = `
|
||||
/* kill sidebar ads */
|
||||
.native-ad-container,
|
||||
.premium-banner-outer,
|
||||
.native-sidebar-ad,
|
||||
.infobar-toaster-container,
|
||||
#eu-cookie-policy,
|
||||
.ad-container,
|
||||
.listingsignupbar,
|
||||
a[href="/premium"],
|
||||
[data-promoted^="true"],
|
||||
a[href^="https://alb.reddit.com"]
|
||||
{
|
||||
display: none !important;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
|
@ -46,4 +107,64 @@ if(styles != null){
|
|||
console.log('Style changed')
|
||||
}
|
||||
|
||||
|
||||
// Replace default alert with new function
|
||||
// whose style can be changed!
|
||||
window.alert = (message) => {
|
||||
let alertDiv = document.getElementById('customAlert');
|
||||
if (!alertDiv) {
|
||||
const html = `
|
||||
<div id="customAlert" class="custom-alert">
|
||||
<div class="custom-alert-content">
|
||||
<p id="alertMessage"></p>
|
||||
<button id="alertOkButton">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.custom-alert {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
.custom-alert-content {
|
||||
background-color: #fefefe;
|
||||
margin: 15% auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #888;
|
||||
width: 80%;
|
||||
font-family: monospace; /* Use monospace font */
|
||||
}
|
||||
.visible {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', dismissAlert);
|
||||
document.getElementById('alertMessage').textContent = message;
|
||||
alertDiv.classList.add('visible');
|
||||
}
|
||||
// ^ takes 0.014ms to run, so performance is not the concern here.
|
||||
// timed with console.time, console.timeEnd
|
||||
|
||||
document.body.style.visibility = "visible"
|
||||
|
|
90
rose.c
90
rose.c
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "plugins/libre_redirect/libre_redirect.h"
|
||||
#include "plugins/readability/readability.h"
|
||||
#include "plugins/shortcuts/shortcuts.h"
|
||||
#include "plugins/style/style.h"
|
||||
|
||||
// #include "plugins/stand_in/stand_in.h"
|
||||
|
@ -14,7 +15,8 @@
|
|||
int LIBRE_REDIRECT_ENABLED = true;
|
||||
int READABILITY_ENABLED = true;
|
||||
int CUSTOM_STYLE_ENABLED = true;
|
||||
int CUSTOM_USER_AGENT = true;
|
||||
int CUSTOM_USER_AGENT = false;
|
||||
int NUM_TABS = 0;
|
||||
|
||||
// to enable plugins,
|
||||
// 1. Enable them:
|
||||
|
@ -96,10 +98,19 @@ void load_uri(WebKitWebView* view, const char* uri)
|
|||
if (g_str_has_prefix(uri, "http://") || g_str_has_prefix(uri, "https://") || g_str_has_prefix(uri, "file://") || g_str_has_prefix(uri, "about:")) {
|
||||
webkit_web_view_load_uri(view, uri);
|
||||
} else {
|
||||
// webkit_web_view_load_uri(view, uri);
|
||||
char tmp[strlen(uri) + strlen(SEARCH)];
|
||||
snprintf(tmp, sizeof(tmp), SEARCH, uri);
|
||||
webkit_web_view_load_uri(view, tmp);
|
||||
// Check for shortcuts
|
||||
int l = SHORTCUT_N + strlen(uri) + 1;
|
||||
char uri_expanded[l];
|
||||
str_init(uri_expanded, l);
|
||||
int check = shortcut_expand(uri, uri_expanded);
|
||||
if (check == 2) {
|
||||
webkit_web_view_load_uri(view, uri_expanded);
|
||||
} else {
|
||||
// Feed into search engine.
|
||||
char tmp[strlen(uri) + strlen(SEARCH)];
|
||||
snprintf(tmp, sizeof(tmp), SEARCH, uri);
|
||||
webkit_web_view_load_uri(view, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,12 +194,17 @@ GtkWidget* handle_create_new_tab(WebKitWebView* self,
|
|||
WebKitNavigationAction* navigation_action,
|
||||
GtkNotebook* notebook)
|
||||
{
|
||||
WebKitURIRequest* uri_request = webkit_navigation_action_get_request(navigation_action);
|
||||
const char* uri = webkit_uri_request_get_uri(uri_request);
|
||||
printf("Creating new window: %s\n", uri);
|
||||
notebook_append(notebook, uri);
|
||||
gtk_notebook_set_show_tabs(notebook, true);
|
||||
return NULL;
|
||||
if (NUM_TABS < MAX_NUM_TABS || NUM_TABS == 0) {
|
||||
WebKitURIRequest* uri_request = webkit_navigation_action_get_request(navigation_action);
|
||||
const char* uri = webkit_uri_request_get_uri(uri_request);
|
||||
printf("Creating new window: %s\n", uri);
|
||||
notebook_append(notebook, uri);
|
||||
gtk_notebook_set_show_tabs(notebook, true);
|
||||
return NULL;
|
||||
} else {
|
||||
webkit_web_view_run_javascript(notebook_get_webview(notebook),
|
||||
"alert('Too many tabs, not opening a new one')", NULL, NULL, NULL);
|
||||
}
|
||||
/* WebKitGTK documentation recommends returning the new webview.
|
||||
* I imagine that this might allow e.g., to go back in a new tab
|
||||
* or generally to keep track of history.
|
||||
|
@ -199,27 +215,42 @@ GtkWidget* handle_create_new_tab(WebKitWebView* self,
|
|||
|
||||
void notebook_append(GtkNotebook* notebook, const char* uri)
|
||||
{
|
||||
GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(window));
|
||||
GdkVisual* rgba_visual = gdk_screen_get_rgba_visual(screen);
|
||||
GdkRGBA rgba;
|
||||
if (NUM_TABS < MAX_NUM_TABS || NUM_TABS == 0) {
|
||||
GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(window));
|
||||
GdkVisual* rgba_visual = gdk_screen_get_rgba_visual(screen);
|
||||
GdkRGBA rgba;
|
||||
|
||||
gdk_rgba_parse(&rgba, BG_COLOR);
|
||||
gdk_rgba_parse(&rgba, BG_COLOR);
|
||||
|
||||
WebKitWebView* view = webview_new();
|
||||
WebKitWebView* view = webview_new();
|
||||
|
||||
gtk_widget_set_visual(GTK_WIDGET(window), rgba_visual);
|
||||
g_signal_connect(view, "load_changed", G_CALLBACK(load_changed), notebook);
|
||||
g_signal_connect(view, "create", G_CALLBACK(handle_create_new_tab), notebook);
|
||||
gtk_widget_set_visual(GTK_WIDGET(window), rgba_visual);
|
||||
g_signal_connect(view, "load_changed", G_CALLBACK(load_changed), notebook);
|
||||
g_signal_connect(view, "create", G_CALLBACK(handle_create_new_tab), notebook);
|
||||
|
||||
int n = gtk_notebook_append_page(notebook, GTK_WIDGET(view), NULL);
|
||||
gtk_notebook_set_tab_reorderable(notebook, GTK_WIDGET(view), true);
|
||||
gtk_widget_show_all(GTK_WIDGET(window));
|
||||
gtk_widget_hide(GTK_WIDGET(bar));
|
||||
webkit_web_view_set_background_color(view, &rgba);
|
||||
load_uri(view, (uri) ? uri : HOME);
|
||||
gtk_notebook_set_current_page(notebook, n);
|
||||
gtk_notebook_set_tab_label_text(notebook, GTK_WIDGET(view), "-");
|
||||
webkit_web_view_set_zoom_level(view, ZOOM);
|
||||
int n = gtk_notebook_append_page(notebook, GTK_WIDGET(view), NULL);
|
||||
gtk_notebook_set_tab_reorderable(notebook, GTK_WIDGET(view), true);
|
||||
gtk_widget_show_all(GTK_WIDGET(window));
|
||||
gtk_widget_hide(GTK_WIDGET(bar));
|
||||
webkit_web_view_set_background_color(view, &rgba);
|
||||
load_uri(view, (uri) ? uri : HOME);
|
||||
|
||||
if (CUSTOM_STYLE_ENABLED) {
|
||||
char* style_js = malloc(STYLE_N + 1);
|
||||
read_style_js(style_js);
|
||||
webkit_web_view_run_javascript(notebook_get_webview(notebook), style_js,
|
||||
NULL, NULL, NULL);
|
||||
free(style_js);
|
||||
}
|
||||
|
||||
gtk_notebook_set_current_page(notebook, n);
|
||||
gtk_notebook_set_tab_label_text(notebook, GTK_WIDGET(view), "-");
|
||||
webkit_web_view_set_zoom_level(view, ZOOM);
|
||||
NUM_TABS += 1;
|
||||
} else {
|
||||
webkit_web_view_run_javascript(notebook_get_webview(notebook),
|
||||
"alert('Too many tabs, not opening a new one')", NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void show_bar(GtkNotebook* notebook)
|
||||
|
@ -306,6 +337,7 @@ int handle_key(func id, GtkNotebook* notebook)
|
|||
|
||||
case close_tab:
|
||||
gtk_notebook_remove_page(notebook, gtk_notebook_get_current_page(notebook));
|
||||
NUM_TABS -= 1;
|
||||
|
||||
switch (gtk_notebook_get_n_pages(notebook)) {
|
||||
case 0:
|
||||
|
@ -436,7 +468,7 @@ void setup(GtkNotebook* notebook, int argc, char** argv)
|
|||
window_init(notebook);
|
||||
|
||||
// Initialize with first uri
|
||||
char* first_uri = argc > 1 ? argv[1] : NULL;
|
||||
char* first_uri = argc > 1 ? argv[1] : HOME;
|
||||
notebook_init(notebook, first_uri);
|
||||
g_object_set(gtk_settings_get_default(), GTK, NULL);
|
||||
|
||||
|
|
BIN
screenshots/6-hello-world.png
Normal file
BIN
screenshots/6-hello-world.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 302 KiB |
BIN
screenshots/7-hello-world-search.png
Normal file
BIN
screenshots/7-hello-world-search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
20
style.css
20
style.css
|
@ -11,7 +11,7 @@
|
|||
outline-color: @Lavender;
|
||||
color: @Text;
|
||||
border-color: white;
|
||||
font-size: 16px;
|
||||
font-size: 25px;
|
||||
/*@Base; */
|
||||
/* border-bottom-color: @Base; */
|
||||
}
|
||||
|
@ -20,6 +20,23 @@ window, notebook, headerbar {
|
|||
background: @Base;
|
||||
}
|
||||
|
||||
/* Make titlebar pretty gigantic. I'm pretty myopic. */
|
||||
.titlebar {
|
||||
padding: 10px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
|
||||
.titlebar * {
|
||||
padding: 10px;
|
||||
font-size: 27px;
|
||||
}
|
||||
|
||||
header * {
|
||||
font-size: 20px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
tabs {
|
||||
background-color: @Base;
|
||||
padding: 3px;
|
||||
|
@ -32,6 +49,7 @@ tab {
|
|||
margin: 2px 5px 2px 0px;
|
||||
padding: 5px;
|
||||
border-style: solid;
|
||||
font-size: 27px;
|
||||
/*border-color: white;
|
||||
border-bottom-color: white;
|
||||
outline-color: white;
|
||||
|
|
9
user-scripts/ubuntu-20.04/rose-GIO_MODULE_DIR.desktop
Executable file
9
user-scripts/ubuntu-20.04/rose-GIO_MODULE_DIR.desktop
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env xdg-open
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Exec=/home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose.sh %u
|
||||
Name=Rose
|
||||
Comment=Minimalistic browser
|
||||
Icon=/home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-desktop-icon.png
|
BIN
user-scripts/ubuntu-20.04/rose-images/rose-homepage-1.6-zoom.png
Normal file
BIN
user-scripts/ubuntu-20.04/rose-images/rose-homepage-1.6-zoom.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 102 KiB |
BIN
user-scripts/ubuntu-20.04/rose-images/rose-homepage-2.png
Normal file
BIN
user-scripts/ubuntu-20.04/rose-images/rose-homepage-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 142 KiB |
|
@ -3,7 +3,7 @@
|
|||
Version=1.0
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Exec= /usr/bin/rose %u
|
||||
Exec=/bin/rose %u
|
||||
Name=Rose
|
||||
Comment=Minimalistic browser
|
||||
Icon=/home/loki/Documents/core/software/fresh/C/rose-browser/rosenrot/user-scripts/ubuntu-20.04/rose-images/rose-desktop-icon.png
|
||||
|
|
3
user-scripts/ubuntu-20.04/rose.sh
Executable file
3
user-scripts/ubuntu-20.04/rose.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/ /bin/rose "$1"
|
||||
|
Loading…
Reference in New Issue
Block a user