Skip to content

Commit

Permalink
Add QOL fixes to CSS parser
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinL10 committed Aug 29, 2023
1 parent aed35b0 commit ec40b4d
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 75 deletions.
54 changes: 11 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,20 @@

![Actions status](https://github.com/KevinL10/browser/actions/workflows/CI.yml/badge.svg)


A web browser implemented from scratch in Python.


Adapted from [browser.engineering](https://browser.engineering/).



### Supported features:

ch. 1
- `HTTP/1.1`
- File URI scheme
- data scheme
- view-source scheme


### Todo:

ch.2
- Scrolling (mouse wheel & up/down keys)

### Todo:



ch.3
- font size, weight, slant (support for `<big>, <small>, <i>, <b>, <br>`)
- font caching

### Todo:
- ch. 1: Custom testing infrastructure (serving test websites with specific headers / content)
- ch. 1: HTTP response caching
- ch. 1: Support transfer-encoding: chunked

- ch. 2: Emoji support
- ch. 2: Allow browser resizing
- ch. 2: Zoom for font size

- ch. 3: Superscripts (`<sup>`)
- ch. 3: Soft hyphens – breaking a long word across lines
- ch. 3: Small caps (`<abbr>`)
- ch. 3: Preformatted text (`<pre>`)

- ch. 4: comments
- ch. 4: paragraphs
- ch. 4: scripts
- ch. 4: quoted attributes
- ch. 4: syntax highlighting
- [] Fix comment handling in HTML and CSS parser
- [] <pre> and <code>
- [] Browser resizing
- [] Visual scroll bar
- [] Bullet lists <li>
- [] Inline CSS styling <style>
- [] Additional CSS selectors
- [] Move block/inline display to the default CSS file
- [] Class selectors for CSS
- [] Add width and height to block objects
- [] Implement font-family for CSS
10 changes: 7 additions & 3 deletions browser/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
ENTITIES = {
"<": "&lt;",
">": "&gt;"
"&lt;": "<",
"&gt;": ">",
"&ldquo;": '"',
"&rdquo;": '"',
"&lsquo;": "'",
"&rsquo;": "'",
"&copy;": "©",
}

# Canvas width and height
Expand All @@ -17,4 +22,3 @@

# Maximum number of redirects before erroring
MAX_REDIRECTS = 5

3 changes: 1 addition & 2 deletions browser/graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from browser.constants import VSTEP, HEIGHT, WIDTH, SCROLL_STEP
from browser.layout import (
DocumentLayout,
print_layout,
DrawRect,
DrawLine,
DrawText,
Expand Down Expand Up @@ -108,7 +107,7 @@ def load(self, url):
self.document = DocumentLayout(self.node)
self.document.layout()

print_layout(self.document)
# print_layout(self.document)

# The display_list consists of commands like DrawText and DrawRect
self.display_list = []
Expand Down
17 changes: 10 additions & 7 deletions browser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,17 +293,20 @@ def style(node, rules):
for property, value in pairs.items():
node.style[property] = value

# print(rules)
# Resolve font sizes
parent_px = (
float(node.parent.style["font-size"][:-2])
if node.parent
else INHERITED_PROPERTIES["font-size"]
)

# Resolve font percentage sign
if node.style["font-size"].endswith("%"):
if node.parent:
parent_font_size = node.parent.style["font-size"]
else:
parent_font_size = INHERITED_PROPERTIES["font-size"]

node_pct = float(node.style["font-size"][:-1]) / 100
parent_px = float(parent_font_size[:-2])
node.style["font-size"] = str(parent_px * node_pct) + "px"
elif node.style["font-size"].endswith("em"):
node_em = float(node.style["font-size"][:-2])
node.style["font-size"] = str(node_em * parent_px) + "px"

for child in node.children:
style(child, rules)
Expand Down
7 changes: 5 additions & 2 deletions browser/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,11 @@ def request(self, num_redirects=0):
# For view-source schemes, we show the raw HTML output
# by replacing reserved characters with entities
if self.url.startswith("view-source:"):
for reserved, entity in ENTITIES.items():
body = body.replace(reserved, entity)
for entity, character in ENTITIES.items():
body = body.replace(character, entity)
else:
for entity, character in ENTITIES.items():
body = body.replace(entity, character)

return headers, body

Expand Down
9 changes: 0 additions & 9 deletions browser6.css

This file was deleted.

56 changes: 47 additions & 9 deletions tests/browser.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,51 @@
pre {
background-color: gray;
h1 {
font-size: 2em;
font-weight: bold;
}

h1 {
font-size: 300%;
h2 {
font-size: 1.5em;
font-weight: bold;
}

h3 {
font-size: 1.17em;
font-weight: bold;
}

h4 {
font-size: 1.33em;
font-weight: bold;
}

h5 {
font-size: 0.83em;
font-weight: bold;
}

h6 {
font-size: 0.67em;
font-weight: bold;
}

a {
color: blue;
}

i {
font-style: italic;
}

b {
font-weight: bold;
}

small {
font-size: 90%;
}

big {
font-size: 110%;
}

a { color: blue; }
i { font-style: italic; }
b { font-weight: bold; }
small { font-size: 90%; }
big { font-size: 110%; }
/* https://www.w3schools.com/cssref/css_default_values.php */
8 changes: 8 additions & 0 deletions tests/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@

<link href="pre-blue.css" rel="stylesheet" />


</head>
<body>
<h1>
Title!
</h1>
<h2>
An h2 header
</h2>
<h3>
An h3 header
</h3>

<a>
This is some a text
</a>
Expand Down

0 comments on commit ec40b4d

Please sign in to comment.