Improving the editing code in WebKit

March 22nd, 2013 No comments

For a while now Igalia and Bloomberg have been collaborating to advance Web technologies. As part of that, I’ve been lately involved on improving some editing capabilities of WebKit (posts to follow soon).

As you probably know, in HTML5 any element can be editable. The feature was introduced some time ago, but was finally standardized by the WHATWG. It’s as easy as adding the attribute contenteditable=true and voilà, the magic unfolds (check it out!!!).

That’s indeed a very powerful feature that allows you to create fast and full-featured rich text editors on the Web. Thing is that, although the contenteditable is standardized, some of the behaviors are not, and thus, each Web engine must provide the one it considers the most correct.

Let me show an example of the above. Imagine that you have the typical HTML bulleted list but inside an editable content element (like a <div>). It’d look like something like this:

  • one
  • two
  • three
  • four

Nothing unusual so far. Now imagine that you select the item “two” and then drag it to the end of “four”. What would be the expected behavior? There is no clear answer to that, you might think that one possible outcome could be:

  • one
  • three
  • fourtwo

which matches Firefox behavior (and WebKit’s as well before I landed this). Another possible result would be this one:

  • one
  • three
  • four
  • two

Both of them seem pretty sensible, the question is whether you consider that you’re dragging just some text, or a text inside a <li> element. It is not an easy decision, so let’s examine some other cases, for example, what happens if we try with two items instead of just one?. In that case (assuming we select “two” and “three” and drop them after “four”)  the result is the following:

  • one
  • four
  • two
  • three

So despite apparently being both outcomes equally correct, it seems that the behavior is a bit inconsistent depending on the number of items you select. I don’t know how this is implemented in Firefox but I’ll try to explain why WebKit was behaving like that.

WebKit is actually pretty smart when dealing with this kind of operations. When doing a drag and drop of a selection, WebKit builds a markup representation (see this file for further details) of the selected contents. In the first case (one item selected) WebKit detects that the selection starts and ends inside the same node (a text element). That’s why the generated markup does not include any <li> tags, and thus, the content is pasted at the end of the “four” item as text.

In the case of multiple item selection, WebKit traverses the DOM tree looking for a common ancestor of the selected nodes in order to build a proper serialized markup representation of the data that is dragged. As you might have deduced, that operation generates a markup that does include all the nodes it finds until the common ancestor is reached (to preserve the structure and appearance). So instead of having a simple two we’d end up with something similar to <li>two</li><li>three</li> for the multiple selection case.

The actual code is a bit more complex than just “get this markup and insert it into the document” because it has to deal with several corner cases and also needs to perform some cleanups after the move operations. Also the generated markup is much more complex (for the single selected item the markup is normally a <span> element which includes styling data among other stuff) but I simplified it for the sake of simplicity.

So after some work (tracked in bug 111556) I came up with a solution that effectively makes WebCore’s editing code to behave the same way independently of the number of selected list items (note that partial selections inside a list item are not affected by this change).

I’d like to thank Ryosuke Niwa for his insightful reviews and Igalia for giving me the chance to work on exciting stuff around WebKit.

Categories: Hacking, Igalia, WebKit Tags:

http://publicsuffix.org support coming to libsoup

June 20th, 2012 No comments

I have the pleasure to frequently hack on libsoup as part of the great Igalia WebKit team. Many things are happening in libsoup but that’s a topic for some other upcoming post. Today I will talk about a new feature I landed just a few days ago and that will be shipped with the 2.40 release. I’m talking about the support for http://publicsuffix.org.

What’s that? The public suffix list is a community driven initiative from Mozilla whose aim is to provide a trusted list of well known public domain suffixes, like for example: .com, .space.museum or ايران.ir.

Why something like that is useful? Citing the web page, it can be used for:

  • Avoid privacy-damaging “supercookies” being set for high-level domain name suffixes
  • Highlight the most important part of a domain name in the user interface
  • Accurately sort history entries by site

My main motivation when I decided to implement it in libsoup was to fix the “supercookie” issue. Hosts could set cookies for a whole top level domain like .com, something that has important security and privacy considerations. Firefox, Chromium and Opera use it also for this purpose. Epiphany has just joined the group.

Apart from that it could be also used for visual stuff. Wondering how Firefox does something like this?

Domain highlighting

Firefox showing in bold font the URL base domain

The API is quite simple, basically there are 2 calls:

const char *soup_tld_get_base_domain   (const char *hostname,
                                        GError    **error);

gboolean    soup_tld_domain_is_public_suffix (const char *domain);

the first one returns a pointer to the start of the base domain of a URL (like www.igalia.com -> igalia.com  in the picture above) while the second one will tell you if a given domain is a well known public domain or not (libsoup uses it internally to block supercookies).

Categories: Igalia, WebKit Tags: , ,

ReSiStance 0.9.2 released

June 7th, 2011 3 comments

Every now and then I try to devote some spare time to add new features to ReSiStance. For this release there are 3 major changes:

  • Item window new appearance
  • Open links in external browser
  • Labels support

