Blog Archives

Blog entries related to the Mozilla project

Future of editing on the web

Last week, I met with Aryeh Gregor (the editor of the HTML Editing APIs specification, among other specs), Ryosuke Niwa and Annie Sullivan (both of WebKit editing fame) and Jonas Sicking (prolific Gecko hacker) to discuss the future of HTML editing APIs on the web, and also exchange ideas on how Gecko and WebKit handle editing.  The meetings were extremely productive, and we managed to discuss a lot of stuff.  I’m trying to provide a summary of everything we discussed.  You can see the meeting agenda and minutes for more information.

HTML Editing Specification

We all agreed that Aryeh has been doing a great job in specifying how web browsers should behave in response to editing APIs.  The current situation is less than ideal.  Currently, every browser engine behaves differently when those APIs are invoked, and because of the complexity of handling editing commands, in a lot of situations, no browser engine gets it right.  Aryeh has been doing black-box testing on how browser engines behave, and he’s been designing generic algorithms which behave sanely.  Gecko and WebKit are planning to gradually move towards implementing the newly specified behavior for these APIs.  This can be tricky in some cases where modifying the engine’s behvior would break web compatibility, but we are planning to try to handle the safer cases first and watch closely for web content which make the wrong assumption about how things are supposed to behave.

The spec itself is not finished yet, but it’s generally in a good shape.  We discussed some future improvements to the spec, and we’ll reiterate on the spec to improve it even more as we move ahead.

Mutation Events Replacement, and New Editing Events

Mutation events in their current form behave very badly.  They are usually a reason for bad performance, and they are extremely painful to handle correctly, so they are always responsible for a lot of the stability problems that we face in Gecko (and I’m sure other browser engines have been experiencing the same types of problems).  Jonas has proposed a replacement for these events.  There has been lots of feedback on the proposal, and it’s not yet in a final form, but the discussions seem to be proceeding quite well.

Traditionally one of the reasons that people have needed mutation events have been modifying how browsers handle editing commands.  We discussed a possible better alternative for this use case.  We could provide two new events, the beforeeditaction and aftereditaction events (note that I’m just using these names as placeholders for better names that we will hopefully think of in the future!).  The beforeeditaction event would fire before the browser initiates handling of an editing command.  It would be cancelable, so that web applications which do not want certain commands enabled can just cancel the respective events.  The aftereditaction event would fire when the browser is done performing the editing action.  This event will provide semantic information about the editing operation performed, and will allow web content to alter the DOM generated as a result of the editing action.  Think of a web application which wants to use strong tags instead of b tags for bold text generated by the bold command.  With aftereditaction, the web application can just fix up the DOM after the browser has modified it to use strong tags.

This idea can even be taken one step further.  The browser can fire beforeeditaction and aftereditaction events even for commands which it does not support natively.  Handling these events will give web applications a new way of providing custom editing commands!  The more we talked about these two events, the more we thought that they are going to be useful!

UndoManager Specification

Ryosuke has been working on the UndoManager specification.  It is a new interface which allows web applications to hook into browser’s native undo/redo transaction manager.  It is an awesome way to enable web applications to put custom transactions into the browser’s undo/redo stack, and also enable undo/redo for a host of new applications on the web (think of having undo/redo working for a drawing tool built on top of the HTML5 canvas, for example!).  We discussed some of the details of the spec, and managed to agree on everything that we discussed.

The good news here is that this is something which is going to come to a browser engine near you really soon!  William Chen, an awesome intern at Mozilla is working on implementing it for Gecko, and Ryosuke told me that he’s planning to implement it for WebKit too once he finishes some of the refactoring that needs to be done before this can happen.

Selection APIs

We talked about the Selection specification, which is currently part of the DOM Range specification.  We agreed that we need a way for web developers to create new selection objects, with the hope that some day we would allow editing commands to operate on parts of the web page that are not visually selected by the user.  The selection story is really complicated for Gecko, because we allow multi-range selections, but we fail to handle them correctly everywhere, especially in the case of editable content.  I have some plans to address this problem, but those plans probably deserve their own blog/mailing-list post.

Collaborative Editing

Collaborative editing seems to be one of the topics which is currently hot among web developers.  Think of web applications like Etherpad which allow several users to edit the same document at the same time.  Annie gave us an overview of some of the challenges in developing collaborative editing applications.  We then discussed some of the ideas which might make the lives of people developing such applications easier.  These ideas included the beforeeditaction and aftereditaction events, an event to fire when the selection changes in a document, and adding a helper method to change the tag for an element in the DOM (which is now being discussed here).

Clipboard APIs

We discussed possible ways to provide clipboard access to web applications.  Opera has proposed a Clipboard API specification, which seems like a good starting point.  We talked about some of the security implications of allowing web pages to put data on the clipboard (which might be an annoyance, or worse, if the web page puts code to run a malicious command on the terminal hoping that the user would paste it in the terminal), and read data from the clipboard (the possibility of reading important data related to the user from the clipboard).  WebKit currently fires the clipboard events for user initiated copy/paste operations, providing access to the clipboard contents to the web application.  We would want to support this in Gecko too.  But the general problem of how to handle the security implications is mostly a UX issue, and we decided to ask our UX teams for feedback on this.

We also discussed how we could prevent potentially bad content from being pasted into an editable area.  One notable example is absolutely positioned elements.  There is no good way for us to determine what styles would apply to an element before the actual pasted document fragment gets injected into the target page’s DOM.  We concluded that allowing authors to handle this case in their aftereditaction handlers might be the best approach here.

Implementation Issues

We also spent some time describing the Gecko and WebKit implementation of contentEditable, and tried to get familiar with some of the upsides and downsides of each implementation.  One of the interesting things that was discussed here was the possibility of borrowing tests from each other.  It seems like WebKit should at least be able to borrow a subset of the crashtests and reftests from Gecko.  Borrowing WebKit tests for Gecko might be a bit trickier, since WebKit’s LayoutTests depend on WebKit’s internals.  But we all agreed that it would be a very good idea for us to adopt cross-browser unit tests.

Future Ideas

We also took some time to go over some future ideas.

IME APIs for the web

There is a proposal to enable web pages to implement IME in Javascript.  This seems to be an interesting proposal, and we decided to put the Gecko and WebKit IME experts in touch with each other to make some progress on this.

Keyboard events interoperability

Currently, there are some interoperability problems with keyboard events.  One such category of problems align with the differences between the modifier keys on Mac and Windows/Linux platforms.  Another source is some browsers not sending the correct keyCode and charCode in the keyboard events for some keyboard layouts.  Determining what needs to be done in all of these cases is tricky, but this was not the area of expertise of any of us.

Keyboard shortcuts

We might be able to leverage the accessKeyLabel property to inform the web pages about the default keyboard accelerator modifier key on the platform on which the browser runs (but there are some privacy concerns with exposing this information).  We agreed that we need a platform independent way to defining shortcut keys, in order to not require authors to handle low level keyboard events to implement keyboard shortcuts.  We might be able to use the accesskey attribute on command elements for this purpose.  We also would need a way to assign a command element to a certain contentEditable element.  We might be able to use the for attribute on the command elements to point to the ID of a contentEditable element.  Also, we thought that we should handle the well-known keyboard shortcuts for operations such as undo, redo, select all, bold, italicize, underline, cut, copy and paste automatically.

Spell checking APIs

There has been a proposal to enable web applications to provide their own spell checking facilities in Javascript.  Both Gecko and WebKit are interested in implementing this API in the future.

Exposing editing algorithms to web content

It might be a good idea for us to expose some of the base editing algorithms to web application authors so that they can use them in their own applications.  We all agreed that we should probably wait for the editing spec to stabilize a bit before we go ahead and consider exposing some of the base algorithms.  We also need feedback from web developers on what kinds of algorithms they would find useful to have access to.

Accessibility concerns

Currently, browser engines do not behave in a consistent way when navigating through editable regions using the keyboard.  We need to specify how browsers should move the caret when the user initiates moving commands using the keyboard.  While some of this behavior might be platform dependent, we would really prefer the keyboard navigation to work similarly across different platforms, if possible.

