ie6 blog post, click on blog images, prims.js syntax highlighting

This commit is contained in:
Murphy 2024-09-25 12:02:27 -04:00
parent 83a1fe244f
commit d5fed52363
Signed by: freya
GPG key ID: 744AB800E383AE52
16 changed files with 324 additions and 8 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
src/public/css/*.css src/public/css/*.css
!src/public/css/prism.css
data data

View file

@ -40,7 +40,7 @@ http {
} }
location / { location / {
add_header Content-Security-Policy "script-src 'none'; object-src 'none'; base-uri 'none'"; add_header Content-Security-Policy "object-src 'none'; base-uri 'none'";
root /opt/website/web; root /opt/website/web;
include fastcgi_params; include fastcgi_params;
fastcgi_pass php:9000; fastcgi_pass php:9000;

View file

@ -0,0 +1,241 @@
---
name: IE6
date: 2024-09-25T09:28:35-04:00
desc: Why must i make myself suffer...
---
For a while now I have been in the rabbit hole of downloading old browsers and
seeing what features they no longer support. Some bowsers dont support fonts,
some dont support styling, and one of them called IE6 is the worst of them all!
I am not sure what made me decide that making my website work on old browsers
was a good idea, but over the past few months, i've been slowly improving
my websites compatibility. Now I can fully say my website works all the way
back to IE6.
### Timescale
Not only is IE6 hard to support, it is really old (compared to today). IE6
was released on August 24, 2001, which was almost 23 years ago. Thats older
than me! When this browser was created I wasn't even born, yet people from that
time could go to my website, and it would work.
> Why not support an older browser?
Well as much as I hate myself, I don't hate myself that much... for now. The
main reason to stop at IE6 is the website, [caniuse.com](https://caniuse.com),
does not collect data before IE6. So it would be really hard to try to figure
out what css is suppored before then. Also IE6 used to be a standard basis for
many real websites to support, which means there are a lot of chat logs,
posts, and whatnot explaning how to get things working. All of this I cannot
say the same for IE5, or even Netscape.
### How i did it
Now into how I got this working. Well it was a lot of things. Quite a lot did
not work at all. When I first tried rendering my website in IE6, it looked like
this: ![Website before modifications](public/blog/site1.jpg)
... not great. There is no background, fonts, colors are wrong. Acually there
are NO style sheets loading at all! What you are looking at is just html and
nothing else!
### Firefox First
To tackle this I decided to fix things in stages and try to get old firefox
working first. And to start I decided to pick Firefox 10, released in 2012.
And this was a much better starting point since the website was still broken,
but some styling was still working: ![Website FF10](public/blog/site2.jpg)
The background seemed to work, and images were loading, but fonts, font colors,
and just the entire layout was broken.
#### -moz
It turnes out that a lot of older browsers to support alot of the features I
use, but they are not accessable though the normal css tag. Instead you have
to apply the vendor prefix, and for firefox its -moz.
#### scss
Now since I wanted to support multiple older browsers, I would need multiple
vendor prefixes. And these prefixes would need to be duplicated for every
single css style that needs them (a lot). So I switched to using scss, due to
its feature called mixins. This would allow me to create a mixin that could
take the normal arguments of any style, and output all of the vendor prefixes.
For eamaple:
```scss
@mixin linear-gradient($values...) {
background: -webkit-linear-gradient($values);
background: -moz-linear-gradient($values);
background: linear-gradient($values);
}
```
Now i only have to type `@linear-gradient(...)` and it will compile down to
all the vendor prefixes!
#### what broke
> So what was broken?
Well quite a lot broke. In no particular order, the following css styles needed
vendor prefixes:
- display
- flex-direction
- justify-content
- align-items
- linear-gradient
- fit-content
- keyframes
Now some of you may see flex box styles in there and think:
> Wait IE6 doesnt support Flex?!
..and you would be correct. As I started getting FF3.5, then FF2 to work. Even
more things broke. But as soon as I made the jump to suppot IE9, all hell broke
loose.
### the layout
Now some people might know why supporting old IE sucks, and my biggest reason
is that getting your layout working is awful. There is no flex box. There is
no css grid. You only have tables.
Now writing out <table\> all over my source code would not be fun. It would
be harder to work with, and would also just look bad. So thank god for the
css style `display: table`. With this style, you can mimmic your website
using bunch of tables, and can get different blocks to flow correctly.
The only issue is that display table isnt great for horozontal lists. Such as
the links in my nav bar. They were vertical and not across. To fix this I also
pulled an old IE trick and turned it into a list (<ul\>), and made each of the
<li\> elements `display: inline-block`, so that they would not wrap.
Horray now my website works. Lets see how it looks in IE6...
![Broken IE6](public/blog/site3.jpg)
... dear god why is nothing working?!?!
### IE6
#### URIs
For some reason IE6 does not like to load relative paths. It does not support
them. At all. If i had a link starting with / to load a css file, it would not
load it. All of my links to go to other pages were also broken. IE6 requires
a `http://` in front of any uri. So now I had to create a function that
generates the first half of the url `http://<host>:<port><base>`, and I could
then apply that to every URL.
#### Fonts
Another things that IE6 doesnt support is fonts... kinda. It does not support
TTF, OTF, WOFF, WOFF2, or any font format besides one called embedded opentype
i.e. .eot. So all I had to do to fix that was generate eot font files from my
ttf ones, and add those in. Now my font-family mixin looks like this:
```scss
@mixin font-face($name) {
@font-face {
font-family: $name;
src: url("../font/" + $name + ".eot");
src: url("../font/" + $name + ".eot?#iefix") format("embedded-opentype"),
url("../font/" + $name + ".woff2") format("woff2"),
url("../font/" + $name + ".woff") format("woff"),
url("../font/" + $name + ".ttf") format("truetype"),
url("../font/" + $name + ".otf") format("opentype"),
url("../font/" + $name + ".svg#" + $name) format('svg');
font-weight: normal;
font-style: normal;
font-display: swap;
}
}
```
#### How is it now?
![Bettter IE6](public/blog/site4.jpg)
Well it mostly works, but the layout is still kinda broken, and there
are box sizing issues.
#### Layout
Well remember how i started using `display: table`. Well IE6 and IE7 do not
support it. Now like i said earlier I didnt want to go putting tables around
in my html. So I decided to compromise. When viewing from IE6 and IE7, I
only show one column instead of the normal two for my website. Along with a
few extra padding fixes my layout was fixed.
#### Box sizing
CSS has a property called `box-sizing`, which defines how the width and height of
an element should be caculated. By default `content-box` says to not include
border and padding in the calculations, while `border-box` does include them.
So in the above image, the reason the header is bulging is because its given
a set height, then after that its adding the padding. This breaks it since i
want some padding and the header to stay the height i tell it.
The issue is that IE6 and IE7 do not support box-sizing. Thankfully there is a
pollyfill for it!
> Wait... what is a pollyfill?
Well a pollyfill is a set of javascript that can add support for newer features
in older browsers. Normally they are used to add more modern JS standard library
functions, but they can also be used to fix css.
I found this [github repo](https://github.com/Schepp/box-sizing-polyfill) that
contains a polyfill, but wait. What the heck is a htc file?
#### IE6 HTML Components
Turns out Microsoft struck again and implemented a non web standard feature in
their browser, because .htc files are not at all supported in any other browser.
Well it turns out that .htc files are just java script that runs on a per html
element. It provides the `element` variable that the script can use to access
the current element its being run on. So if I applied it to my entire page,
it would run the javascript code for every single element on my page. To enable
a htc file you got to use the `behavior` css property.
```scss
#header, #footer {
behavior: url(boxsizing.htc);
}
```
Now this polyfill can be used to recaculate the width and height of the header
and footer elements!
### IE6 Works
And now everything works:
![Website working under IE6](public/blog/site5.jpg);
### Conclusion
I do not know what made me want to do this, but i did it. It works. Yay!
Oh and for the love for god do not do this yourself (unless you hate yourself).
Also, a final list of every css style that does not work in IE6 (that i used
to use)...
- flex boxes and
- display table
- gradients
- margin:auto (in some cases)
- most fonts (besides eot)
- css animations
- css variables
- border radius
- fit content
- html elments:
- header
- footer
- section
- nav

BIN
src/public/blog/site1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
src/public/blog/site2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

BIN
src/public/blog/site3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

BIN
src/public/blog/site4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

BIN
src/public/blog/site5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

3
src/public/css/prism.css Normal file
View file

@ -0,0 +1,3 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism-okaidia&languages=markup+css+clike+javascript+bash+c+cpp+lua+markup-templating+php+rust+scss */
code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}