The item window (aka the window that shows the contents of a particular blog post/news/whatever) has been completely reworked. The header (with the title of the post, the name of the author and the date) used to be an static label on the top that was always visible. That was not a good idea taking into account the size constraints we have for this kind of devices. That’s why I decided to embed all that info the the HTML of the feed item. Next/Prev buttons were also removed from the header. They’re now located on the right in landscape mode.

Another long awaited feature by users was the “open links in browser”. Finally I got some time to implement it.

Last but not least, ReSiStance got labels support (thanks to  Chus Picos again for the initial implementation). This means that you can decide whether to start ReSiStance with the “classic” window with all the feeds, or with a new window that shows a list of labels created by the user. Users can add feeds to one ore more labels and that way they could group them by topics, interests, languages…

This screencast shows these three new features in action:

ReSiStance 0.9.2 from Igalia on Vimeo.

PS: as usual you can checkout the code from gitorious.

Categories: Hacking, Maemo Tags:

ReSiStance 0.8 with Google Reader support

January 11th, 2011 29 comments

I delayed a bit ReSiStance development during last months because we had a lot of work in Igalia’s WebKit team. But I managed to find some time during Xmass to advance some work and to review a couple of pending patches. The most important ones were by far, the Google Reader support ones.

It all started with some sensational work done by Chus Picos. She did almost all the research regarding the status of Google Reader API (check here if you’re interested) and cooked a very nice set of initial patches. Thank you very much for the great work o/o.

Using those patches as basis, I fixed some remaining issues detected during the review process and implemented a couple of (IMHO) nice features I wanted on top. Basically with ReSiStance 0.8 you can:

  • One-click import of the feeds from your Google Reader account
  • Auto read/unread status sync with Google Reader as you read
  • Add new subscriptions to Google Reader
  • Remove subscriptions from Google Reader

Note that being a mobile app I tried to minimize network traffic as much as possible, and thus, no synchronization is performed automatically except the read status update as you read.

So this is how the main window looks like right now:

There you could see that the Google Reader patches came with a couple of UI changes. Zooming in the left part of the screenshot

unveils a couple of new UI elements:

  • a brand new cell renderer to showboth  feed title with subtitle and small Google Reader like icon for subscribed feeds (Planet Igalia and Fanhouse NBA blog in this case)
  • feeds without favicon now get a default RSS one (see Planet Webkit)

Now if we take a closer look at the rightmost part of the main window

we could realize that another new cell renderer was also developed to show the amount of unread items (and yes the background color is taken from the theme) inside a rounded corner rectangles.

Apart from the new UI items and the Google Reader support, there are a lot of other changes like connectivity improvements (with libconic integration), better exception handling, sorting fixes, duplicate entries detection…

Summing up, this new release not only adds some changes in the UI but tons of them in the guts of ReSiStance, so give it a try if you like it and tell me any bug you might find. Take into account that you need to setup the extras-devel respository in your N900 to have ReSiStance listed in the Application Manager. For those interested in the code, you can get it from the git repo as usual.

Categories: Hacking, Maemo Tags:

WebKitGtk+ HTTP cache ready!

October 20th, 2010 3 comments

It’s being a while since I joined the Igalia‘s WebKitGtk+ team. Mainly focused on network stuff, I managed to tackle several issues during this time although nothing like what I call “the one“.

Last week, after really a lot of work, we landed the patches that add HTTP cache  support to WebKitGtk+. It all started in libsoup. The idea was to create an HTTP cache inside libsoup using the new-io branch started by Dan during the past WebKitGtk+ hackfest. Having that into libsoup is great as it potentially benefits the whole GNOME platform. So taking Xan’s SoupCache draft as basis, I started to port it to the new architecture while fixing some bugs and implementing missing features here and there.

It turned out that the underlying new-io code was not mature enough to land in libsoup’s master nor even to be vaguely stable yet. So the WebKitGtk+ team considered that the most sensible solution would be to temporarily import all that new code in WebKitGtk+. And that’s preciselly what we did. WebKitGtk+ has now a new API that will allow any client to enjoy HTTP caching.

If you want to know how to use it, you can take a look at the patch I also submitted for epiphany. As you can see it’s pretty simple, just create a SoupCache object and add it to the session like any other SoupSessionFeature.

Note that this new API will be most likely removed as soon as libsoup equivalent is ready, but having it inside WebKitGtk+ in the meantime definitely worths it.

Categories: Hacking, Igalia, WebKit Tags:

ReSiStance 0.5 released

August 19th, 2010 2 comments

I released yesterday ReSiStance 0.5 with some bug fixes and two new really cool features:

  • OMPL Import/Export: moving from other clients to ReSiStance should be easier now, and you can use the export feature also to backup your feed lists.
  • Feed auto-discovery: this is THE killer feature of this release. Currently it uses the syndic8.com services. Just type a couple of words and ReSiStance will give you back a list of feeds that could be interesting for you. Just select the ones you like the most and voilà, ReSiStance will automatically setup them for you.

