Sunday, 22 June 2008

Web Browser

It's been a bit of a gap since my last post, I managed to get sidetracked to doing some work on a website I setup last year .. which involved lots of php, mysql and javascript. So now I'm back ready for some 'proper' coding I needed to do a refresher on c++, so I've decided to have a quick go at a second version of a web browser I wrote a couple of years ago.

The 'skanky sea dog' web browser is just a bit of fun really .. I'm just doing it as a little learning project so I can learn the details of how html / web servers work. The first version was very simple, it downloaded the html for a page, and did some incredibly basic processing of the html to show some text on the screen, and download some of the images (more a proof of concept).

This time, after learning a bit of css and javascript, I have a bit better understanding of how the html DOM (document object model) works, and as it is a tree structure, and I have a fair bit of experience at dealing with tree structures (they seem to crop up everywhere in coding), I thought i'd give it a go at parsing the html into a tree of c++ objects, with different types for different html tags.

The parsing was actually not all that tricky, I had earlier written an xml parser, so I modified it to get some useful functions for html parsing, then allowed the tree to 'build itself' by parsing the html - i.e. it encounters an [html] tag, it creates an html node, and begins parsing for child objects within this node. When it finally encounters the [/html] tag, it is finished with the node, and moves up the the higher node on the tree (in this case the document node), until all the document has been processed.

For rendering, I knew that I had to somehow implement a version of the html 'box model', i.e. child elements determining the size of parent elements, or parents constraining the size of child elements etc. I have no idea how firefox and IE handle this, but I have done it using the old trick of traversing the tree.

I do several passes, down the tree to the leaf nodes, then up again to the root, doing different operations on each pass, gradually refining the box models for each element (things like widths, heights, minimum width, desired width, offsets etc).

This seems to be working, and now I'm doing some refinements for tables to allow the columns and rows to line up.



For rendering, I wanted ideally to make things cross platform, but as I'm only familiar with windows, I've tried to separate things a bit for the rendering code. Each html element has it's own win32 window. Whether that's a good or bad idea I don't know yet .. I basically had the choice to draw everything manually, or rely on the win32 techniques. While I like doing everything manually, win32 normally makes it an enormous pain the ass to do anything manually, so I'll go with the flow for now and see what happens.

Incidently finding the sizes of image elements is easy .. text elements is more tricky. I used things like getting the text metrics and finding the pixels used by each word in turn to determine the minimum widths and desired widths for text elements. In fact in some elements (e.g. [div] or [body]) you can have text elements intermingled with images etc so it is slightly more complex determining widths etc but it is very doable.

I get the feeling that while the overall structure of the browser code is quite well laid out, the intricasies could quickly become a bit of a rats nest because I think there will be so many 'special cases'. This may be part of the explanation for the differences in behaviour between Internet Explorer and Firefox, however I think there is probably some fundamental difference in their box model calculation method which leads to their 'quirks'.

No comments: