The elusive @ key

The elusive @ key

Capturing the @ key in javascript

I regularly use Atlassians confluence and I'm a fan of the simplicity with which I can insert macros, create links or reference people with the { [ and @ keys respectively. Its a great alternative to using keyboard shortcuts or using the mouse to click on menus.

I'm interested in trying similar UI in some of my applications so decided to try out capturing the @ key to load an intellisense menu for peoples names.

First I tried plain javascript to capture the keyCode on a keyUp event but couldn't get the callback to fire as expected.

I've used libraries like mousetrap before in my apps to good effect so I tested that quickly to no avail. It wouldn't fire on the binding to the @ key either. In fact I tried a bunch of key binding libraries and online testing pages and I couldn't find one that worked.

At this point after some research I found out three relevant bits of information.

  1. There is no standardized way to detect keyboard layouts in javascript. Most libraries target US qwerty keyboard layout.
  2. The most reliable way to detect the key pressed is by converting and comparing it using String.fromCharCode()
  3. The only cross-browser way to reliably get the charCode is on the keypress event.

So with this in mind I wrote the following which worked in chrome:

document.getElementById("content").onkeypress(function (e) {  
    if (String.fromCharCode(e.which) === "@") {
        console.log("@ key pressed!");

To make this code cross-browser friendly there is more to do though. Some versions of IE dont populate the e.which property. The following function I found in this article which proved very helpful in navigating the x-browser minefield.

// event.type must be keypress
function getChar(event) {  
  if (event.which == null) {
    return String.fromCharCode(event.keyCode) // IE
  } else if (event.which!=0 && event.charCode!=0) {
    return String.fromCharCode(event.which)   // the rest
  } else {
    return null // special key

Putting it all together I arrived at the following which I think is reasonably robust.

document.getElementById("content").onkeypress(function (e) {  
    var char = getChar(event || window.event);
    if (!char) return; // special key
    if (char === "@") {
        console.log("@ key pressed");

I thought it would take me about two minutes to capture the @ input key. Several hours later, boy was I wrong.

Typescript is great but...did MS just tell me to go **** myself?

image by @jrecursive


TypeScript is great for c# developers but the deployment pipeline is a crummy afterthought.

The what...

I work on some web apps that have lots of javascript. I've been working with web apps for years and there are some areas I feel I can write clean, sensible code. Javascript has never really been one of them.

Part of that, heck most of that, is on me as I'm too lazy to care about things like block vs function scope and callback contexts.

The why?

I'm not a fan of the (function(){ bracket soup; })() and weird var _this = this; stuff that goes on. It all looks so unseemly and I just never feel that productive coding in it.

I've tried (and failed) with the less brackety coffeescript and perhaps it was the tooling, but spending ages looking for the rogue whitespace or incorrectly indented function had me reaching for the asprin and a gun.

Part of our apps were written in coffeescript. They worked ok, but it hadn't been smooth sailing and the code just didn't seem well structured, nor I that productive.

Enter typescript (yass)

Yet another superset. Nothing to see right?

Perhaps it's less jarring from switching between c#, where I spend most of my days, or maybe its because I'm refactoring existing code but when I started experimenting with porting some of our code away from pure js or coffeescript implementations, something magical starting happening.

I started enjoying writing client-side script and my productivity went up; way way up.

Training Wheels

Modules, classes, interfaces and straightforward preservation of scope with lamda style syntax just made me feel at home. The type-checking appealed massively to my desire to have tooling which could help me spot the howlers, I like training wheels on my dynamically typed languages.

Within a short period of time, I had worked my way through a bunch of existing code and it was cleaner, more composable, easier to extend and with fewer errors thanks to the type checking. I think this stuff can scale nicely.

So I'm ripping through code conversions like a boss and having fun doing so, figuratively drunk at the wheel...

When a couple of guys who were up to no good...

starting making trouble in my neighbourhood.

  • Unit testing
  • Deployment

I usually run unit tests as part of deployment so its only one thing really, but the fresh prince quote was too tempting...I digress.

So after a bit of googling I found a few candidates, chutzpa, tsUnit and I already use R# with phantomjs.

One problem with all these is with handling external references and having to reference both ts and the js files for dependent libraries like jQuery et al.

Now typescript tooling, as of VS2013 Update 2 RC made a mistake IMO by automagically adding or inferring all your script references and going ape-daft when you reference js files from ts files. So now one has to add chutzpa only references or for R# keep a second copy of jquery.js named as jquery.ts for testing...seriously?

So leaving aside testing for a moment to running things on a build server ...

oh wait, it wont run on a build server...

So ts files are created in your IDE and it goes like this...

  • MSBuild properties and targets are imported into your .csproj file
  • You get a project property page giving you some options
  • A 'TypeScriptCompile' buildaction for your .ts files
  • Generated js and optionally files are not added to the project
  • the compile tsc.exe is installed in %programfiles32%\Microsoft SDKs\TypeScript\IHateBuildServers
  • the build props and targets are referenced from %programfiles32%\MSBuild\VisualStudio\Vx.x\TypeScript\IHateBuildServersMore

Now I've had my battles with MSBuild targets and SDKs for clickonce, licensing transforms, satellite references and publishing before and each time I feel like the MS guy on my side was off that day. I'm not alone in wanting better.

Installing things on build servers can be done but is not my preference. A more portable solution is to check it in to source control

The build friendly thing to do, would have been to use nuget to deliver both the compiler and build targets sans VS integration so please vote for the issue above if you agree.

Going further, I want much more control over my js build pipeline than ECMA version, js maps and AMD, CommonJS support and remapping base paths. It should be easy to use my own pipeline for bundling, minification, obfuscation etc.

To misquote Kanye...

Microsoft doesn't care about build processes

Please MS, sort this hot mess out!

I really like TypeScript, I really dislike deploying TypeScript.