Resizing and table editing UI

One of the things that people really want is resizing and table editing UI.  Gecko tries to provide this UI, but the existing UI is buggy and may not be the ideal one.  WebKit currently doesn’t provide any UI for this, at all.  For resizing, we’re currently thinking of using the CSS resize property.  Table editing UI is not going to be that easy though, and we agreed that we should discuss that in the future.

Overall, I’m really excited about the direction we’re heading towards in the world of editing on the web.  There seems to be a lot of interest in both Gecko and WebKit to try to improve the current situation, and I do hope that in the future we would be able to have this discussion with other browser vendors too.

Posted in Blog Tagged with: ,

Resisting saying yes

We’ve been too used to say yes.  I’d like to remind everyone about this, and ask them to reconsider this old habit of ours.

Recently, what happened with bug 656120 made me feel warm and fuzzy inside.  This bug potentially solves the Javascript memory usage problems introduced in Firefox 4.  The feedback from the users on the Nightly branch was positive after landing this patch on trunk, so it was suggested for this patch to be backported to the Aurora branch.

mentioned that this is a bad idea, but we decided to let the drivers make the call, and I think they made the right call on this: this patch should wait for Firefox 7, and should not be backported to Aurora (which would mean that it would make it into Firefox 6).

I’d like to take a moment and bring our channel rules into attention.  According to these rules, the code changes that we should accept on Aurora include features backouts or disabling, security fixes, or fixes necessary to get the product into shipping state.  Although I too would really like our users to get this fix as soon as possible, but rushing things like this in the last minute is one of the reasons why we used to slip our schedules in the previous release model.  We were too lenient.  We used to say yes to a lot of things.  I could understand why.  In the old release model, if a fix slipped a release, nobody could tell when it would ship in the next version of Firefox.  That has changed now.  Look at things this way: rushing something on a branch where it doesn’t belong could potentially cause all of the other fixes on that branch to reach our users with a delay.  Let’s be more patient, and let’s say no more often.  As a wise man once said, "it’s good to know that there’s going to be another train in 6 weeks".

Posted in Blog Tagged with: ,

Building Firefox with Address Sanitizer

Address Sanitizer is a new project based on clang which aims to provide relatively cheap memory access checking.  It is capable of detecting errors such as out-of-bounds access or use-after-free at runtime.  Although its functionality is a subset of what Valgrind supports, running applications built with Address Sanitizer is noticeably faster than running them under Valgrind, which can simplify the testing process.

I recently got a build of Firefox with Address Sanitizer working.  Getting these builds in relatively simple.  Firstly, you should build Address Sanizer yourself.  Then, you can use a mozconfig like this:

export CC=/path/to/address-sanitizer/asan_clang_Linux/bin/clang
export CXX=/path/to/address-sanitizer/asan_clang_Linux/bin/clang++

export CFLAGS='-fasan -Dxmalloc=myxmalloc'
export CXXFLAGS='-fasan -Dxmalloc=myxmalloc'
export LDFLAGS=-ldl

. $topsrcdir/browser/config/mozconfig
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/objdir-ff-asan
mk_add_options MOZ_MAKE_FLAGS="-j4"
ac_add_options --enable-application=browser
ac_add_options --enable-debug
ac_add_options --disable-optimize
ac_add_options --disable-jemalloc
ac_add_options --disable-crashreporter

Once your mozconfig is set up, just build and run Firefox as you normally would.  I have not yet found any memory safety issues in Firefox using Address Sanitizer, but it’s not really surprising, since I mostly attempted to run our unit tests with this build, but the build is fast enough that you can even use it as your main browser.  If you do see an issue, please file a bug.

Posted in Blog Tagged with: , ,

Automated landing on mozilla-central

My previous post about assisted landing of patches on mozilla-central was very well received.  Apparently, all you have to do to get something awesome like that working is to blog about it.  I chatted at the office with Chris AtLee about the idea and talked to him about what needs to be done, and who needs to own it, and shortly after, Lukas Blakk informed me that she has an intern for this job, and invited me to a meeting about the project.  All this happened without me lifting a finger, which is amazing!

