Grids everywhere!

September 23rd, 2014 No comments

Hi dear readers,

it’s awesome to see people-really-excited (including our friends at Bloomberg) about CSS Grid Layout, specially after Rachel Andrew‘s talk in CSSConf. I really believe CSS Grid Layout will be a revolution for web designers as it will help them to build amazing responsive web sites without having to add hacks all around.

Me and my fellow Igalians keep working on adjusting the code to match the specification, polishing the code, adding new features and even drastically improving the performance of grid.

Adventures in the Grid

March 31st, 2014 No comments

Hi there, fellow readers. Today I’m starting a mini-series of posts to talk a little bit about the work I’ve been lately doing at Igalia around WebKit and Blink web engines. I’ve been involved in the implementation of a new standard called CSS Grid Layout in both engines. My mate rego has already talked about that, so take a look at his post if you need to know more about the basics. Read it? Great, let’s move on.

The new grid layout

I’d like to stress that grid layout is not (only) about aligning elements in columns and rows (after all you can already do it with tables or complicated layouts using positioned and/or floating blocks right?). What’s interesting is that a grid layout doesn’t have content structure. What does it mean? As the specs say:

unlike tables, grid layout doesn’t have content structure, and thus enables a wide variety of layouts not possible with tables. For example, the children of a grid container can position themselves such that they overlap and layer similar to positioned elements.

In addition, it provides a very fine grained control of the layout of the elements of the grid (generally with the help of media queries) based on device form factors, orientation, available space, etc…

Today, I’m going to focus specifically on how to position elements inside a grid, and in particular how to do that using named grid lines and named grid areas. Going too fast? No problem, let’s recap a bit.

Positioning grid items

In CSS grid layout a grid is defined by a set of intersecting horizontal and vertical lines which divide the space of the grid in areas where to place grid items. Those grid lines are numbered starting from number 1. Based on a declaration like:

	grid-template-rows: 50px 1fr 50px;
	grid-template-columns: 150px 1fr;

we would get the following

Grid lines defining a grid with 3 rows and 2 columns

So in order to position an item in a grid, you have the a very straightforward way of doing it which consist of specifying the the grid line’s start and end positions for either columns, rows or both. Given the above grid, and supposing that you want to place some item in the rightmost area on the bottom, you’d just need to specify it the following way:

	grid-row: 3 / 4;
	grid-column: 2 / 3;

Easy huh? Your item will span from column lines 2 to 3 and from row lines 3 to 4. There are tons of different ways to specify the position and the span for your grid items, so many that perhaps they deserve a separate blog post (just check this section of the specs if you need the details now).

Placing items using named grid lines

Despite being easy and even intuitive (at least for us developers), this way of placing grid items using grid line numbers might not be optimal for web authors. With large grids, knowing the exact grid line our item should span to could become an increasingly difficult task. So, why not give the grid lines a meaningful name? What about giving authors the possibility to assign a name (or multiple) to each grid line so they wouldn’t have to remember/compute the exact index of each grid line?

Naming grid lines is pretty easy. Authors just need to specify the names they want to assign to each line (yeah “names” in plural) in the grid definition by putting them into parentheses surrounding the definitions of the grid track breadths. Something like:

	grid-template-rows: (first start) 100px 40px (middle) 1fr 250px (last)

Based on this definition, the following declarations are totally equivalent:

	grid-row: first / middle;
	grid-row: 1 / middle;
	grid-row: first / 3;
	grid-row: 1 / 3;
	grid-row: start / middle;
	grid-row: start / 3;

I wouldn’t enter into discussing which one is the most descriptive or the best (there are some more), just choose the one you prefer.

Placing items using named areas

Although things like named grid lines ease the design task, authors don’t normally foresee the layout of a web page using a matrix of positions but instead they normally divide the available space in “areas” in their minds, we’re talking about areas like the footer, the side bar, the header, etc… So why don’t take advantage of that and allow the web authors to specify those grid areas?

For example, let’s imagine that we’re designing a website with a header on top, a footer in the bottom, a sidebar with links for example on your left and the important content on your right. We can easily (and very visually I’d say) define these four grid areas using the CSS Grid Layout properties. It’d be something like this:

	grid-template-areas: "  .     header  header"
	                     "sidebar content content"
	                     "sidebar content content"
	                     "  .     footer  footer";

There you go, a 4×3 matrix with 4 different named grid areas. Some remarks:

  • The dot “.” means unnamed area
  • “header” will occupy columns 2 and 3 in the first row
  • “footer” will occupy columns 2 and 3 in the last row
  • “sidebar” will span from 2nd to 3rd row in the first column
  • “content” will fill columns 2 to 3 in rows 2 to 3

That’s all. Based on that definition, we could use the grid-area property to place our elements. We just need to specify the grid area where to place them and the grid will automatically position them based on their size and available free space.

Placing items using grid area’s implicit grid line names

Hmm, not enough for you? You said you still need something extra? So you want the simplicity of grid areas and the flexibility of named grid lines? No problem, the spec defines what’s called the implicit named grid lines generated by each defined grid area. What does it mean? Basically that for any grid area you define, let’s call it “A“, the engine will automatically generate “A-start” and “A-end” grid line names for columns and rows, so you could use them to position any grid item as if they were explicitly defined by you.

If I take the grid defined above with grid-template-areas it’s perfectly valid to position a grid item using the following declarations

	grid-column: header-start / 3;
	grid-row: 2 / sidebar-end;

which are equivalent to

	grid-column: 2 / 3;
	grid-row: 2 / 4;

As you might have wondered, you can mix all these three methods to position grid items together.

How is it implemented?

What I have described should be working fine in latest WebKit nightlies after I landed this. Regarding Blink, there are some missing bits already addressed here that will likely land soon. Obviously this is not a matter of a single change :), we’re building all this on top of many other changes in WebKit and also in Blink.

In my next post I’ll talk about the implementation details and also about the differences between WebKit and Blink as we have followed slightly different paths to implement this. Stay tuned!

Acknowledgements

Many thanks for the nice reviews I got from both WebKit reviewers and Blink owners. Also I’d explicitly like to thank the awesome guys at Bloomberg for sponsoring this work.

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 30 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 2 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: