Build a WebKit browser
Learn how to get WebKit built and running on a Linux system to develop browsers
For a while a few years back, it seemed like every single new browser was being made in WebKit. While Apple’s Safari browser had been using it for years, Google’s Chrome and the Chromium project seemed to launch it into the spotlight and result in desktop and mobile browsers built on the technology.
While the standard source is optimised for development on OS X and Windows, there is a branch of it specifically for Linux: QtWebKit. With this source you can continue to develop the engine for use on Linux or you can build your own browser using WebKit as a lightweight rendering engine.
In this tutorial, we will show you how to get WebKit set up on your system, along with some pointers on how to construct a browser using the source so that you can then go ahead and begin creating a custom project.
1. Grab the source code
We need to first get the source code for QtWebKit, which is part of the normal WebKit source tree. Open up a terminal and cd to the place where you like to keep your sources, or create a new directory for it with mkdir. Sync the source locally in the terminal with:
$ git clone git://gitorious.org/webkit/webkit.git
The source will take up just over 4 GB of space, so make sure you have space and perhaps something to do while you wait.
2. Get the staging branch
This step is optional, but you could also look at tracking the staging branch specifically for the Qt port. To do this you need to first cd into the WebKit directory that was just created. From there, you can fire off the following commands:
$ git remote add Qtwebkit git://gitorious.org/
$ git fetch Qtwebkit
However, the current release of the Qt port files is in the normal WebKit source that we downloaded.
3. Get the Qt 5 source
We need to build Qt 5 properly so that our WebKit can run and be developed in the correct way. We first need to download the files to install Qt 5, which can be found here: www.qt.io/download-open-source. You can also download the installer file in the terminal using something like:
$ wget http://download.Qt.io/official_releases/
Remember to take into account the latest version of Qt 5 before you download.
4. Install Qt 5
Once it’s downloaded, we can get ready to install it. First of all, elevate the file so you can execute it using:
$ chmod +x Qt-opensource-linux-x86-5.4.1.run
Remember to change the version on this line to be the one you downloaded. When you have done that, you can install it using the following:
This will bring up a graphical installer – follow the instructions to install Qt 5.
5. Setup OpenGL
If you haven’t already installed the OpenGL libraries, you should do so now. They can be installed using:
$ sudo apt-get install mesa-common-dev
If you’re using a more recent version of Ubuntu, you may encounter some problems properly working with Qt code, so it can be prudent to install the following package as well:
$ sudo apt-get install libglu1-mesa-dev -y
If you start having problems with GL as part of this tutorial, installing this package may fix it.
6. Set the Qt paths
Before we can continue building WebKit, we need to set the correct paths for the Qt development software. We first need to set QTDIR to the location of the Qt installation. Do this by exporting the path with:
$ export QTDIR=[Install directory]
Then make sure that the Qt 5 qmake is the first in the PATH. Use the following to do this:
$ export PATH=$QTDIR/bin:$PATH
7. Get any extra dependencies
Depending on your development environment, we may need to add extra dependencies to make sure everything will run and compile correctly. Ensure that the following packages are installed just to be certain that the compiling goes smoothly.
$ sudo apt-get install bison gperf flex
libsqlite0-dev libicu-dev libxslt-dev ruby
There may be other packages you need and you can install them as you go, but these seemed to be the common absent packages in our tests.
8. Start to build WebKit
Finally, we can begin to actually build the QtWebKit source. Go to the directory that you’ve downloaded the WebKit source to and build it using:
$ webkit/Tools/Scripts/build-webkit -Qt
This will take a while, depending on your system. If there are any other errors or missing dependencies, it will stop and you may have to hunt down the libraries that it needs.
9. Launch a test of WebKit
Once everything is compiled (and it will take a while depending on your system), you can run this very basic version of WebKit using the following:
$ Tools/Scripts/run-launcher -Qt
This is the QtTestBrowser, which is a very quick implementation of WebKit as a browser. You can look through the files to get an idea of how it uses WebKit.
10. WebKit use explained
There are some basic principles to the way WebKit handles data to render. This is handled via the WebCore engine and is made up of specific systems: the Document Object Model (DOM) tree, the render tree and the style tree. These three parts help to render each webpage efficiently and therefore we will break them down and discuss them in more detail over the next few steps.
11. How the DOM tree works
Each webpage is parsed into this DOM tree of nodes, all referred to be the base class of Node.h. Of these nodes, there are three that are relevant for actually rendering data: Document.h/HTMLDocument.h, which is the root of the tree; all of the tags from the HTML or XML are kept in Elements.h, and can be queried whenever you need them; finally, Text.h contains all the raw text that goes between the elements – in other words, the content on the page that
is actually readable.
12. Structure of the render tree
The rendering nodes of the render tree mostly correspond to the nodes in the DOM tree, albeit with a few extra objects and nodes that don’t exist in DOM. These are kept in RenderObject.h. The RenderObject for a DOM node can be obtained using:
RenderObject* renderer() const
… which can be more usefully used as:
RenderObject* firstChild() const;
RenderObject* lastChild() const;
RenderObject* previousSibling() const;
RenderObject* nextSibling() const;
13. Create the render tree
Renderers are created when a DOM node is attached to a renderer. The information in the node will determine what kind of renderer to use, including not creating it if certain conditions are met. It’s a top-down recursive operation – all descendants have renderer nodes created after their parents. You can call the attach method with:
… on the DOM nodes to begin the rendering process and get it fully underway.
14. Destroy the render tree
This is related to creating render trees by calling the opposite command, which detaches the DOM nodes from the renderer with the following:
This destroys the render tree and is supposed to occur when a tab or window is closed down, as it ends the need to see the information that was present in the DOM tree. This is a good step to help complete the process.
15. Use style information
While attaching DOM information to a renderer, the element is queried for CSS/style information and the resultant data is kept in RenderStyle.h for when the webpage requires this rendering. All supported style properties can be queried via RenderStyle.h which then connects it to an attached renderer with:
This style can be changed on the renderer, but otherwise it will stay the same until destroyed. Styles can be accessed using:
RenderStyle* style() const
16. Work with RenderBox
This is the subclass that handles any objects that use the CSS box model. This includes objects with borders, padding, margins, width and height (a couple of non-box model will subclass from RenderBox right now, but that will be fixed in the future). The diagram for this step illustrates the parts and structure of the CSS box model.
17. Read relevant widths
If you want to see the information from the object, you can call the raw data with:
int marginTop() const;
int marginBottom() const;
int marginLeft() const;
int marginRight() const;
int paddingTop() const;
int paddingBottom() const;
int paddingLeft() const;
int paddingRight() const;
int borderTop() const;
int borderBottom() const;
int borderLeft() const;
int borderRight() const;
The rest of the style information is stored similar to this.
18. Create your custom browser
With enough time and effort, your can use WebKit as an engine for your own very powerful, very sleek browser. It won’t have the sync abilities of Chrome unless you own a ridiculously far-reaching online infrastructure, but you can easily make it so that settings of files can be synced between systems using cloud storage.
There is a lot more to learn with WebKit, but we have presented you with just the basic steps to understanding how it works. No go forth and explore some more!