Skip to content

Commit e2f3a22

Browse files
committed
refactor: Refactor for relative paths in link hrefs and a shitty implementation of !important
1 parent 58b87ae commit e2f3a22

11 files changed

Lines changed: 222 additions & 282 deletions

File tree

harbor/engine/res/css/harbor.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
html, body {
2+
background-color: #11111b !important;
3+
color: #a6adc8 !important;
4+
}
5+
6+
h1 {
7+
color: #cdd6f4;
8+
}
9+
10+
a {
11+
color: #89b4fa;
12+
}
13+
14+
h1, h2, p, ul { margin-left: 2rem; }
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Harbor: No Connection</title>
7+
</head>
8+
<body>
9+
10+
</body>
11+
</html>

harbor/engine/res/pages/tab.html

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,8 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>New Tab</title>
7-
<style>
8-
html, body {
9-
background-color: #11111b;
10-
color: #a6adc8;
11-
}
12-
13-
h1 {
14-
color: #cdd6f4;
15-
}
16-
17-
a {
18-
color: #89b4fa;
19-
}
20-
21-
h1, h2, p, ul { margin-left: 2rem; }
22-
</style>
6+
<title>Harbor: New Tab</title>
7+
<link rel="stylesheet" href="../css/harbor.css"/>
238
</head>
249
<body>
2510
<h1>Welcome to your new tab!</h1>

harbor/engine/src/agent.rs

Lines changed: 73 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,15 @@ use std::rc::Rc;
55

66
use crate::{
77
css::{cssom::CSSStyleSheet, parser::parse_stylesheet, tokenize::tokenize},
8+
globals::{
9+
ERROR, ERROR_PAGE_PATH, NEW_TAB, NEW_TAB_PAGE_PATH, NO_CONNECTION, NO_CONNECTION_PAGE_PATH,
10+
NO_CONNECTION_URL,
11+
},
812
html5::{dom::Document, parse::Parser},
9-
http::{Client, Header, Protocol, Request, url::URL},
13+
http::{
14+
Client, Header, Protocol, Request, RequestIntegrityError, RequestIntegrityErrorKind,
15+
url::URL,
16+
},
1017
infra::{InputStream, Serializable},
1118
};
1219

@@ -69,8 +76,11 @@ impl Agent {
6976
});
7077

7178
let response = match _response {
72-
Some(resp) => resp,
73-
None => return None,
79+
Ok(resp) => resp,
80+
Err(_) => {
81+
eprintln!("Failed to fetch stylesheet URL: {}", resolved_url);
82+
return None;
83+
}
7484
};
7585