The result of that meeting is a wiki page on the topic, which is a combination of minutes of the meeting and the goals and steps for the project.  Feel free to review it and let us know if we’re missing something very big!

Marc Jessome is the real force behind this project, so please send all of the thank-you notes his way!  :-)  And don’t forget to answer the try server usage survey which Lukas designed in order to gather much-needed feedback about this project.

Last, but not least, it’s time to get more serious about the good fight against intermittent oranges, because that would be a prerequisite of actually starting to use these facilities.  I’ll keep writing more about that in the near future, so stay tuned.

Posted in Blog Tagged with: ,

Assisted landing of patches on mozilla-central

Imagine this for a second.  You work on fixing something, get the required reviews, and run your patch on the try server.  Everything looks good.  Then you set a flag or something on the bug, and go home, and enjoy your evening.  The next morning, you’re reading your bugmail while enjoying your coffee, and you see a message from landingbot@mozilla.org saying that the patch has successfully landed on mozilla-central, you smile, and wonder how people used to spend 4 hours watching the tree (and possibly getting yelled at by me or philor in the meantime) when they wanted to land something on mozilla-central.  This, my friend, is what we need to move towards, I think.

Now, I’m not entirely delusional here.  We have a very large number of tests testing all aspects of our code, including correctness and performance.  We usually use these tests to judge the quality of a patch.  The results of these tests can be used by machines to make a judgement about the quality of a patch.  So, we can put these tests to use for automating this process.  Here is roughly what I have in mind:

  1. We would have a bot which constantly watches Bugzilla for automated landing requests.  Once such a request is found, it gets added to a queue.
  2. For landing each change, the bot looks at the head of the queue, imports the patch (or hg bundle, in case of bugs with multiple patches) into a clone of mozilla-central.  If the import process is not successful (because the patch has been bit-rotten for example), the bot aborts and reports the problem on the bug.  Otherwise, the bot pushes the changes to the try server.
  3. The bot would watch the try server for results of the push.  If the push has more than one orange job, the bot aborts the landing process and reports the problem on the bug.  If the push has only one orange job, the bot retriggers that job, and reports the possibility of coming across an intermittent orange on the bug, and goes back to watching the try server push.  If the push is all green, the bot takes the change, transplants it on a fresh clone of mozilla-central (and aborts if the patch has been bit-rotten since step 1) and pushes it to mozilla-central.
  4. The bot would watch the mozilla-central push.  For any orange job, the bot retriggers it.  If the second run of the job goes green, the bot reports the orange as intermittent on the bug.  Otherwise, the bot backs out the change.  When the push gets one green run for every job, the bot reports success on the bug, and markes the bug as RESOLVED FIXED.

"Yeah, right!", you would say, "Like there’s ever a push which doesn’t see any intermittent orange!".  But if you’ve been watching the tree closely during the past week or so, you would have noticed that there are a lot of jobs which do not see any intermittent oranges (I’m not talking about oranges, or worse, reds, caused by people landing untested stuff, those will be reliably caught by our good robot).  These pushes are still not the majority of pushes, but we’re getting there.  Slowly, but surely.  Take a look at this image, which can be found here.

Orange Factor going down

The situation is not improving on its own.  It’s improving because of all of the wonderful developers who are working on fixing intermittent orange bugs in the area of their expertise (and some brilliant people who even go one step further and fix oranges in the areas of code unfamiliar to them)!  You can help too.  But more on that in a future post.

Once we reach an average of 1 intermittent orange per push, we could make such a plan work for real.  I don’t know about you, but this makes me really excited.  I think we all have better stuff to do than watching the tree for hours after we land something.

Posted in Blog Tagged with: ,

Avoiding intermittent oranges

Writing tests which are resilient against intermittent failures is hard.  In the process of trying to fix a large number of intermittent orange bugs, I’ve found out that a large portion of them are just caused by mistakes in writing tests, and almost all of those mistakes fall into commonly reoccurring patterns.  It’s hard to avoid those mistakes, unless you know how they lead to intermittent oranges, and how to avoid them.

