11 Nov 2014

Lessons on Best Practices from Mozilla

One of the ways we facilitate improvement in development processes and the like at EventMobi is by having lunch and learns where someone will present on something interesting. Sometimes that's a cool technology they've used or a good development practice they've discovered or have had experience with. To that end I gave a presentation on some of the lessons I've learnt on best practices while working in the Mozilla open-source community.

Allthough many of these best practices may seem like no brainers to seasoned developers, I still hear way to many horror stories through the grapevine about software being built under seriously bad conditions. So, without further ado.

Code Ownership

One of the things I think Mozilla does really well is the idea of code ownership. This essentially means identifying those who have a level of knowledge about a particular area or module of code and thrusting upon them the responsibility to oversee it. From a practical point of view this means answering questions about the module that others have and also reviewing all of the changes that are being made to the module in order to ensure that they are sane and fit into the larger architecture of the module as a whole.

Mozilla does this really well by having clear definitions of what code ownership means, who code owners are, and who in the owners absence, can make decisions about that module.

The key part to this set up in my opinion is that it makes it clear what the requirements to become a code owner are and what their responsibilities are as a code owner. Too often I feel like, as with other things, if they aren't formalized they become subject to, well, subjectivity. And the details of code ownership and responsibility get lost in translation and hence, not enacted.

Bottom line, formalizing your code ownership policies and processes are a foundation for success. Without that it becomes unclear even who to ask to review code, is it the person in the blame? Possibly. Maybe not. Maybe that person didn't make correct changes, or made changes under the guidance of someone else. Maybe the code your changing has never even had a true 'owner'. No one knows the big picture for that piece of code and so no one knows enough about it to make informed decisions. That's a problem. If a code owner had been designated when that code was written that would never have been an issue.

Testing

We all know testing is a must for any sane development process. What I've learned through Mozilla is that having an insane amount of tests is okay. And honestly, preferable to just enough. As just enough is hard to gauge. The more tests I have in general, the more confident I feel in my code. Having a gauntlet of tests for your code makes it that much stronger.

Not only that, but it's important to be staying on top of tests. As a rule, not accepting code before it has a test and adding regression tests for bugs that are fixed. In exceptional cases code can merged without tests, but it should be tracked so that tests for it will be added later. Ten minutes spent writing a test now could save hours of developer time in the future tracking down bugs.

Saying No

This is one of my personal favourites. And especially relevant I think in companies which are, in my experience, more driven to say yes—in order to hit that extra profit margin, to please that extra customer, to do whatever—as opposed to open-source projects who are able to say no because most of the time they have no deadline. They're driven by desire to build that next cool thing, to build it well, and to do it in a sane way.

From my experience working in Mozilla's and other open-source communities I've found it's important to say no when a feature isn't ready, when it's not good enough yet, when it needs an extra test, when it's not necessary, or when you just ain't got no time for that. I do think, however, that it's hard to say no sometimes while working under the constraints of a profit driven process. There is a healthy balance one can achieve though. We have to strive to achieve this zen like state.

Managing Technical Debt

One of the main ways I've seen this done is by ceating tickets for everything. See something off about the code? Log a ticket. See something in need of refactoring? Log a ticket. See something that needs a test? Log a ticket. Any kind of piece of work that you think needs to get done, any kind of open question that needs to be answered about the state of the code, log a ticket for it.

Logging tickets for the problem gives it visibility and documents it somewhere. This enables a few things to happen. It enables communication about the state of your code base across your team and makes that information easily accessible as it's documented in your tracking system. It also puts the problems that are not necessarily bugs—your stinky, ugly, untested code, or otherwise—to be in your teams face all the time. It's not just getting swept under the rug and not being paid attention too. It forces your team to deal with it and be aware of it.

The key part of this strategy then becomes managing all these tickets and attempting to understand what they are telling you. One of the ways you can do this is by doing regular triages. This means going through the open tickets and getting an idea of what state your code is in and prioritizing how to go about fixing it. This is key as it turns the information that your team has been generating into something actionable and something that you can learn from.

- Tagged in mozilla, open-source, cdot, and development processes.
23 Jul 2014

WebVTT Released in Firefox 31

If you haven't seen the release notes WebVTT has finally been released in Firefox 31. I'm super excited about this as it's the culmination of a lot of my own and countless others' work over the last two years. Especially since it has been delayed for releases 29 and 30.

That being said, there are still a few known major bugs with WebVTT in Firefox 31:

  • TextTrackCue enter, exit, and change events do not work yet. I'm working on getting them done now.
  • WebVTT subtitles do not show on audio only elements yet. This will probably be what is tackled after the TextTrackCue events (EDIT: To clarify, I meant audio only video elements).
  • There is no support for any in-band TextTrack WebVTT data yet. If your a video or audio codec developer that wants in-band WebVTT to work in Firefox, please help out :-).
  • Oh, and there is no UI on the HTML5 Video element to control subtitles... not the most convenient, but it's currently being worked on as well.
I do expect the bugs to start rolling in as well and I'm actually kind of looking forward to that as it will help improve WebVTT in Firefox.

