mirror of
https://github.com/neon-mmd/websurfx.git
synced 2024-12-24 21:38:22 -05:00
Merge branch 'rolling' into rolling
This commit is contained in:
commit
bdc5170c87
132
Cargo.lock
generated
132
Cargo.lock
generated
@ -65,15 +65,15 @@ checksum = "a2e7b88f3804e01bd4191fdb08650430bbfcb43d3d9b2890064df3551ec7d25b"
|
||||
dependencies = [
|
||||
"actix-http",
|
||||
"actix-web",
|
||||
"futures 0.3.29",
|
||||
"futures 0.3.30",
|
||||
"governor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "actix-http"
|
||||
version = "3.4.0"
|
||||
version = "3.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9"
|
||||
checksum = "129d4c88e98860e1758c5de288d1632b07970a16d59bdf7b8d66053d582bb71f"
|
||||
dependencies = [
|
||||
"actix-codec",
|
||||
"actix-rt",
|
||||
@ -111,14 +111,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
|
||||
dependencies = [
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "actix-router"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799"
|
||||
checksum = "d22475596539443685426b6bdadb926ad0ecaefdfc5fb05e5e3441f15463c511"
|
||||
dependencies = [
|
||||
"bytestring",
|
||||
"http 0.2.11",
|
||||
@ -177,9 +177,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "actix-web"
|
||||
version = "4.4.0"
|
||||
version = "4.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9"
|
||||
checksum = "e43428f3bf11dee6d166b00ec2df4e3aa8cc1606aaa0b7433c146852e2f4e03b"
|
||||
dependencies = [
|
||||
"actix-codec",
|
||||
"actix-http",
|
||||
@ -224,7 +224,7 @@ dependencies = [
|
||||
"actix-router",
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -313,9 +313,9 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.76"
|
||||
version = "1.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59d2a3357dde987206219e78ecfbbb6e8dad06cbb65292758d3270e6254f7355"
|
||||
checksum = "c9d19de80eff169429ac1e9f48fffb163916b448a44e8e046186232046d9e1f9"
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
@ -369,7 +369,7 @@ checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -552,9 +552,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo-platform"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff"
|
||||
checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -824,12 +824,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.9"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5"
|
||||
checksum = "82a9b73a36529d9c47029b9fb3a6f0ea3cc916a261195352ba19e770fc1748b2"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils 0.8.17",
|
||||
"crossbeam-utils 0.8.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -882,9 +882,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.17"
|
||||
version = "0.8.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f"
|
||||
checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
@ -941,7 +941,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331"
|
||||
dependencies = [
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1232,9 +1232,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -1247,9 +1247,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@ -1257,9 +1257,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-cpupool"
|
||||
@ -1273,9 +1273,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@ -1284,32 +1284,32 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
|
||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
|
||||
[[package]]
|
||||
name = "futures-timer"
|
||||
@ -1319,9 +1319,9 @@ checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -1394,7 +1394,7 @@ checksum = "821239e5672ff23e2a7060901fa622950bbd80b649cdaadd78d1c1767ed14eb4"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"dashmap",
|
||||
"futures 0.3.29",
|
||||
"futures 0.3.30",
|
||||
"futures-timer",
|
||||
"no-std-compat",
|
||||
"nonzero_ext",
|
||||
@ -1725,13 +1725,13 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.9"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
|
||||
checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2018,7 +2018,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e0b72e7c9042467008b10279fc732326bd605459ae03bda88825909dd19b56"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-utils 0.8.17",
|
||||
"crossbeam-utils 0.8.18",
|
||||
"dashmap",
|
||||
"skeptic",
|
||||
"smallvec 1.11.2",
|
||||
@ -2198,9 +2198,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.32.1"
|
||||
version = "0.32.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
|
||||
checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@ -2240,7 +2240,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2451,7 +2451,7 @@ dependencies = [
|
||||
"phf_shared 0.11.2",
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2498,7 +2498,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2606,7 +2606,7 @@ version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab"
|
||||
dependencies = [
|
||||
"crossbeam-utils 0.8.17",
|
||||
"crossbeam-utils 0.8.18",
|
||||
"libc",
|
||||
"mach2",
|
||||
"once_cell",
|
||||
@ -2798,7 +2798,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"bytes 1.5.0",
|
||||
"combine",
|
||||
"futures 0.3.29",
|
||||
"futures 0.3.30",
|
||||
"futures-util",
|
||||
"itoa 1.0.10",
|
||||
"percent-encoding 2.3.1",
|
||||
@ -3047,11 +3047,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.22"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
|
||||
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3178,7 +3178,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3414,9 +3414,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.42"
|
||||
version = "2.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8"
|
||||
checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
@ -3474,15 +3474,15 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.8.1"
|
||||
version = "3.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
|
||||
checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand",
|
||||
"redox_syscall 0.4.1",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3655,7 +3655,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3993,7 +3993,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@ -4027,7 +4027,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@ -4056,7 +4056,7 @@ checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10"
|
||||
|
||||
[[package]]
|
||||
name = "websurfx"
|
||||
version = "1.6.8"
|
||||
version = "1.6.11"
|
||||
dependencies = [
|
||||
"actix-cors",
|
||||
"actix-files",
|
||||
@ -4070,7 +4070,7 @@ dependencies = [
|
||||
"env_logger",
|
||||
"error-stack",
|
||||
"fake-useragent",
|
||||
"futures 0.3.29",
|
||||
"futures 0.3.30",
|
||||
"lightningcss",
|
||||
"log",
|
||||
"maud",
|
||||
@ -4324,5 +4324,5 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.71",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.42",
|
||||
"syn 2.0.43",
|
||||
]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "websurfx"
|
||||
version = "1.6.8"
|
||||
version = "1.6.11"
|
||||
edition = "2021"
|
||||
description = "An open-source alternative to Searx that provides clean, ad-free, and organic results with incredible speed while keeping privacy and security in mind."
|
||||
repository = "https://github.com/neon-mmd/websurfx"
|
||||
|
@ -60,4 +60,4 @@
|
||||
# calls the build function
|
||||
packages.websurfx = packages.default;
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,62 @@
|
||||
/**
|
||||
* This functions gets the saved cookies if it is present on the user's machine If it
|
||||
* is available then it is parsed and converted to an object which is then used to
|
||||
* retrieve the preferences that the user had selected previously and is then loaded
|
||||
* and used for displaying the user provided settings by setting them as the selected
|
||||
* options in the settings page.
|
||||
*
|
||||
* @function
|
||||
* @param {string} cookie - It takes the client settings cookie as a string.
|
||||
* @returns {void}
|
||||
*/
|
||||
function setClientSettingsOnPage(cookie) {
|
||||
let cookie_value = cookie
|
||||
.split(';')
|
||||
.map((item) => item.split('='))
|
||||
.reduce((acc, [_, v]) => (acc = JSON.parse(v)) && acc, {})
|
||||
|
||||
// Loop through all select tags and add their values to the cookie dictionary
|
||||
document.querySelectorAll('select').forEach((select_tag) => {
|
||||
switch (select_tag.name) {
|
||||
case 'themes':
|
||||
select_tag.value = cookie_value['theme']
|
||||
break
|
||||
case 'colorschemes':
|
||||
select_tag.value = cookie_value['colorscheme']
|
||||
break
|
||||
case 'animations':
|
||||
select_tag.value = cookie_value['animation']
|
||||
break
|
||||
case 'safe_search_levels':
|
||||
select_tag.value = cookie_value['safe_search_level']
|
||||
break
|
||||
}
|
||||
})
|
||||
let engines = document.querySelectorAll('.engine')
|
||||
let engines_cookie = cookie_value['engines']
|
||||
|
||||
if (engines_cookie.length === engines.length) {
|
||||
document.querySelector('.select_all').checked = true
|
||||
engines.forEach((engine_checkbox) => {
|
||||
engine_checkbox.checked = true
|
||||
})
|
||||
} else {
|
||||
engines.forEach((engines_checkbox) => {
|
||||
engines_checkbox.checked = false
|
||||
})
|
||||
engines_cookie.forEach((engine_name) => {
|
||||
engines.forEach((engine_checkbox) => {
|
||||
if (
|
||||
engine_checkbox.parentNode.parentNode.innerText.trim() ===
|
||||
engine_name.trim()
|
||||
) {
|
||||
engine_checkbox.checked = true
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is executed when any page on the website finishes loading and
|
||||
* this function retrieves the cookies if it is present on the user's machine.
|
||||
@ -16,9 +75,14 @@ document.addEventListener(
|
||||
let cookie = decodeURIComponent(document.cookie)
|
||||
// Set the value of the input field to the decoded cookie value if it is not empty
|
||||
// Otherwise, display a message indicating that no cookies have been saved on the user's system
|
||||
document.querySelector('.cookies input').value = cookie.length
|
||||
? cookie
|
||||
: 'No cookies have been saved on your system'
|
||||
if (cookie.length) {
|
||||
document.querySelector('.cookies input').value = cookie
|
||||
// This function displays the user provided settings on the settings page.
|
||||
setClientSettingsOnPage(cookie)
|
||||
} else {
|
||||
document.querySelector('.cookies input').value =
|
||||
'No cookies have been saved on your system'
|
||||
}
|
||||
} catch (error) {
|
||||
// If there is an error decoding the cookie, log the error to the console
|
||||
// and display an error message in the input field
|
||||
|
@ -600,12 +600,20 @@ footer div {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.settings_container .tab .description {
|
||||
.settings_container .tab .description,
|
||||
.settings_container .tab .admin_warning {
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.settings_container .tab .description {
|
||||
color: var(--foreground-color);
|
||||
}
|
||||
|
||||
.settings_container .tab .admin_warning {
|
||||
color: var(--color-two);
|
||||
}
|
||||
|
||||
.settings_container .user_interface select,
|
||||
.settings_container .general select {
|
||||
margin: 0.7rem 0;
|
||||
|
@ -6,6 +6,7 @@
|
||||
pub mod brave;
|
||||
pub mod duckduckgo;
|
||||
pub mod librex;
|
||||
pub mod mojeek;
|
||||
pub mod search_result_parser;
|
||||
pub mod searx;
|
||||
pub mod startpage;
|
||||
|
151
src/engines/mojeek.rs
Normal file
151
src/engines/mojeek.rs
Normal file
@ -0,0 +1,151 @@
|
||||
//! The `mojeek` module handles the scraping of results from the mojeek search engine
|
||||
//! by querying the upstream mojeek search engine with user provided query and with a page
|
||||
//! number if provided.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use reqwest::header::HeaderMap;
|
||||
use reqwest::Client;
|
||||
use scraper::Html;
|
||||
|
||||
use crate::models::aggregation_models::SearchResult;
|
||||
|
||||
use crate::models::engine_models::{EngineError, SearchEngine};
|
||||
|
||||
use error_stack::{Report, Result, ResultExt};
|
||||
|
||||
use super::search_result_parser::SearchResultParser;
|
||||
|
||||
/// A new Mojeek engine type defined in-order to implement the `SearchEngine` trait which allows to
|
||||
/// reduce code duplication as well as allows to create vector of different search engines easily.
|
||||
pub struct Mojeek {
|
||||
/// The parser, used to interpret the search result.
|
||||
parser: SearchResultParser,
|
||||
}
|
||||
|
||||
impl Mojeek {
|
||||
/// Creates the Mojeek parser.
|
||||
pub fn new() -> Result<Self, EngineError> {
|
||||
Ok(Self {
|
||||
parser: SearchResultParser::new(
|
||||
".result-col",
|
||||
".results-standard li",
|
||||
"a span.url",
|
||||
"h2 a.title",
|
||||
"p.s",
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SearchEngine for Mojeek {
|
||||
async fn results(
|
||||
&self,
|
||||
query: &str,
|
||||
page: u32,
|
||||
user_agent: &str,
|
||||
client: &Client,
|
||||
safe_search: u8,
|
||||
) -> Result<HashMap<String, SearchResult>, EngineError> {
|
||||
// Mojeek uses `start results from this number` convention
|
||||
// So, for 10 results per page, page 0 starts at 1, page 1
|
||||
// starts at 11, and so on.
|
||||
let results_per_page = 10;
|
||||
let start_result = results_per_page * page + 1;
|
||||
|
||||
let results_per_page = results_per_page.to_string();
|
||||
let start_result = start_result.to_string();
|
||||
|
||||
let search_engines = vec![
|
||||
"Bing",
|
||||
"Brave",
|
||||
"DuckDuckGo",
|
||||
"Ecosia",
|
||||
"Google",
|
||||
"Lilo",
|
||||
"Metager",
|
||||
"Qwant",
|
||||
"Startpage",
|
||||
"Swisscows",
|
||||
"Yandex",
|
||||
"Yep",
|
||||
"You",
|
||||
];
|
||||
let qss = search_engines.join("%2C");
|
||||
let safe = if safe_search == 0 { "0" } else { "1" };
|
||||
|
||||
// Mojeek detects automated requests, these are preferences that are
|
||||
// able to circumvent the countermeasure. Some of these are
|
||||
// not documented in their Search API
|
||||
let query_params: Vec<(&str, &str)> = vec![
|
||||
("t", results_per_page.as_str()),
|
||||
("theme", "dark"),
|
||||
("arc", "none"),
|
||||
("date", "1"),
|
||||
("cdate", "1"),
|
||||
("tlen", "100"),
|
||||
("ref", "1"),
|
||||
("hp", "minimal"),
|
||||
("lb", "en"),
|
||||
("qss", &qss),
|
||||
("safe", safe),
|
||||
];
|
||||
|
||||
let mut query_params_string = String::new();
|
||||
for (k, v) in &query_params {
|
||||
query_params_string.push_str(&format!("&{k}={v}"));
|
||||
}
|
||||
|
||||
let url: String = match page {
|
||||
0 => {
|
||||
format!("https://www.mojeek.com/search?q={query}{query_params_string}")
|
||||
}
|
||||
_ => {
|
||||
format!(
|
||||
"https://www.mojeek.com/search?q={query}&s={start_result}{query_params_string}"
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let mut cookie_string = String::new();
|
||||
for (k, v) in &query_params {
|
||||
cookie_string.push_str(&format!("{k}={v}; "));
|
||||
}
|
||||
|
||||
let header_map = HeaderMap::try_from(&HashMap::from([
|
||||
("USER_AGENT".to_string(), user_agent.to_string()),
|
||||
("REFERER".to_string(), "https://google.com/".to_string()),
|
||||
(
|
||||
"CONTENT_TYPE".to_string(),
|
||||
"application/x-www-form-urlencoded".to_string(),
|
||||
),
|
||||
("COOKIE".to_string(), cookie_string),
|
||||
]))
|
||||
.change_context(EngineError::UnexpectedError)?;
|
||||
|
||||
let document: Html = Html::parse_document(
|
||||
&Mojeek::fetch_html_from_upstream(self, &url, header_map, client).await?,
|
||||
);
|
||||
|
||||
if let Some(no_result_msg) = self.parser.parse_for_no_results(&document).nth(0) {
|
||||
if no_result_msg
|
||||
.inner_html()
|
||||
.contains("No pages found matching:")
|
||||
{
|
||||
return Err(Report::new(EngineError::EmptyResultSet));
|
||||
}
|
||||
}
|
||||
|
||||
// scrape all the results from the html
|
||||
self.parser
|
||||
.parse_for_results(&document, |title, url, desc| {
|
||||
Some(SearchResult::new(
|
||||
title.inner_html().trim(),
|
||||
url.inner_html().trim(),
|
||||
desc.inner_html().trim(),
|
||||
&["mojeek"],
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
@ -162,6 +162,10 @@ impl EngineHandler {
|
||||
let engine = crate::engines::librex::LibreX::new()?;
|
||||
("librex", Box::new(engine))
|
||||
}
|
||||
"mojeek" => {
|
||||
let engine = crate::engines::mojeek::Mojeek::new()?;
|
||||
("mojeek", Box::new(engine))
|
||||
}
|
||||
_ => {
|
||||
return Err(Report::from(EngineError::NoSuchEngineFound(
|
||||
engine_name.to_string(),
|
||||
|
@ -12,14 +12,16 @@ use std::fs::read_to_string;
|
||||
/// Handles the route of index page or main page of the `websurfx` meta search engine website.
|
||||
#[get("/")]
|
||||
pub async fn index(config: web::Data<Config>) -> Result<HttpResponse, Box<dyn std::error::Error>> {
|
||||
Ok(HttpResponse::Ok().body(
|
||||
crate::templates::views::index::index(
|
||||
&config.style.colorscheme,
|
||||
&config.style.theme,
|
||||
&config.style.animation,
|
||||
)
|
||||
.0,
|
||||
))
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("text/html; charset=utf-8")
|
||||
.body(
|
||||
crate::templates::views::index::index(
|
||||
&config.style.colorscheme,
|
||||
&config.style.theme,
|
||||
&config.style.animation,
|
||||
)
|
||||
.0,
|
||||
))
|
||||
}
|
||||
|
||||
/// Handles the route of any other accessed route/page which is not provided by the
|
||||
@ -52,14 +54,16 @@ pub async fn robots_data(_req: HttpRequest) -> Result<HttpResponse, Box<dyn std:
|
||||
/// Handles the route of about page of the `websurfx` meta search engine website.
|
||||
#[get("/about")]
|
||||
pub async fn about(config: web::Data<Config>) -> Result<HttpResponse, Box<dyn std::error::Error>> {
|
||||
Ok(HttpResponse::Ok().body(
|
||||
crate::templates::views::about::about(
|
||||
&config.style.colorscheme,
|
||||
&config.style.theme,
|
||||
&config.style.animation,
|
||||
)
|
||||
.0,
|
||||
))
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("text/html; charset=utf-8")
|
||||
.body(
|
||||
crate::templates::views::about::about(
|
||||
&config.style.colorscheme,
|
||||
&config.style.theme,
|
||||
&config.style.animation,
|
||||
)
|
||||
.0,
|
||||
))
|
||||
}
|
||||
|
||||
/// Handles the route of settings page of the `websurfx` meta search engine website.
|
||||
@ -67,16 +71,16 @@ pub async fn about(config: web::Data<Config>) -> Result<HttpResponse, Box<dyn st
|
||||
pub async fn settings(
|
||||
config: web::Data<Config>,
|
||||
) -> Result<HttpResponse, Box<dyn std::error::Error>> {
|
||||
Ok(HttpResponse::Ok().body(
|
||||
crate::templates::views::settings::settings(
|
||||
&config.style.colorscheme,
|
||||
&config.style.theme,
|
||||
&config.style.animation,
|
||||
&config
|
||||
.upstream_search_engines
|
||||
.keys()
|
||||
.collect::<Vec<&String>>(),
|
||||
)?
|
||||
.0,
|
||||
))
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("text/html; charset=utf-8")
|
||||
.body(
|
||||
crate::templates::views::settings::settings(
|
||||
config.safe_search,
|
||||
&config.style.colorscheme,
|
||||
&config.style.theme,
|
||||
&config.style.animation,
|
||||
&config.upstream_search_engines,
|
||||
)?
|
||||
.0,
|
||||
))
|
||||
}
|
||||
|
@ -59,25 +59,27 @@ pub async fn search(
|
||||
)
|
||||
};
|
||||
|
||||
// .max(1) makes sure that the page > 0.
|
||||
let page = params.page.unwrap_or(1).max(1);
|
||||
// .max(1) makes sure that the page >= 0.
|
||||
let page = params.page.unwrap_or(1).max(1) - 1;
|
||||
|
||||
let (_, results, _) = join!(
|
||||
get_results(page - 1),
|
||||
get_results(page.saturating_sub(1)),
|
||||
get_results(page),
|
||||
get_results(page + 1)
|
||||
);
|
||||
|
||||
Ok(HttpResponse::Ok().body(
|
||||
crate::templates::views::search::search(
|
||||
&config.style.colorscheme,
|
||||
&config.style.theme,
|
||||
&config.style.animation,
|
||||
query,
|
||||
&results?,
|
||||
)
|
||||
.0,
|
||||
))
|
||||
Ok(HttpResponse::Ok()
|
||||
.content_type("text/html; charset=utf-8")
|
||||
.body(
|
||||
crate::templates::views::search::search(
|
||||
&config.style.colorscheme,
|
||||
&config.style.theme,
|
||||
&config.style.animation,
|
||||
query,
|
||||
&results?,
|
||||
)
|
||||
.0,
|
||||
))
|
||||
}
|
||||
None => Ok(HttpResponse::TemporaryRedirect()
|
||||
.insert_header(("location", "/"))
|
||||
|
@ -1,17 +1,20 @@
|
||||
//! A module that handles the engines tab for setting page view in the `websurfx` frontend.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use maud::{html, Markup};
|
||||
|
||||
/// A functions that handles the html code for the engines tab for the settings page for the search page.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `engine_names` - It takes the list of all available engine names as an argument.
|
||||
/// * `engine_names` - It takes the key value pair list of all available engine names and there corresponding
|
||||
/// selected (enabled/disabled) value as an argument.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// It returns the compiled html markup code for the engines tab.
|
||||
pub fn engines(engine_names: &[&String]) -> Markup {
|
||||
pub fn engines(engine_names: &HashMap<String, bool>) -> Markup {
|
||||
html!(
|
||||
div class="engines tab"{
|
||||
h1{"Engines"}
|
||||
@ -20,21 +23,49 @@ pub fn engines(engine_names: &[&String]) -> Markup {
|
||||
"Select the search engines from the list of engines that you want results from"
|
||||
}
|
||||
.engine_selection{
|
||||
.toggle_btn{
|
||||
label class="switch"{
|
||||
input type="checkbox" class="select_all" onchange="toggleAllSelection()";
|
||||
span class="slider round"{}
|
||||
}
|
||||
"Select All"
|
||||
// Checks whether all the engines are selected or not if they are then the
|
||||
// checked `select_all` button is rendered otherwise the unchecked version
|
||||
// is rendered.
|
||||
@if engine_names.values().all(|selected| *selected){
|
||||
.toggle_btn{
|
||||
label class="switch"{
|
||||
input type="checkbox" class="select_all" onchange="toggleAllSelection()" checked;
|
||||
span class="slider round"{}
|
||||
}
|
||||
"Select All"
|
||||
}
|
||||
}
|
||||
@else{
|
||||
.toggle_btn {
|
||||
label class="switch"{
|
||||
input type="checkbox" class="select_all" onchange="toggleAllSelection()";
|
||||
span class="slider round"{}
|
||||
}
|
||||
"Select All"
|
||||
}
|
||||
}
|
||||
hr;
|
||||
@for engine_name in engine_names{
|
||||
.toggle_btn{
|
||||
label class="switch"{
|
||||
input type="checkbox" class="engine";
|
||||
span class="slider round"{}
|
||||
@for (engine_name, selected) in engine_names{
|
||||
// Checks whether the `engine_name` is selected or not if they are then the
|
||||
// checked `engine` button is rendered otherwise the unchecked version is
|
||||
// rendered.
|
||||
@if *selected {
|
||||
.toggle_btn{
|
||||
label class="switch"{
|
||||
input type="checkbox" class="engine" checked;
|
||||
span class="slider round"{}
|
||||
}
|
||||
(format!("{}{}",engine_name[..1].to_uppercase().to_owned(), engine_name[1..].to_owned()))
|
||||
}
|
||||
}
|
||||
@else {
|
||||
.toggle_btn {
|
||||
label class="switch"{
|
||||
input type="checkbox" class="engine";
|
||||
span class="slider round"{}
|
||||
}
|
||||
(format!("{}{}",engine_name[..1].to_uppercase().to_owned(), engine_name[1..].to_owned()))
|
||||
}
|
||||
(format!("{}{}",engine_name[..1].to_uppercase().to_owned(), engine_name[1..].to_owned()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,14 @@ const SAFE_SEARCH_LEVELS: [(u8, &str); 3] = [(0, "None"), (1, "Low"), (2, "Moder
|
||||
|
||||
/// A functions that handles the html code for the general tab for the settings page for the search page.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `safe_search_level` - It takes the safe search level as an argument.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// It returns the compiled html markup code for the general tab.
|
||||
pub fn general() -> Markup {
|
||||
pub fn general(safe_search_level: u8) -> Markup {
|
||||
html!(
|
||||
div class="general tab active"{
|
||||
h1{"General"}
|
||||
@ -18,9 +22,19 @@ pub fn general() -> Markup {
|
||||
p class="description"{
|
||||
"Select a safe search level from the menu below to filter content based on the level."
|
||||
}
|
||||
select name="safe_search_levels"{
|
||||
@for (k,v) in SAFE_SEARCH_LEVELS{
|
||||
option value=(k){(v)}
|
||||
@if safe_search_level < 3 {
|
||||
select name="safe_search_levels" {
|
||||
// Sets the user selected safe_search_level name from the config file as the first option in the selection list.
|
||||
option value=(safe_search_level){(SAFE_SEARCH_LEVELS.iter().find(|level| level.0 == safe_search_level).unwrap().1)}
|
||||
@for (k,v) in SAFE_SEARCH_LEVELS.iter().filter(|level| level.0 != safe_search_level){
|
||||
option value=(k){(v)}
|
||||
}
|
||||
}
|
||||
}
|
||||
@else {
|
||||
p class="admin_warning" {"⚠️ This setting is being managed by the server administrator."}
|
||||
select name="safe_search_levels" disabled {
|
||||
option value=(SAFE_SEARCH_LEVELS[2].0){(SAFE_SEARCH_LEVELS[2].1)}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,16 @@ use crate::handler::{file_path, FileType};
|
||||
use maud::{html, Markup};
|
||||
use std::fs::read_dir;
|
||||
|
||||
/// A helper function that helps in building the list of all available colorscheme/theme names
|
||||
/// present in the colorschemes and themes folder respectively.
|
||||
/// A helper function that helps in building the list of all available colorscheme/theme/animation
|
||||
/// names present in the colorschemes, animations and themes folder respectively by excluding the
|
||||
/// ones that have already been selected via the config file.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `style_type` - It takes the style type of the values `theme` and `colorscheme` as an
|
||||
/// argument.
|
||||
/// * `selected_style` - It takes the currently selected style value provided via the config file
|
||||
/// as an argument.
|
||||
///
|
||||
/// # Error
|
||||
///
|
||||
@ -18,7 +21,8 @@ use std::fs::read_dir;
|
||||
/// returns a standard error message.
|
||||
fn style_option_list(
|
||||
style_type: &str,
|
||||
) -> Result<Vec<(String, String)>, Box<dyn std::error::Error + '_>> {
|
||||
selected_style: &str,
|
||||
) -> Result<Vec<(String, String)>, Box<dyn std::error::Error>> {
|
||||
let mut style_option_names: Vec<(String, String)> = Vec::new();
|
||||
for file in read_dir(format!(
|
||||
"{}static/{}/",
|
||||
@ -26,7 +30,13 @@ fn style_option_list(
|
||||
style_type,
|
||||
))? {
|
||||
let style_name = file?.file_name().to_str().unwrap().replace(".css", "");
|
||||
style_option_names.push((style_name.clone(), style_name.replace('-', " ")));
|
||||
if selected_style != style_name {
|
||||
style_option_names.push((style_name.clone(), style_name.replace('-', " ")));
|
||||
}
|
||||
}
|
||||
|
||||
if style_type == "animations" {
|
||||
style_option_names.push(("".to_owned(), "none".to_owned()))
|
||||
}
|
||||
|
||||
Ok(style_option_names)
|
||||
@ -38,7 +48,11 @@ fn style_option_list(
|
||||
///
|
||||
/// It returns the compiled html markup code for the user interface tab on success otherwise
|
||||
/// returns a standard error message.
|
||||
pub fn user_interface() -> Result<Markup, Box<dyn std::error::Error>> {
|
||||
pub fn user_interface(
|
||||
theme: &str,
|
||||
colorscheme: &str,
|
||||
animation: &Option<String>,
|
||||
) -> Result<Markup, Box<dyn std::error::Error>> {
|
||||
Ok(html!(
|
||||
div class="user_interface tab"{
|
||||
h1{"User Interface"}
|
||||
@ -47,7 +61,9 @@ pub fn user_interface() -> Result<Markup, Box<dyn std::error::Error>> {
|
||||
"Select the theme from the available themes to be used in user interface"
|
||||
}
|
||||
select name="themes"{
|
||||
@for (k,v) in style_option_list("themes")?{
|
||||
// Sets the user selected theme name from the config file as the first option in the selection list.
|
||||
option value=(theme){(theme.replace('-', " "))}
|
||||
@for (k,v) in style_option_list("themes", theme)?{
|
||||
option value=(k){(v)}
|
||||
}
|
||||
}
|
||||
@ -56,7 +72,9 @@ pub fn user_interface() -> Result<Markup, Box<dyn std::error::Error>> {
|
||||
"Select the color scheme for your theme to be used in user interface"
|
||||
}
|
||||
select name="colorschemes"{
|
||||
@for (k,v) in style_option_list("colorschemes")?{
|
||||
// Sets the user selected colorscheme name from the config file as the first option in the selection list.
|
||||
option value=(colorscheme){(colorscheme.replace('-', " "))}
|
||||
@for (k,v) in style_option_list("colorschemes", colorscheme)?{
|
||||
option value=(k){(v)}
|
||||
}
|
||||
}
|
||||
@ -65,12 +83,12 @@ pub fn user_interface() -> Result<Markup, Box<dyn std::error::Error>> {
|
||||
"Select the animation for your theme to be used in user interface"
|
||||
}
|
||||
select name="animations"{
|
||||
option value=""{"none"}
|
||||
@for (k,v) in style_option_list("animations")?{
|
||||
// Sets the user selected animation name from the config file as the first option in the selection list.
|
||||
option value=(animation.as_ref().unwrap_or(&"".to_owned())){(animation.as_ref().unwrap_or(&"".to_owned()).replace('-'," "))}
|
||||
@for (k,v) in style_option_list("animations", animation.as_ref().unwrap_or(&"".to_owned()))?{
|
||||
option value=(k){(v)}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
))
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! A module that handles the view for the settings page in the `websurfx` frontend.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use maud::{html, Markup};
|
||||
|
||||
use crate::templates::partials::{
|
||||
@ -14,8 +16,10 @@ use crate::templates::partials::{
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `safe_search_level` - It takes the safe search level as an argument.
|
||||
/// * `colorscheme` - It takes the colorscheme name as an argument.
|
||||
/// * `theme` - It takes the theme name as an argument.
|
||||
/// * `animation` - It takes the animation name as an argument.
|
||||
/// * `engine_names` - It takes a list of engine names as an argument.
|
||||
///
|
||||
/// # Error
|
||||
@ -23,10 +27,11 @@ use crate::templates::partials::{
|
||||
/// This function returns a compiled html markup code on success otherwise returns a standard error
|
||||
/// message.
|
||||
pub fn settings(
|
||||
safe_search_level: u8,
|
||||
colorscheme: &str,
|
||||
theme: &str,
|
||||
animation: &Option<String>,
|
||||
engine_names: &[&String],
|
||||
engine_names: &HashMap<String, bool>,
|
||||
) -> Result<Markup, Box<dyn std::error::Error>> {
|
||||
Ok(html!(
|
||||
(header(colorscheme, theme, animation))
|
||||
@ -41,8 +46,8 @@ pub fn settings(
|
||||
.btn onclick="setActiveTab(this)"{"cookies"}
|
||||
}
|
||||
.main_container{
|
||||
(general())
|
||||
(user_interface()?)
|
||||
(general(safe_search_level))
|
||||
(user_interface(theme, colorscheme, animation)?)
|
||||
(engines(engine_names))
|
||||
(cookies())
|
||||
p class="message"{}
|
||||
|
@ -64,4 +64,5 @@ upstream_search_engines = {
|
||||
Brave = false,
|
||||
Startpage = false,
|
||||
LibreX = false,
|
||||
Mojeek = false,
|
||||
} -- select the upstream search engines from which the results should be fetched.
|
||||
|
Loading…
Reference in New Issue
Block a user