In order to share my experience about what type of patterns could cause a test to fail intermittently, I’ve gathered a list of common intermittent failure patterns on MDN, and I urge everybody who writes tests for the Mozilla project to go ahead and take a look at that list.  I think if the test writers and reviewers have those items on mind when creating or reviewing a test, we can reduce the amount of new tests which are susceptible to intermittent failures dramatically.

And please make sure to add to the list if you know of other such patterns that I’ve missed.

Posted in Blog Tagged with: , ,

Running Firefox tests with extensions installed

When debugging a test, I’ve sometimes found it useful to have access to an extension such as DOM Inspector or Firebug to debug what’s going on with the test.  In the past, you could do this by a bunch of hacks to make sure that you get the extension inside the test profile folder in time so that the test harness doesn’t delete it for you.  But last week I landed a patch which enables you to do this more efficiently.  Here’s how the new setup works:

  1. You should download the extension’s XPI into your current directory.
  2. You should rename it into {addon-ID}.xpi, where addon-ID is the ID of the extension as specified in its install.rdf file.
  3. You should pass the name of the new XPI file to the –install-extension flag which runtests.py and runreftest.py scripts now accept.

For example, if you want to have Firebug when running the mochitest suite, here’s how you should start the suite:

python objdir/_tests/testing/mochitest/runtests.py --install-extension=firebug\@software.joehewitt.com.xpi

Happy debugging!

Posted in Blog Tagged with: , ,

Let’s keep the blame history clean

I’ve started to believe that commit messages are a very important part of our code history.  I think that they should provide a clear description of what the change does, what’s the corresponding bug number, who reviewed and approved the patch, etc.  I think you should even include a lengthy description of why the patch does what it does, if needed, in a multiline commit message, like this.

We’ve started to use some magic tokens like CLOSED TREE and DONTBUILD which are not really part of the changeset you’re pushing, but instruct our automated tools to modify their behavior.  This is fine because it let’s us do things that we can’t do otherwise, but it messes the blame history up when somebody is looking at your changeset years from now.  I’ve started to use a solution which I think is elegant and cheap: using empty commit messages.  In order to use these tokens, you can create an empty changeset as the topmost changeset that you’re going to push, like this:

hg qnew -m 'Try to fix things so that we can reopen our CLOSED TREE' magictoken
hg qfinish .
hg push

It’s been some time that I’m switching over to this technique, and I thought I should share it in case others are interested in using it too.

Posted in Blog Tagged with: ,

Important changes to the Firefox 4 spell checker

Update: We had to pull these changes out of Firefox 4 because of some regressions that they caused.  We will revisit this issue after Firefox 4, and will hopefully deliver this set of fixes in the next version of Firefox.


I landed a patch today which changes the Firefox 4 built-in spell checker in two important ways:

  • Firefox 4 will be able to correctly spell check words containing hyphens, such as the English word "scot-free".
  • Firefox 4 will be able to correctly spell check words up to 130 letters long.

Here is the slightly longer version of what changed.  Before this change, when Firefox saw a word such as "scot-free", it would break it into two words, "scot" and "free", and pass each of them to Hunspell (which is the spell checking engine we use) to see if they are correctly spelled or not.  So, even though the word was correctly spelled, Hunspell would not have any way to know that, because all it saw was Firefox asking it whether "scot" is correctly spelled, and whether "free" is correctly spelled.  The result was that "scot" was underlined as incorrectly spelled.

After this change, Firefox would pass the entire word, "scot-free" to Hunspell, which would enable Hunspell to recognize the whole word, and make the correct decision about its spelling.  This is especially important for the languages which use the hyphen character as part of the non-compound words frequently.

Also, previously, Firefox would automatically mark any word with more than 64 letters as being incorrectly spelled.  This is a problem for languages which tend to have words much longer than that, such as German and Swedish, to name a few.  The new limit is 130 letters.  This new limit might also not be enough for some words in some languages.  We plan to remove this limit entirely in future Firefox versions.

