Miscellaneous Findings VII: Quirks

There’s one finding about a handy D3 method, and the rest are about quirks, including one that affected getting this weblog, in this edition of Miscellaneous Findings.

This is a roundup of miscellaneous things that I’ve found out about (or have rediscovered). I take notes on findings regularly, and I put the findings that translate well to speech on my podcast, Small Findings. The rest (which are often technical findings), I put here. They’re not always written up for maximum comprehension as a blog post, but if anything is hard to understand, please email me if you need clarification.

JavaScript weirdness

There is a self keyword for referring to the global scope, whether it’s Window or Worker.

#javascript #weird

Wintersmith

If you are using a Jade template with the static site generator Wintersmith, and your template pulls in files in a directory like so:

block content
  article.article
    section.content!= typogr(page.html).typogrify()
    each finding in page.parent.findings
      include partials/finding

And you then edit a file in that directory (in this example findings), you may get this error next time you build the site:

articles/miscellaneous-findings-006/index.html: /home/jimkang/gcw/weblog-src/templates/partials/finding.jade:5
  > 5|     section.content!= typogr(page.html).typogrify()

Cannot read property 'jquery' of undefined

I thought this had something to do with the contents of the files being read, and I was partly right, but no amount of editing changed anything, and the build succeeded only when I deleted everything in findings.

I was editing with vim, and vim puts a hidden .swp file in the directory. typogrify was choking on that. Closing the file in vim got rid of the problem.

#static-site #vim #hidden

d3

In D3 6 (maybe this was introduced in 5? definitely was not in 4), there is a handy join method on the selection object.

It’s shorthand for exit with remove chained to it, enter with append chained to it, and returns the merged enter and update selections (the set of selections that’s still valid after syncing with the new data) so that you can make updates to them, like updating attributes and text.

So you can replace this:

var connectionSels = connectionsSel
  .selectAll('li')
  .data(soul.connections);
connectionSels.exit().remove();
var newConnectionSels = connectionSels.enter().append('li');
newConnectionSels.merge(connectionSels).text(accessor('identity'));

With:

connectionsSel
  .selectAll('li')
  .data(soul.connections)
  .join('li')
  .text(accessor('identity'));

It seems trivial and sort of is, but I find it cuts down on the reading strain.

And it’s not for all situations. If you’re doing something special on the exit or enter selections, you can provide functions to join to do them, but in that case, I think it’s better to stay explicit like this:

var containers = itemRoot.selectAll('.item-container').data(ids, accessor('identity'));
containers.exit().remove();
containers
  .enter()
  .append('li')
  .classed('item-container', true)
  .classed('soul', true)
  .attr('id', accessor('identity'));

#d3

Mobile Safari

File inputs

You can set the accept attribute of an input element to audio/*, and on Firefox, the file selection dialog will let the user select any audio file. This doesn’t work on Mobile Safari, which apparently can’t tell what files are audio files. So, you have to specify file extensions, like:

<input type="file" id="media-file" accept="image/*, video/*, audio/*, .m4a,.ogg,.mp3,.wav" multiple />

#web #media #browser