[Webkit-unassigned] [Bug 16401] [GTK] GObject/C DOM binding

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Feb 10 20:12:45 PST 2009


------- Comment #128 from adam at yorba.org  2009-02-10 20:12 PDT -------
Created an attachment (id=27549)
 --> (https://bugs.webkit.org/attachment.cgi?id=27549&action=view)
DOM patch with lots of fixes, updated to revision 40813

My colleague Jim and I are highly interested in seeing DOM bindings added to
WebKit/GTK.  Over the last couple of weeks, we've extensively cleaned up and
enhanced the last patch posted here (posted by Martin Soto in comment #96 on
11/30) in an effort to resolve all outstanding issues.  Here is a list of the
major changes we've made, followed by a list of potentially open questions.

- We've updated the patch to build with a current WebKit (revision 40813,
corresponding to the latest nightly build).

- In the last patch, each wrapper GObject pointed to a private structure which
in turn pointed to a native C++ WebKit object.  (Comments on this thread show
that there was previously yet one more level of indirection which Martin has
already removed.)  These pointers were duplicated at each level of the
inheritance hierarchy.  For example, a GdomHTMLButtonElement pointed to a
native HTMLButtonElement, but the parent class GdomHTMLElement and all other
parent classes also contained pointers to the native object.  This was
unnecessary and wasteful.

With our changes, each wrapper GObject simply contains an opaque void * which
actually points to the native C++ object.  We've eliminated the duplicate
pointers in the inheritance hierarchy as well as the private structure.
 Comments in this thread indicate that the private structure was created in
case we might need to store extra data there in some future version of the
code.  We doubt that will be necessary, but if we do need a private structure
at some point we can simply update the void * to point to it without breaking
binary compatibility with applications that use DOM objects.

Because we've eliminated the private structure, we can't use a C++ smart
pointer to point to the native C++ object, and so we call ref() manually when a
GObject wrapper is initialized and call deref() when it's finalized.  As some
reviewers pointed out, the existing code called ref() on some smart pointers in
some cases, which was unnecessary; we've eliminated that wherever it happened
in the code.

- The W3C DOM specifies that certain methods may raise exceptions.  In the last
patch, DOM exceptions were not made available in any way to an application
using the GObject wrapper layer.  The usual way to report errors in GObject is
through a parameter of type GError ** at the end of a method's parameter list.
 (In fact, Vala's bindings generator can automatically generate exceptions in
Vala when calling a GObject method that takes a GError **).   With our changes,
whenever a DOM method raises an exception, the corresponding GObject method has
a GError **.  If an exception occurs, the returned GError contains a textual
description of the error as reported by the DOM code.

- In the last patch, each DOM attribute was exposed as a GObject property, but
not via GObject getter/setter methods. In GTK it's actually common to expose
properties in both ways; for example, GTKWidget has both a "name" property and
methods gtk_widget_get_name() and gtk_widget_set_name().  We feel that GObject
properties alone are inadequate for exposing DOM attributes, both because they
are relatively inefficient (they are accessed via a string name provided at
runtime) and also because there's no way to report error information when a
caller gets or sets a property.

With our changes, each DOM attribute is exposed both as a property and via
getter/setter methods.  When the DOM specifies that getting or setting the
attribute may raise an exception, the corresponding getter/setter method takes
a GError ** for error reporting.  We're not particularly attached to using
GObject properties at all, and can remove them if you like; that would
significantly reduce code size (especially in the generated code).  It's up to

- The last patch contained some support for reporting DOM events to the GObject
caller.  The event interface was different from that specified by the DOM and
the implementation was incomplete (there was no way to unregister an event
listener).  In our patch we've removed all the event code, simply because
events raise various design issues and we'd prefer to deal with them in a
subsequent iteration.  As various commenters have mentioned, the patch is large
enough as it is and removing the event code seemed like a good way to reduce
its size.

- We've eliminated IDL changes which caused the GObject binding to behave like
JavaScript in some special cases.  All GObject calls now behave like the static
Objective-C binding.

- gdom.h previously included a large hard-coded list of files; we now
autogenerate this.  The makefiles also included large hard-coded lists of
GObject wrapper sources; these are now generated dynamically (just like the
lists of JObject wrapper sources to be built).

- By removing events, autogenerating file lists and performing miscellaneous
code cleanup we've reduced the size of the patch from over 5500 lines to under
3500 lines.

- We've eliminated the separate defines FEATURE_DEFINES_GDOM and

- With the last patch, header files were installed in two places: in
include/webkit-1.0/gdom and in include/webkit-1.0/webkit.  We now install them
only in include/webkit-1.0/gdom.

- Where possible, we've renamed source and header files to have all-lowercase
names as is conventional in GTK.  The autogenerated wrapper files still have
CamelCase names because we use implicit makefile rules to generate these from
.idl files, which also have CamelCase names, and GNU make doesn't allow us to
perform a lowercasing transformation inside the implicit the rule.  So the
autogenerated filenames don't quite fit the GTK convention; we don't think this
is a significant problem.

- The last patch included a function named GStringConvert; this name didn't fit
the coding conventions.  We've renamed it to gdom_gstring_convert().

- There were some lines of the form #include "gdom/xxx.h".  We've changed these
to look like #include "xxx.h"; the makefiles now include the gdom directory in
the include path if necessary.

- Some #includes used angle brackets unnecessarily as pointed out by Alp in
comment 28; we've fixed this.

- The Apple copyright lacked the text "All rights reserved" in some source
files; we've fixed this.

- The Perl generator script contained lots of tabs; we've replaced them with

== open questions ==

Here are design decisions that potentially remain open along with their current
status.  We're happy to change any of these in the code to satisfy the
consensus of the WebKit team.

1. How should GObject DOM classes be named?  To represent the DOM interface
called Element, we could use any of the following:  GdomElement (the current
choice); GDOMElement; WebKitElement; WebKitDOMElement.

We don't have a strong opinion here.  It's slightly unusual for a single GTK
package to contain classes with two different prefixes, and so if we use the
Gdom or GDOM prefix we'll need to play some tricks in order to autogenerate
Vala bindings for the webkit-1.0 package, which will contain some classes
prefixed with WebKit (e.g. WebKitWebFrame) and others prefixed with Gdom/GDOM.
 (We've actually done this, and can share our Vala bindings generator script if
you like.)

If we use names such as WebKitElement or WebKitDOMElement then Vala bindings
should be automatic.  If we use WebKitElement without the word DOM, then API
documentation which shows a sorted list of classes will show DOM classes
interspersed with other WebKit classes; this might be confusing.  On the other
hand, the WebKitDOM prefix will lead to long names such as

If we use either the Gdom, GDOM or WebKitDOM prefix we might want to remove
duplicate occurrences of the word DOM; for example, we could replace
GdomDOMObject with GdomObject.  We have not done this at this point.

2. Should a DOM attribute be exposed both via getter/setter methods and via a
property, or only via getter/setter methods?  As mentioned above, we currently
have both getters/setters and properties but are willing to take the property
code away if desired.

3. How does a string returned by a DOM function get freed?  Currently the
caller is responsible for freeing.  In comment 28 Alp suggested other possible
mechanisms such as some sort of garbage collection.  We believe that the
existing caller-frees policy is the way to go; it is the usual mechanism in
GObject classes and will play well with higher-level language bindings.


We're looking forward to having these bindings in WebKit!  Please let me know
if there's anything more we can do to help out.

Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

More information about the webkit-unassigned mailing list