If you’re a localizer, or a dictionary author, there shouldn’t be any need for you to change the dictionary files for your language.  However, it would be great if you can test Firefox 4 nightlies starting from tomorrow with your languages to verify that it correctly recognizes long words in your language, or those words which have a hyphen in them (and are not compound words).  Keep in mind that these changes will only affect your language if the dictionary is capable of recognizing those words.  If you see any issues with this, please file a bug to let us know.

For the gory details, the curious reader can read bug 355178.

Posted in Blog Tagged with: , ,

Why I do what I do

Let’s go back to spring, 2006.  I was a regular guy, who knew how to write code, and had some free time on his hands.  Back then, after a few years of using free software extensively, I decided that I wanted to stop being only a consumer of free software, and I wanted to give something back to the amazing free software community.  So, I set out to seek an answer to what today seems like one of the most important questions that I ever asked myself, career-wise: "Where can you have the most impact?"

As it turned out, answering that question wasn’t easy.  I had a dilemma.  I didn’t know if I could be effective in a free software community at all (I had no experience in that back then).  I didn’t know what projects needed the most help.  I didn’t know how I could have the most positive impact that was potentially possible.  I didn’t know where my help was needed, and appreciated.

So I started to write down a list of all of the free software projects that I used regularly.  I (unfortunately) don’t have that list around any more, but I remember tens of projects were on that list.  Then I sat down, gazed at the list, and told myself: "Well, this sure didn’t make the choice easy now, did it?"

It certainly did not.  I had all sorts of stuff on that list, from complex things such as the Linux kernel, to very narrowly scoped projects such as gnokii.  I knew that I had to come up with a set of criteria in order to pick up a project from the list, so I decided that I would either look into the projects with the most possible positive impact on users worldwide, or with the projects which could get the most benefit from my expertise.  The list came down to Mozilla and Wine.

Mozilla was the winner of the first category.  It was the project with the most potential positive impact on the world, according to what I thought.  Wine was the winner of the second category.  It was the project with the most potential for taking benefit from my expertise (I used to know lots of stuff about the Windows internals, as I had been doing systems programming for Windows for a long time).  The easier choice for me would have been Wine, as I already had a list of things to work on in Wine, and I had a pretty good idea what needed to be done.  But I don’t like things which come easy.  I like challenges.  So I chose Mozilla.

At that point, I practically knew nothing about contributing to Mozilla.  I went ahead and started to read the hacking guides that Mozilla published at the time.  Then I grabbed the source and tried to look at it.  It gave me the chills.  It was this huge source code which looked very intimidating.  I couldn’t even get it to compile!  So I looked for people who would help me to get started.  timeless and mcsmurf were the two people who helped me compile Firefox for the first time (yes, back in the day, compiling the Mozilla code base for the first time took a while — it took me about a month to finally get a build!).  Then I started to find bugs to work on.  I learned how to write patches, test them, ask for review, ask them to be committed, etc.  The first patch ever committed to the Mozilla code base on my behalf was bug 338179.

Fast forward almost four and a half years later.  I’m still working on the Mozilla project, and I’m pretty happy with what I do!

I have two disjoint sets of reasons why I enjoy my work in the Mozilla project: selfish and altruistic reasons.

I like to feel that there are things that every one of us can do which can have tremendous effect on the world.  There are humanitarian causes in which one could participate.  Most people wouldn’t consider contributing to a software project as one, but I do.  At the broad scope, I see the Mozilla project as a humanitarian cause to empower individuals over the Internet.  We build the technology which has made some amazing things possible.  Projects such as Ushahidi and Kiva are built over the Internet, and people all around the world are using the Internet on a daily basis to engage with other people, find new ideas, get involved in their society, and improve their lives.

Getting involved in the Mozilla project has also helped me become a better person.  It has improved my self-confidence a lot, as it has shown me over and over that I can surprise myself (in a good way!), and it has made me feel that I’m useful.  This has been extremely important to me.  It has also been a constant stream of technical challenges to me, which has kept me happy.  And it’s always nice to see how people react when they find out that I work on Firefox.  I’ve got a lot of compliments, and a lot of thank-you’s, and it’s flattering.  It gives you a warm feeling inside, and I know that’s something that I’m lucky to have.

Posted in Blog Tagged with: ,