more quick answers

* notepad

* fix config

* mdn docs

* search bar fix
This commit is contained in:
Shrecknt 2024-04-14 21:35:23 -07:00 committed by GitHub
parent 99a28ce8d3
commit 25760146a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 89 additions and 7 deletions

View File

@ -14,17 +14,17 @@ pub struct Config {
impl Config { impl Config {
pub fn read_or_create() -> eyre::Result<Self> { pub fn read_or_create() -> eyre::Result<Self> {
let default_config_str = include_str!("../default-config.toml"); let default_config_str = include_str!("../default-config.toml");
let default_config = toml::from_str(default_config_str)?; let mut config: Config = toml::from_str(default_config_str)?;
let config_path = Path::new("config.toml"); let config_path = Path::new("config.toml");
if config_path.exists() { if config_path.exists() {
let mut given_config = toml::from_str::<Config>(&fs::read_to_string(config_path)?)?; let given_config = toml::from_str::<Config>(&fs::read_to_string(config_path)?)?;
given_config.update(default_config); config.update(given_config);
Ok(given_config) Ok(config)
} else { } else {
println!("No config found, creating one at {config_path:?}"); println!("No config found, creating one at {config_path:?}");
fs::write(config_path, default_config_str)?; fs::write(config_path, default_config_str)?;
Ok(default_config) Ok(config)
} }
} }

View File

@ -1,6 +1,7 @@
pub mod dictionary; pub mod dictionary;
pub mod fend; pub mod fend;
pub mod ip; pub mod ip;
pub mod notepad;
pub mod numbat; pub mod numbat;
pub mod thesaurus; pub mod thesaurus;
pub mod timezone; pub mod timezone;

View File

@ -0,0 +1,13 @@
use crate::engines::{EngineResponse, SearchQuery};
use super::regex;
pub fn request(query: &SearchQuery) -> EngineResponse {
if !regex!("(note|text|code) ?(pad|book|edit(or|er)?)").is_match(&query.query.to_lowercase()) {
return EngineResponse::new();
}
EngineResponse::answer_html(
r#"<div contenteditable id='notepad' placeholder='Notes' style='width:100%;color:white;outline:none;min-height:4em;font-size:12px;'></div>"#.to_string()
)
}

View File

@ -38,6 +38,7 @@ engines! {
Dictionary = "dictionary", Dictionary = "dictionary",
Fend = "fend", Fend = "fend",
Ip = "ip", Ip = "ip",
Notepad = "notepad",
Numbat = "numbat", Numbat = "numbat",
Thesaurus = "thesaurus", Thesaurus = "thesaurus",
Timezone = "timezone", Timezone = "timezone",
@ -46,6 +47,7 @@ engines! {
// post-search // post-search
DocsRs = "docs_rs", DocsRs = "docs_rs",
GitHub = "github", GitHub = "github",
Mdn = "mdn",
StackExchange = "stackexchange", StackExchange = "stackexchange",
} }
@ -63,6 +65,7 @@ engine_requests! {
Dictionary => answer::dictionary::request, parse_response, Dictionary => answer::dictionary::request, parse_response,
Fend => answer::fend::request, None, Fend => answer::fend::request, None,
Ip => answer::ip::request, None, Ip => answer::ip::request, None,
Notepad => answer::notepad::request, None,
Numbat => answer::numbat::request, None, Numbat => answer::numbat::request, None,
Thesaurus => answer::thesaurus::request, parse_response, Thesaurus => answer::thesaurus::request, parse_response,
Timezone => answer::timezone::request, None, Timezone => answer::timezone::request, None,
@ -77,9 +80,10 @@ engine_autocomplete_requests! {
} }
engine_postsearch_requests! { engine_postsearch_requests! {
StackExchange => postsearch::stackexchange::request, parse_response,
GitHub => postsearch::github::request, parse_response,
DocsRs => postsearch::docs_rs::request, parse_response, DocsRs => postsearch::docs_rs::request, parse_response,
GitHub => postsearch::github::request, parse_response,
Mdn => postsearch::mdn::request, parse_response,
StackExchange => postsearch::stackexchange::request, parse_response,
} }
impl fmt::Display for Engine { impl fmt::Display for Engine {

View File

@ -4,4 +4,5 @@
pub mod docs_rs; pub mod docs_rs;
pub mod github; pub mod github;
pub mod mdn;
pub mod stackexchange; pub mod stackexchange;

View File

@ -0,0 +1,54 @@
use scraper::{Html, Selector};
use crate::engines::{HttpResponse, Response, CLIENT};
pub fn request(response: &Response) -> Option<reqwest::RequestBuilder> {
for search_result in response.search_results.iter().take(8) {
if search_result
.url
.starts_with("https://developer.mozilla.org/en-US/docs/Web")
{
return Some(CLIENT.get(search_result.url.as_str()));
}
}
None
}
pub fn parse_response(HttpResponse { res, body }: &HttpResponse) -> Option<String> {
let url = res.url().clone();
let dom = Html::parse_document(body);
let page_title = dom
.select(&Selector::parse("header > h1").unwrap())
.next()?
.text()
.collect::<String>()
.trim()
.to_string();
let doc_query = Selector::parse(".section-content").unwrap();
let doc_html = dom
.select(&doc_query)
.next()
.map(|doc| doc.inner_html())
.unwrap_or_default();
let doc_html = ammonia::Builder::default()
.link_rel(None)
.url_relative(ammonia::UrlRelative::RewriteWithBase(url.clone()))
.clean(&doc_html)
.to_string();
let title_html = format!(
r#"<h2><a href="{url}">{title}</a></h2>"#,
url = html_escape::encode_quoted_attribute(&url.to_string()),
title = html_escape::encode_safe(&page_title),
);
Some(format!(
r#"{title_html}<div class="infobox-mdn-article">{doc_html}</div>"#
))
}

View File

@ -109,6 +109,15 @@ document.addEventListener("keydown", (e) => {
return; return;
} }
// if the currently selected element is not the search bar and is contenteditable, don't do anything
const focusedEl = document.querySelector(":focus");
if (
focusedEl &&
(focusedEl.tagName == "input" ||
focusedEl.getAttribute("contenteditable") !== null)
)
return;
// if the user starts typing but they don't have focus on the input, focus it // if the user starts typing but they don't have focus on the input, focus it
// no modifier keys // no modifier keys