- Tagged in mozilla and open-source.
15 Apr 2014

Getting the number of lines of text in an Element

One of the biggest problems I faced when developing vtt.js is that a lot of the layout algorithm depends on being able to know the line height of the subtitle text. This boils down to being able to know the line height of the div within which the subtitle text sits. A lot of the time this is easy to get:

  var lineHeight = div.style.lineHeight;

But, what if you haven't set a line height? Then you would need to get the computed value of the line height:

  var lineHeight = window.getComputedStyle(null, div).getPropertyValue("lineHeight");

This works... some of the time. On some browsers if you try to get the computed value of the line height and you haven't explicitly set a line height, the computed property will return back as the value normal. That's helpful...

After much searching I found out that you if you use getClientRects on an inline element it will return you a TextRectangle box for each line of text in the inline element. At that point you can either assume that each line has the same height and get just use the height property of the first TextRectangle or to get a somewhat more accurate number you can take the height of the inline element and divide it by the number of TextRectangles you have.

  var inlineElement = document.getElementById("myInlineElement"),
      textRectangles = inlineElement.getClientRects(),
      container = inlineElement.getBoundingClientRect(),
      lineHeight = container.height / textRectangles.length;

  alert("The average line height is: " + lineHeight);

This works really well for the amount of actual code you need to write. I've read about more accurate methods, but they take some serious coding. Like walking through each character in the text and tracking when overflow happens serious.

Now back to my original question which was how to get the number of lines of text in a div (block level) element. The way I did this was to wrap my div which has my content in another div, and set the inner div's display property to inline. Then you can calculate the line height/number of lines of text of the inner div since it has inline display. This way you retain your contents block level layout while being able to figure out how many lines of text it is.

This is it all put together:

  <div>
    <div id="content" style="display:inline;">
      This is all my content in here. I wonder how many lines it is?
    </div>
  </div>
  var inlineElement = document.getElementById("content"),
      textRectangles = inlineElement.getClientRects(),
      container = inlineElement.getBoundingClientRect(),
      lineHeight = container.height / textRectangles.length;

  alert("The average line height is: " + lineHeight);
- Tagged in mozilla, seneca college, open-source, and cdot.
11 Apr 2014

Hosting your JavaScript library builds for Bower

A while ago I blogged about the troubles of hosting a pre-built distribution of vtt.js for Bower. The issue was that there is a build step we have to do to get a distributable file that Bower can use. So we couldn't just point Bower at our repo and be done with it as we weren't currently checking in the builds. I decided on hosting these builds in a separate repo instead of checking the builds into the main repo. However, this got troublesome after a while (as you might be able to imagine) since I was building and commiting the Bower updates manually instead of making a script like I should have. It might be a good thing that I didn't end up automating it with a script since we decided to switch to hosting the builds in the same repo as the source code.

The way I ended up solving this was to build a grunt task that utilizes a number of other tasks to build and commit the files while bumping our library version. This way we're not checking in new dist files with every little change to the code. Dist files which won't even be available through Bower or node because they're not attached to a particular version. We only need to build and check in the dist files when we're ready to make a new release.

I called this grunt task release and it utilizes the grunt-contrib-concat, grunt-contrib-uglify, and grunt-bump modules.

  grunt.registerTask( "build", [ "uglify:dist", "concat:dist" ] );

  grunt.registerTask( "stage-dist", "Stage dist files.", function() {
    exec( "git add dist/*", this.async() );
  });

  grunt.registerTask("release", "Build the distributables and bump the version.", function(arg) {
    grunt.task.run( "build", "stage-dist", "bump:" + arg );
  });

I've also separated out builds into dev builds and dist builds. This way in the normal course of development we don't build dist files which are tracked by git and have to worry about not commiting those changes. Which would be the case because our test suite needs to build the library in order to test it.

  grunt.registerTask( "build", [ "uglify:dist", "concat:dist" ] );
  grunt.registerTask( "dev-build", [ "uglify:dev", "concat:dev" ])
  grunt.registerTask( "default", [ "jshint", "dev-build" ]);

Then when we're ready to make a new release with a new dist we would just run.

  grunt release:patch // Or major or minor if we want too.
- Tagged in mozilla, seneca college, open-source, and cdot.
28 Mar 2014

WebVTT (vtt.js) on Nodejs

Good news! You can now use vtt.js on Nodejs. There are two different ways you can get it on npm:

  1. You can install the basic vtt.js package which just exports the WebVTT, VTTCue, and VTTRegion implementations into a nice Node package for you. Using this method you will have to provide your own window object for vtt.js to run on. See the docs for more information.
  2. You can install node-vtt which is a Node wrapper for vtt.js. node-vtt runs vtt.js on an instance of PhantomJS. This means that you don't have to provide your own window object for vtt.js since it will already be running in the context of a web page. It also provides a couple of convenience functions such as parseFile, processFile, and others. See the docs for more information.
- Tagged in mozilla, seneca college, open-source, and cdot.

Wow coding Copyleft Richard Eyre 2013

Code for this site can be found on GitHub.