7686
match response.body {
@@ -96,25 +106,48 @@ impl Agent {
96106
return Some(css_content);
97107
}
98108

109+
fn open_error_page(&mut self, error: RequestIntegrityError) -> Rc<RefCell<Document>> {
110+
let url = match error.kind {
111+
RequestIntegrityErrorKind::NoConnection => NO_CONNECTION_URL,
112+
RequestIntegrityErrorKind::InvalidMethod => "harbor:invalidmethod",
113+
RequestIntegrityErrorKind::InvalidHeaders => "harbor:invalidheaders",
114+
RequestIntegrityErrorKind::InvalidBody => "harbor:invalidbody",
115+
};
116+
117+
self.open(url).unwrap()
118+
}
119+
99120
pub fn open(&mut self, url: &str) -> Option<Rc<RefCell<Document>>> {
100121
if url.starts_with("harbor:") {
101122
let path = url.trim_start_matches("harbor:").to_string();
102123

103-
match path.as_str() {
104-
"new" => {
105-
let html_content = fs::read_to_string("res/pages/tab.html").unwrap();
106-
let mut stream =
107-
InputStream::new(&html_content.chars().collect::<Vec<char>>()[..]);
124+
let path = match path.as_str() {
125+
NEW_TAB => NEW_TAB_PAGE_PATH,
126+
NO_CONNECTION => NO_CONNECTION_PAGE_PATH,
127+
ERROR => ERROR_PAGE_PATH,
128+
_ => ERROR_PAGE_PATH,
129+
};
130+
131+
println!("Path: {}", path);
132+
let html_content = fs::read_to_string(path).unwrap();
133+
let mut stream = InputStream::new(&html_content.chars().collect::<Vec<char>>()[..]);
134+
135+
let document = Parser::parse_stream(&mut stream);
136+
document
137+
.borrow_mut()
138+
.insert_stylesheet(0, self.ua_stylesheet.clone());
108139

109-
let document = Parser::parse_stream(&mut stream);
110-
document
111-
.borrow_mut()
112-
.insert_stylesheet(0, self.ua_stylesheet.clone());
140+
let this_url = format!(
141+
"file://{}/{}",
142+
std::env::current_dir().unwrap().to_str().unwrap(),
143+
path
144+
);
113145

114-
return Some(document);
115-
}
116-
_ => return None,
117-
}
146+
println!("This URL: {}", this_url);
147+
148+
self.handle_link_elements(&this_url, &document);
149+
150+
return Some(document);
118151
}
119152

120153
let maybe_resolved_url = URL::pure_parse(url.to_string());
@@ -144,8 +177,8 @@ impl Agent {
144177
});
145178

146179
let response = match _response {
147-
Some(resp) => resp,
148-
None => return None,
180+
Ok(resp) => resp,
181+
Err(e) => return Some(self.open_error_page(e)),
149182
};
150183

151184
match response.body {
@@ -167,27 +200,33 @@ impl Agent {
167200
.borrow_mut()
168201
.insert_stylesheet(0, self.ua_stylesheet.clone());
169202

170-
let links = document.borrow().get_links();
203+
self.handle_link_elements(url, &document);
171204

172-
for link in links {
173-
if !link
174-
.borrow()
175-
.rel_list()
176-
.contains(&String::from("stylesheet"))
177-
{
178-
continue;
179-
}
205+
self.cached_pages.insert(resolved_url, Rc::clone(&document));
180206

181-
if let Some(stylesheet) = self.fetch_stylesheet(&link.borrow().href) {
182-
document
183-
.borrow_mut()
184-
.insert_stylesheet(0, stylesheet.clone());
185-
}
207+
return Some(document);
208+
}
209+
}
210+
211+
fn handle_link_elements(&mut self, root_url: &str, document: &Rc<RefCell<Document>>) {
212+
let links = document.borrow().get_links();
213+
214+
for link in links {
215+
if !link
216+
.borrow()
217+
.rel_list()
218+
.contains(&String::from("stylesheet"))
219+
{
220+
continue;
186221
}
187222

188-
self.cached_pages.insert(resolved_url, Rc::clone(&document));
223+
let joint = URL::join_urls(root_url.to_string(), link.borrow().href.clone()).unwrap();
189224

190-
return Some(document);
225+
if let Some(stylesheet) = self.fetch_stylesheet(joint.serialize().as_str()) {
226+
document
227+
.borrow_mut()
228+
.insert_stylesheet(0, stylesheet.clone());
229+
}
191230
}
192231
}
193232
}

harbor/engine/src/globals.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,17 @@ pub const INITIAL_WINDOW_HEIGHT: u32 = 600;
1818
pub const MINIMUM_WINDOW_WIDTH: u32 = 400;
1919
pub const MINIMUM_WINDOW_HEIGHT: u32 = 300;
2020

21-
pub const NEW_TAB_URL: &str = "harbor:new";
21+
pub const NEW_TAB_URL: &str = "harbor:new-tab";
22+
pub const NEW_TAB: &str = "new-tab";
23+
pub const NEW_TAB_PAGE_PATH: &str = "res/pages/tab.html";
24+
25+
pub const NO_CONNECTION_URL: &str = "harbor:no-connection";
26+
pub const NO_CONNECTION: &str = "no-connection";
27+
pub const NO_CONNECTION_PAGE_PATH: &str = "res/pages/no_connection.html";
28+
29+
pub const ERROR_URL: &str = "harbor:error";
30+
pub const ERROR: &str = "error";
31+
pub const ERROR_PAGE_PATH: &str = "res/pages/error.html";
2232

2333
// TODO: Make this configurable
2434
pub const TABS_BAR_OFFSET: fn(f64, f64) -> (f64, f64) =

harbor/engine/src/html5/dom.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
use std::collections::HashMap;
12
use std::fmt::Debug;
23
use std::ops::Deref;
34
use std::rc::Weak;
45
use std::{cell::RefCell, rc::Rc};
56

67
use crate::css::r#box::declarations::handle_declaration;
78
use crate::css::cssom::{
8-
CSSRuleNode, CSSRuleType, CSSStyleRuleData, CSSStyleSheet, CSSStyleSheetExt, ComputedStyle,
9-
DocumentOrShadowRootStyle, StyleSheetList,
9+
CSSDeclaration, CSSRuleNode, CSSRuleType, CSSStyleRuleData, CSSStyleSheet, CSSStyleSheetExt,
10+
ComputedStyle, DocumentOrShadowRootStyle, StyleSheetList,
1011
};
1112
use crate::css::selectors::MatchesElement;
1213
use crate::html5::elements::link::LinkElement;
@@ -1027,6 +1028,8 @@ impl Element {
10271028
let document = node_doc.borrow();
10281029
let style_sheets = document.style_sheets();
10291030

1031+
let mut declarations_to_use: HashMap<String, Vec<CSSDeclaration>> = HashMap::new();
1032+
10301033
for stylesheet in style_sheets.style_sheets.iter() {
10311034
for rule in stylesheet.borrow().css_rules().iter() {
10321035
match rule.deref()._type() {
@@ -1040,12 +1043,17 @@ impl Element {
10401043
for selector in style_rule.selectors() {
10411044
if selector.matches(self, parents) {
10421045
for declaration in style_rule.declarations() {
1043-
handle_declaration(
1044-
declaration,
1045-
self.style_mut(),
1046-
parents,
1047-
viewport_size,
1048-
);
1046+
declarations_to_use
1047+
.entry(declaration.property_name.clone())
1048+
.or_insert_with(Vec::new)
1049+
.push(declaration.clone());
1050+
1051+
// handle_declaration(
1052+
// declaration,
1053+
// self.style_mut(),
1054+
// parents,
1055+
// viewport_size,
1056+
// );
10491057
}
10501058
}
10511059
}
@@ -1057,6 +1065,18 @@ impl Element {
10571065
}
10581066
}
10591067

1068+
for (_, declaration) in declarations_to_use.iter() {
1069+
let mut declaration_to_use = declaration.last().unwrap();
1070+
1071+
for decl in declaration.iter().rev() {
1072+
if decl.important && !declaration_to_use.important {
1073+
declaration_to_use = decl;
1074+
}
1075+
}
1076+
1077+
handle_declaration(declaration_to_use, self.style_mut(), parents, viewport_size);
1078+
}
1079+
10601080
let mut new_parents = match parents {
10611081
Some(p) => p.clone(),
10621082
None => vec![],

harbor/engine/src/html5/elements/link.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const VALID_RELS: [&str; 13] = [
1414
"stylesheet",
1515
];
1616

17+
#[derive(Debug)]
1718
pub struct LinkElement {
1819
pub disabled: bool,
1920
pub href: String,

0 commit comments

Comments
 (0)