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 {
pub fn read_or_create() -> eyre::Result<Self> {
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");
if config_path.exists() {
let mut given_config = toml::from_str::<Config>(&fs::read_to_string(config_path)?)?;
given_config.update(default_config);
Ok(given_config)
let given_config = toml::from_str::<Config>(&fs::read_to_string(config_path)?)?;
config.update(given_config);
Ok(config)
} else {
println!("No config found, creating one at {config_path:?}");
fs::write(config_path, default_config_str)?;
Ok(default_config)
Ok(config)
}
}

View File

@ -1,6 +1,7 @@
pub mod dictionary;
pub mod fend;
pub mod ip;
pub mod notepad;
pub mod numbat;
pub mod thesaurus;
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",
Fend = "fend",
Ip = "ip",
Notepad = "notepad",
Numbat = "numbat",
Thesaurus = "thesaurus",
Timezone = "timezone",
@ -46,6 +47,7 @@ engines! {
// post-search
DocsRs = "docs_rs",
GitHub = "github",
Mdn = "mdn",
StackExchange = "stackexchange",
}
@ -63,6 +65,7 @@ engine_requests! {
Dictionary => answer::dictionary::request, parse_response,
Fend => answer::fend::request, None,
Ip => answer::ip::request, None,
Notepad => answer::notepad::request, None,
Numbat => answer::numbat::request, None,
Thesaurus => answer::thesaurus::request, parse_response,
Timezone => answer::timezone::request, None,
@ -77,9 +80,10 @@ engine_autocomplete_requests! {
}
engine_postsearch_requests! {
StackExchange => postsearch::stackexchange::request, parse_response,
GitHub => postsearch::github::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 {

View File

@ -4,4 +4,5 @@
pub mod docs_rs;
pub mod github;
pub mod mdn;
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;
}
// 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
// no modifier keys