15
src/public/js/prism.js Normal file

File diff suppressed because one or more lines are too long

View file

@ -9,6 +9,21 @@
display: inline-block; display: inline-block;
} }
#post {
code span {
margin-left: 0 !important;
}
img {
margin: $inner-gap;
margin-left: auto;
margin-right: auto;
display: block;
max-width: 100%;
width: 400px;
}
}
#comments { #comments {
> span { > span {
margin-bottom: 10px; margin-bottom: 10px;

View file

@ -36,17 +36,31 @@ class Blog_model extends Model {
$data['desc'] = lang('blog_short_desc'); $data['desc'] = lang('blog_short_desc');
return $data; return $data;
} }
private function update_images(string $md): string {
$pattern = '/<img src="(.*)" alt="(.*)".*>/';
$base = $this->get_url('');
$replace = "<a href=\"{$base}\\1\">";
$replace .= "<img src=\"{$base}\\1\" title=\"\\2\" alt=\"\\2\">";
$replace .= "</a>";
$md = preg_replace($pattern, $replace, $md);
return $md;
}
/** /**
* @param mixed $name * @param mixed $name
* @return bool|<missing> * @return bool|<missing>
*/ */
private function load_post($name): ?array { private function render_post($name): ?array {
$dir = ASSET_ROOT . '/blog'; $dir = ASSET_ROOT . '/blog';
$path = $dir . '/' . $name . '.md'; $path = $dir . '/' . $name . '.md';
if(!file_exists($path)) { if(!file_exists($path)) {
return NULL; return NULL;
} }
$md = $this->markdown->parse($path); $md = $this->markdown->parse($path);
$md['content'] = $this->update_images($md['content']);
return $md; return $md;
} }
/** /**
@ -55,7 +69,7 @@ class Blog_model extends Model {
*/ */
public function get_post($name): ?array { public function get_post($name): ?array {
$data = parent::get_base_data(); $data = parent::get_base_data();
$post = $this->load_post($name); $post = $this->render_post($name);
if (!$post) { if (!$post) {
return NULL; return NULL;
} }
@ -64,16 +78,18 @@ class Blog_model extends Model {
$data['post'] = $post; $data['post'] = $post;
return $data; return $data;
} }
/** /**
* @param mixed $name * @param mixed $name
*/ */
private function load_writeup($name): ?array { private function render_writeup($name): ?array {
$dir = ASSET_ROOT . '/writeup'; $dir = ASSET_ROOT . '/writeup';
$path = $dir . '/' . $name . '.md'; $path = $dir . '/' . $name . '.md';
if(!file_exists($path)) { if(!file_exists($path)) {
return NULL; return NULL;
} }
$md = $this->markdown->parse($path); $md = $this->markdown->parse($path);
$md['content'] = $this->update_images($md['content']);
return $md; return $md;
} }
/** /**
@ -82,7 +98,7 @@ class Blog_model extends Model {
*/ */
public function get_writeup($name): ?array { public function get_writeup($name): ?array {
$data = parent::get_base_data(); $data = parent::get_base_data();
$writeup = $this->load_writeup($name); $writeup = $this->render_writeup($name);
if (!$writeup) { if (!$writeup) {
return NULL; return NULL;
} }

View file

@ -27,3 +27,6 @@
<?php foreach($css as $file) <?php foreach($css as $file)
echo $this->embed_css($file); echo $this->embed_css($file);
?> ?>
<?php foreach($js as $file)
echo $this->link_js($file);
?>

View file

@ -1,5 +1,9 @@
<?php /* Copyright (c) 2024 Freya Murphy */ <?php /* Copyright (c) 2024 Freya Murphy */
$style = array(); $style = array();
$style['home'] = 'css/home.css'; $style['home'] = 'css/home.css';
$style['blog'] = 'css/blog.css'; $style['blog'] = ['css/blog.css', 'css/prism.css'];
$style['error'] = 'css/error.css'; $style['error'] = 'css/error.css';
$style['prism'] = 'css/prism.css';
$js = array();
$js['blog'] = 'js/prism.js';

View file

@ -50,6 +50,17 @@ abstract class Core {
return $url; return $url;
} }
/**
* Loads a js html link
* @param string $path - the path to the js file
*/
public static function link_js(string $path): string
{
$stamp = Core::asset_stamp($path);
$href = Core::get_url("public/{$path}?stamp={$stamp}");
return '<script src="'. $href .'"></script>';
}
/** /**
* Loads a css html link * Loads a css html link
* @param string $path - the path to the css file * @param string $path - the path to the css file

View file

@ -8,8 +8,10 @@ abstract class Model extends Component {
$data['title'] = lang('first_name'); $data['title'] = lang('first_name');
$data['desc'] = lang('default_short_desc'); $data['desc'] = lang('default_short_desc');
$data['css'] = array(); $data['css'] = array();
$data['js'] = array();
$style = $GLOBALS['style']; $style = $GLOBALS['style'];
$js = $GLOBALS['js'];
if (!$app) if (!$app)
$app = CONTEXT['app']; $app = CONTEXT['app'];
@ -18,11 +20,16 @@ abstract class Model extends Component {
$css = $style[$app]; $css = $style[$app];
if (!is_array($css)) if (!is_array($css))
$css = array($css); $css = array($css);
else
$css = $style['app'];
$data['css'] = $css; $data['css'] = $css;
} }
if (isset($js[$app])) {
$js = $js[$app];
if (!is_array($js))
$js = array($js);
$data['js'] = $js;
}
return $data; return $data;
} }