These two really nice features were developed by a University of A Coruña student called Chus Picos as part of their master thesis. She did a really great job and is currently working on some other great features I will talk about next time. So Chus congrats and thanks for the great work.

PS: did I mention that translators are welcomed?

Categories: Hacking Tags:

ReSiStance with WebKitGtk inside

April 2nd, 2010 6 comments

I have released ReSiStance 0.3 (in case if you wonder what about v0.2, it is just that I didn’t blog about it, but it was released on Monday). I don’t know how it could happen, but I totally overlooked the presence of WebKitGtk python bindings in the Maemo repos by the time I started to code ReSiStance. I decided to move to WebKit as soon as I noticed my mistake, specially knowing all the cool features of WebKit Gtk port from the Igalia mates hacking on it.

These are the more remarkable changes since v0.2.1:

  • HTML rendering is now WebKitGtk’s business. It performs blazingly fast, much more than GTKHtml, you’ll easily notice that.
  • Feeds list can be sorted
  • Added application settings
    • Auto load images
    • Default font size
    • Portrait/Landscape modes

You can see all of them in action in this screecast:

ReSiStance 0.3 from Igalia on Vimeo.

UPDATE: I had to push v0.3.1 to the repositories because v0.3 had missing package dependencies

Categories: Hacking, Igalia, Maemo Tags:

Vive la ReSiStance!

March 22nd, 2010 10 comments

After all the hard work required to release Modest and Tinymail I finally found some energy to start a new pet project. I have never really liked the RSS reader that comes with the Nokia N900 Igalia gave me. I looks too “Diablo” and it’s not consistent at all with Fremantle look&feel.

That’s why I decided to write my own and, at the same time, regain contact with Python. The result is ReSiStance 0.1.

ReSiStance 0.1 from Igalia on Vimeo.

These are the main features of this first release

  • Support for RSS 0.90, Netscape RSS 0.91, Userland RSS
    0.91, RSS 0.92, RSS 0.93, RSS 0.94, RSS 1.0, RSS 2.0, Atom 0.3,
    Atom 1.0, and CDF (kindly provided by feedparser module)
  • Feed and Favicon autodiscovery (no need to type the exact URI to the .xml file)
  • Add/Remove/Update feed sources
  • Landscape/Portrait mode support (I love apps with portrait mode)
  • Internationalization support

ReSiStance sources are already available for downloading from gitorious and the package for the N900 was uploaded to extras-devel repository.

Categories: Hacking, Igalia, Maemo Tags:

Tinymail 1.0 released

March 5th, 2010 14 comments

I’m really proud to announce the release of Tinymail 1.0. New packages are available here.

It has been more than 3 years since the project started, and after all the hard work we think now it is time to release the first version of our beloved framework to build e-mail applications for mobile devices. Thank you very much to all contributors! Specially thanks to Philip, Dape, Dirk-Jan and Rob, you all rock guys!

It is already being mentioned in the official announcement I sent to the tinymail devel list but I would like to highlight the main achievements of this release since the previous 0.0.9 pre-release:

  • New widgets to show the mailboxes tree as a plain list
  • New widget to expose only the latest messages of a mailbox
  • New download external images capability
  • Complete rework of IMAP IDLE
  • Improved namespace handling in IMAP
  • Locking, security and connectivity improvements in POP3 code
  • Improved MIME parsing (PGP/GPG parsing now works)
  • New asynchronous methods for getting folders and messages
  • Upated Vala & Python bindings
  • Improved support for 64-bit architectures

For those of you having a Nokia N900 this release contains more or less the same code shipped within your device (remember that Modest, the email program, is tinymail powered). For all people that followed the progresses in tinymail I blogged about recently (here, here or here) you will have to wait for v1.2 release. I promise you won’t have to wait that much…

Categories: Hacking, Igalia, Maemo, Modest Tags:

The Postman always rings twice

February 19th, 2010 1 comment

Thanks to the hackfest time Igalia gently gives me every week I could resume the work I had previously started to add ENVELOPE support to tinymail.

What’s this stuff about? Well basically what we can do now is ask the server for ENVELOPE instead of fetching a random set of headers (like ‘From:’, ‘Subject:’ …). Why is this cool? For several reasons:

  • Speed: IMAP servers do cache ENVELOPE information so they do not have to inspect every email message to extract the requested headers. They can give you ENVELOPE blazingly fast (I run a rough test and downloading a folder with ~1500 headers from AOL IMAP server lasted twice the time of downloading ENVELOPE and BODYSTRUCT, and this means minutes).
  • Bandwidth: ENVELOPE is smaller in size than headers as the name of the headers is not transmitted over the network
  • Future: RDF storage support in tinymail is now closer

You can find this new feature in trunk.

Categories: Hacking, Igalia, Maemo, Modest Tags:

Bad Behavior has blocked 177 access attempts in the last 7 days.