KDE 4.0 Release Counter

Friday, March 20, 2009

A Journey to WebKit via Plasmaland.

While writing a little Plasma utility I was tempted to use the new QT WebKit toolkit to handle the User Interface.

To integrate WebKit in a KDE or QT program is no too diffcult, thanks to metadata that QT adds to C++ classes. It is possible to call directly methods of objects resident in our program from HTML pages via Javascipt taking advantage of slot and signals mechanism.

Firstly, we need to insert references to our application C++ objects in HTML pages, as if thery were native JavaScript variables, using an identifier that will be mapped later to physical objects.

After that we can encode JavaScript functions that take advantage of the methods declared as slots, at certain events, such as pressing a button.

We can then excute embedded objects methods from HTML passing as parameters a HTML level defined entities, such as the values of a form fields.

Each link between WebKit and our application will begin through Javascript functions, so WebKit will commence operations but we can call frame 'evaluateJavascript' to execute a script in the frame context from our host program.

Let's do an example:

Suppose that our goal is to recall the method 'reload' of an instance of a C++ class described in the following way from Javascript :

class DBusApplet : public Plasma::PopupApplet
{
Q_OBJECT
...
public
slots:
void reload(const QString &selection);
private:
...
};

In Javascript our application class instance may be mapped as follows, assuming that it is associated to the variable 'appletInterface':



function execute(selection)
{
appletInterface.reload(selection);
}


Since the conversion of basic types is automatic, what we should do is to 'inject' our C++ objects into WebKit component, but we have to wait until the component alerts us when is the right moment to do it.

After that WebKit has fully laoded a HTML page, assigned by the program directly as string or through a URL, the current frame emits the signal "javaScriptWindowObjectCleared" which must have taken care of in the usual way that QT will make available:


connect(page()->mainFrame(),

SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(populateJavaScriptWindowObject()));

Upon receipt of the signal our 'populateJavaScriptWindowObject' method will be called so we can assign the reference of our objects to WebKit using frame 'addToJavaScriptWindowObject' method, whose arguments are the name of Javascript variable that will contain the reference, and our object address.

page->mainFrame()->addToJavaScriptWindowObject(”appletInterface”, this);


http://doc.trolltech.com/4.4/qtwebkit.html

http://webkit.org/

http://code.google.com/p/dbusapplet/