Wednesday, October 27, 2010

How the smallest bugs can take the most time to solve

For the past few weeks, I have been fixing problems that I run into while testing some of the new video tools that Michael Dale has been developing for the Wikimedia Foundation. As with any new software, especially Javascript tools, there are plenty of issues and since I can find them, I might as well fix some of them, instead of throwing it all back at Michael.

This week I ran into one particular annoying issue. For some reason the menu in the new mwEmbed mediaplayer (Demo of the player) was flickering under certain conditions on Safari. I created a video that demonstrates the problem.

So I was looking trough the code of the player, trying to come up with a reason on why this would behave like this and why only in Safari. I spent a few hours tracking all the events, assuming that some event (like mouseover) for some reason was incorrectly telling the menu to hide itself. I was validated in this line of thought by observing that manipulating some of the Javascript events of the player, would influence the time the menu would reappear. I could however not find something that influenced the hiding of the menu. The fact that jQuery uses anonymous functions everywhere didn't make the debugging process any easier.

My other idea was that perhaps it was a bug in the HTML5 <video> element of Safari, or in the XiphQT plugins used to decode the video in combination with z-index or relative positioning. I created a few testcases from scratch, but neither proved to be likely. I could not figure out what the problem was.

After some discussion with a few Webkit people, I decided to reduce the original HTML. The original HTML is a lot of code, which was why I was reluctant at first to take this path, but all other options had run out. After some heavy reducing, I figured out that Javascript was no factor here, pure HTML and CSS showed the same problem. This took me by surprise, since I had earlier observed how certain JS events were causing the menu to reappear. Cutting and weeding some more I finally found the cause. The three elements that are needed to reproduce the problem.

  1. An HTML5 video element
  2. An overflowing element in scroll mode, on top of the video element
  3. Opacity set on that overflowing element.

Finally I had traced the issue and it turned out to be a bug in Safari/Webkit. The reason as to why the Javascript event manipulation would influence the problem was easy to understand in retrospect. Such events were triggering redraw events in the browser, which for some unknown reason solves the drawing problem caused by the scrolling event.

Hours of debugging for a small issue, that had its root cause in a browser bug. A ticket has been filed with the Webkit developers, but it shows how developing for new browser features continues to be a time consuming process. All new code has bugs, and when the new code is relying on other new code, finding those bugs takes quadruple the time.