Web Development

I am pretty sure that Open Sans by Steve Matteson is my favourite font for reading on a screen. Lately, I have found myself opening the browser’s developer tools and messing with the font-face when I want to read anything non-trivial that uses a font I dislike, but turning on Open Sans is less trivial since it is often not available as a browser default.

I could just settle for a default sans serif font, but that makes my eyes sad. I want my eyes to be tiny smiles when I read, so I wrote some code to fix it:

First I made a script that I can paste into the console:

var lnk = document.createElement('link')
lnk.setAttribute('href', '//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800')
lnk.setAttribute('rel', 'stylesheet')
lnk.setAttribute('type', 'text/css')
document.head.appendChild(lnk)
document.body.style.fontFamily = 'Open Sans'

Finding the script and manually pasting it is not ideal though, so I turned it into a bookmarklet:

javascript:(function(){var lnk = document.createElement('link');lnk.setAttribute('href', '//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800');lnk.setAttribute('rel', 'stylesheet');lnk.setAttribute('type', 'text/css');document.head.appendChild(lnk);document.body.style.fontFamily = 'Open Sans'})()

That is much better, except I don’t tend to keep my bookmarks visible on normal pages (just on my new tab page). I looked around and found this little tool: Convert bookmarklet to Chrome extension by Peter Legierski which let me get an icon next to my omni bar. That did the trick. Peter writes about the conversion tool in his blog How to Convert Bookmarklet to Chrome Extension.

Now I can switch to Open Sans with a single click. Thanks Peter 🙂

I have been confused more learning Haskell than learning any other language so far. I am convinced that the reason for this is that Haskell requires thought a lot earlier in the process than any other language I have learned, and it doesn’t let you keep your hands busy while you figure things out by typing a whole lot of worthless syntax.

Not only does Haskell require more thinking upfront; it also takes away a lot of the trivial little bits and pieces that let you continue to keep your hands busy and feel like you’re really doing quite a lot of stuff, like telling the computer how to iterate over a list or add some things up. With thought at a higher level, it forces me to just think about what the program is supposed to do, and just tell the computer to do that.

How am I supposed to feel like a l33t h4ck3r if I’m not typing furiously for hours on end?

Really I was just writing a post about Haskell to make a note about a few things to check out or remember:

  • yesod for writing web applications in Haskell.
  • cabal describes, and provides support for, Haskell packages.
  • Hackage is the central package archive for Haskell.
  • learnhaskell is guide on github to learning Haskell, with links to several courses in a recommended order.
  • Learn You a Haskell for Great Good! is, as the name suggests, a book for learning Haskell. It has amusing pictures, and that would be enough, but it is also well written (as best I can tell – I am not an editor or critic).

Fraser at work said that yesod is fairly heavyweight and requires a lot of up-front learning before being able to do much. This probably makes it a poor candidate while learning, particularly since it is just in my spare time. He mentioned two more lightweight frameworks:

@mwotton uses Scotty, and also mentioned MFlow, describing it as a “continuation-based thing, so you can write multi-transaction web code in a single function”. It sounds like something to check out once I’ve covered some basics.

Chris Allen linked Magma (algebra), “so you know what you’re doing in Haskell,” so I’d better check that out too.

There is a mailing list for people learning Haskell: Haskell-Beginners.

This afternoon I finally got around to starting to watch the videos from CascadiaJS 2013. I started with ECMAScript Regrets by David Bruant. David talked about some features in JavaScript that are broken, but cannot be changed since they would break the Internet. The key message I took away is that code authors can help avoid future regrets in the language by contributing to specs and by checking implementations before they get out of beta to make sure that they are implemented properly. I took some rough notes, and did a bit of research into anything with which I was unfamiliar:

isNaN is a mess

NaN !== NaN, so isNaN() was made to check for NaN, but it gives back strange, unexpected results. Basically, the global function isNaN() is broken, so David recommends using Number.isNan() in ES6, which returns true for NaN and false for everything else.

A polyfill can be used for earlier ES versions; no polyfill is mentioned on the MDN page for Number.isNaN, but the TC39 codex wiki on github has a Number.isNaN polyfill. There is also is-nan on npm with a compliant Number.isNaN shim.

typeof null

typeof null is "object", but should be "null". The recommendation is to use x === null. This also means that testing for object is broken, but can be worked around by testing Object(x) === x.

scope of this

this is often not what you expect. “use strict” turns use of this in functions that are not applied to something into an error, thus preventing accidental inappropriate user of this.

In ES6 arrow functions this refers to the this of the scope in which the arrow function is defined, which is much nicer.

Strict mode

I realized I had never read all that deeply into Strict mode – I know it is a good idea to use, but not the details, so I checked it out.

There is a lot of cool stuff in strict mode that makes the language more secure and less error prone. It is not worth reproducing the detail here, best just point to Strict mode on MDN. The take-home lesson is that there is no reason not to be putting 'use strict'; at the top of every module or function I write.

I was curious about strict mode in Node.js, and I found some discussion about “use strict” in node for ES6 modules. Basically it looks to be just the same as in browsers: you get strict mode if you ask for it.

stateful regexp

Using RegExp.prototype.test() twice on the same regex can give unexpected results since regular expressions in JS are stateful. Recommendation is to use String.prototype.match() instead as it will always work.

order of operations for ! and in

if (!'property' in object) will check whether false is in the object since ! has higher precedence. Looking at the JavaScript Operator Precedence Table on MDN, I see that ! has precedence 4, and in has precedence 8.

Use ESLint to detect this pattern, and replace it with if (!('property' in object)).

Bonus Section: Regrets in other web things:

CSS: box model. Fix with * { box-sizing: border-box; } (see box-sizing on MDN)

DOM: node.parentNode.removeChild(node) (or just the whole DOM).

XHR inability to do cross-origin requests by default.

localStorage

The choice to use per-origin storage for local storage means that any users or applications sharing the same domain are stepping on each other’s toes all the time. Ideally, there would be some ability to request to use a local storage specific to a page or specific path prefix. I have worked around this in one project by making a wrapper around localStorage that adds a prefix to each key, like so:

function customStorage (prefix) {
  return {
    setItem: function (key, val) {
      localStorage.setItem(prefix + key, val);
    },
    getItem: function (key) {
      return localStorage.getItem(prefix + key);
    },
    ...
  }
}

Adding a prefix based on the current page should be fairly trivial: var pageStorage = customStorage(location.pathname)

The theme for this week seems to have been “building a consistent web platform.” The question of whether this is a real focus in my circles for the week, or the mere overactive pattern recognition of my human brain, is moot. Here are some of the items that caught my attention:

Normalizing CSS

A colleague sent an article Introducing Normalize-OpenType.css. It looks pretty handy to me – I have never been a fan of browser inconsistencies, and anything that can bring them in line to have a consistent base on which to build is valuable in my books.

Naturally this caused me to check out the original normalize.css project, so there’s another hole in my knowledge patched up.

No more frameworks

Earlier in the week I listened to JavaScript Jabber episode 112:Refactoring JavaScript Apps Into a Framework with Brandon Hays, in which Joe Eames brought up No more JS frameworks by Joe Gregorio. The discussion got me interested, so I looked it up and started reading. In the article, Joe (the latter Joe) promotes the use of the core web platform (HTML + CSS + JS) directly, over abstracting it away behind frameworks. Joe argues that frameworks require developers to learn an extra layer of abstraction, but do not free them from dealing with the underlying platform since the abstractions are inevitably leaky. Joe advocates using web components to get reusable pieces of functionality that don’t have the compatibility issues of framework-specific components.

Libraries compose, I can keep adding more. Frameworks surround, I can have only one. @raganwald

Normalize.io

All this talk of moving away from frameworks brought to mind normalize.io, which was presented at the latest CampJS last month by Jonathan Ong. This is a really interesting project that aims to do away with a whole lot of the extra mess used in web development at the moment, such as package managers, build systems and their glut of accoutrements.

The enduring aim of the project is to support a workflow in the Normalize philosophy, allowing developers to use ES6 modules and Web Components with no need for local build tools. Normalize.io provides a suite of tools to support this workflow. The enduring tools are an intelligent file server that deals with dependencies and uses SPDY push (removing the need for file concatenation), and a caching proxy that understands semantic versioning and acts as a registry for all clients. Since the requisite browser features are not yet manifest, there is also a temporary tool, nlz, to fill in the missing functionality until browsers can take over.

“Once browsers support ES6 modules and Web Components, nlz(1) will be completely optional, and it’s main purpose will be dependency inspection”

Later in the week I re-listened to the NodeUp 65: A CampJS Show, in which Jonathan discusses some of the philosophy behind Normalize.

Web Components

Web components require 4 different pieces of browser functionality: templates, custom elements, shadow DOM and imports, according to today’s draft of Introduction to Web Components by W3C. It looks like none of these parts are yet fully endorsed by W3C, according to Web Components Current Status | W3C. The various stages of the endorsement process are shown in the W3C Process Document, 7.4 Advancing a Technical Report to Recommendation, but it is a little dry and does not exactly match the terminology on the status page; suffice it to say that in the present one does not simply use web components.

So how does one use web components without browser support? One uses polyfills. Joe Gregorio’s “No more frameworks” article mentions several polyfills to look into: Polymer, X-Tag and Bosonic.

Polymer

In keeping with the theme, while I was getting ready for work on Thursday morning I saw a tweet by Domenic Denicola linking to the Google IO live stream. I managed to catch part of a couple of web component talks: Polymer and Web Components change everything you know about Web development and Polymer and the Web Components revolution.

According to Addy Osmani in the Componentize the Web video, Polymer provides a convenient and opinionated layer on top of vanilla web components. This strays a little from the theme of filling in the inconsistencies of the web platform to work with standard technologies, since it adds data binding, event handlers and touch gestures on top of standard web components. My instinct is concern, but I get the impression that the additions can be safely ignored, so concern is probably an overreaction.