tag:blogger.com,1999:blog-41210550195221693952024-03-13T19:38:42.201-07:00//todo: think of better titleMe talking about random stuff. Mostly for future reference.Unknownnoreply@blogger.comBlogger752125tag:blogger.com,1999:blog-4121055019522169395.post-5355255965087924752014-07-03T06:29:00.001-07:002014-07-03T06:29:17.906-07:00Sweet.js readtables and JSX macros<a href="http://jlongster.com/Compiling-JSX-with-Sweet.js-using-Readtables">James Long implemented a JSX compiler using Sweet.js macros</a>. Very neat. I can probably port it to work with Mithril as well.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-34037982310677271952014-05-20T08:09:00.001-07:002014-05-20T08:09:13.358-07:00Lessons learned from Angular<p>I just realized that I completely forgot to announce here that I posted <a href="http://lhorie.github.io/mithril-blog/lessons-learned-from-angular.html">this article about lessons learned from Angular</a> on the Mithril Blog.</p><br />
<p>There, I talk about some of the rationales for why Mithril templates are designed the way they are, and what makes them so powerful.</p>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4121055019522169395.post-63390637639791861522014-05-18T08:54:00.002-07:002014-05-18T08:54:22.579-07:00Piggybacking requests in a widgety world<a href="http://lhorie.github.io/mithril-blog/piggybacking-requests-in-a-widgety-world.html">This week's post on the Mithril blog talks about how we can use MVC's separation of concerns to implement a neat model-level optimization</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-24311391860673222712014-05-14T10:56:00.002-07:002014-05-14T10:56:58.964-07:00An exercise in awesomeness<p>I wrote <a href="http://lhorie.github.io/mithril-blog/an-exercise-in-awesomeness.html">a follow-up article</a> to James Long's fantastic <a href="http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome">Removing user interface complexity</a> article, where I ported some of the code examples to Mithril.</p><br />
<p><a href="https://news.ycombinator.com/item?id=7744589">HN post</a></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-21387325120919856322014-05-11T06:15:00.000-07:002014-05-11T06:15:01.314-07:00Getting over a fear of turing complete templatesOver at the Mithril blog, I wrote an article about <a href="http://lhorie.github.io/mithril-blog/getting-over-a-fear-of-turing-complete-templates.html"> the erroneous belief that turing completeness leads to bad code and how it can be used to achieve better expressiveness in MVC templates</a>.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-2737577523994186242014-04-29T07:29:00.000-07:002014-04-29T07:29:06.723-07:00JS animations are cool againA while back GSAP made a (at the time controversial) claim that <a href="http://css-tricks.com/myth-busting-css-animations-vs-javascript/">JS-based animations are actually as fast as CSS based ones</a> (if not faster). It's just jQuery that is slow.<br />
<br />
Now, there's <a href="http://julian.com/research/velocity/">Velocity.js</a>, which brings that GSAP-like speed back to the world of jQuery.<br />
<br />
What GSAP showed us is that Javascript animations can be really powerful (or as it advertises, "impossible w/ CSS3"). A similar trend is that of constraint-based layout engines popping up. In the <a href="http://lhorie.github.io/mithril-blog/">Mithril blog</a> and docs, I've been talking about the expressive power of Javascript in the context of data binding engines and template componentization (something that has been generally in the domain of the HTML language) and this same expressive power is starting to flourish in the styling and flair arena.<br />
<br />
It's really looking like Javascript is taking the reins away from CSS. I like this trend.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-81481177260071755072014-04-28T09:04:00.001-07:002014-04-28T09:04:17.217-07:00Mithril benchmark<a href="http://jsperf.com/angular-vs-knockout-vs-ember/292">Just stumbled upon someone's benchmark of Angular, Ember, Knockout, React and Mithril.</a> Thought others might be interested in seeing it as well.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-68443014351722722852014-04-27T18:55:00.001-07:002014-04-27T18:55:24.227-07:00Curry flavored promises<a href="http://lhorie.github.io/mithril-blog/curry-flavored-promises.html">I wrote an article about using Promises and currying over at the Mithril blog.</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-51349383773995035922014-04-14T10:26:00.002-07:002014-04-14T10:26:49.094-07:00Building a "Seinfeld" app w/ Mithril.js<a href="http://lhorie.github.io/mithril-blog/building-a-seinfeld-app.html">Just reblogging from my Mithril blog</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-26524307051340415802013-12-19T09:27:00.001-08:002013-12-19T09:49:03.766-08:00Koa.js explained<a href="https://github.com/koajs/koa/blob/master/docs/guide.md">Koa.js</a> is a Node.js framework from the Express.js authors. The biggest feature here is that it uses ES6 generators to elegantly fix the callback hell problem that arises in sufficiently complex Node.js apps<br />
<br />
For those who are not familiar w/ ES6 generators, here's an illustration:<br />
<br />
Consider an asynchronous app that does several IO operations. Using the currently standard javscript callback style, an application might look like this:<br />
<pre>app.authenticate(function(loggedIn) {
app.fileExists("bla.txt", function(exists) {
app.readFile("bla.txt", function(text) {
app.sendToClient(text, function() {
app.log("operation successful")
})
})
})
})
</pre>As you can see there's a lot of nesting once you start doing several things in sequence. As it turns out, this causes all sort of problems:<br />
<br />
<ul><li>hard to throw and catch errors effectively<br />
<li>lots of boilerplate code<br />
<li>even more boilerplate code when doing parallel asynchronous operations<br />
<li>difficult to reason about non-trivial code (e.g. what is in scope where, when there are many parallel things happening?)<br />
</ul>ES6 generators are basically functions that can pause and later restart from where they paused. The syntax is the same as a regular function, except that it has an asterisk before the function name, and that it allows the `yield` keyword to be used inside of it <pre>function *myGenerator(a) {
yield a;
}
</pre>The` yield` keyword works almost exactly like `return`, except that if you run the function again, the code will continue executing from the next statement after the yield, instead of running the whole function again. (another difference is that yield is an expression)
For example: <pre>function *countTo3() {
console.log(1);
yield;
console.log(2);
yield;
console.log(3);
}
countTo3(); // logs 1
countTo3(); // logs 2
countTo3(); // logs 3
</pre>With this framework, we can then rewrite that nested application kinda like this: <pre>function *myApp() {
var loggedIn = yield app.authenticate()
var exists = yield app.fileExists("bla.txt")
var text = yield app.readFile("bla.txt")
yield app.sendToClient(text)
app.log("operation successful")
}
</pre>So basically, every time you call `yield` you're explicitly telling the app to "go away and do other stuff" while waiting for expensive IO operations, which makes it very easy to reason about the code, and comes with all the goodness of readability, proper exception stacking, etc.<br />
<br />
Very interesting stuff.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-25044146793939657432013-10-29T14:15:00.000-07:002013-10-29T20:33:23.552-07:00Things that suck in AngularJS (a follow-up)<p>So apparently my last post made it to the <a href="https://news.ycombinator.com/item?id=6630156">HN front page last night</a>. (For the curious, it got ~35k page views in the span of one day, mostly coming from Reddit. That's roughly the same amount of traffic from all other posts in this blog since inception. Heh.)</p><p>First, I'd like to thank the people who have pointed out some factual mistakes in <a href="http://lhorie.blogspot.ca/2013/09/things-that-suck-in-angularjs.html">my previous post</a> (specifically, the existence of $q/$q.all and $timeout.cancel). I was not aware of $q.all, so the rant ended up being useful for me to learn new things after all :)</p><p>The point I was making when I mentioned $timeout though was about orthogonality - e.g. `ng-if` not having an `ng-else` or even an `ng-if-not` counterpart to match `ng-show/ng-hide` - so hopefully my silly mistake didn't detract from the argument.</p><p>Anyways, that post is now almost 2 months old, and a lot has happened both in terms of the progress of AngularJS releases, and my own understanding of the framework/ecosystem, so I figured I should add a little update.</p><h2>What is better</h2><h3>Documentation</h3><p>In the documentation front, there's been a consistent trickle of PR pull requests on the github project to improve various areas of the documentation. Most notoriously, the <a href="http://docs.angularjs.org/guide/directive">directive guide</a> is a lot more example-driven and beginner-friendly. Unfortunately, the old docs for directives are nowhere to be found now and it's now much harder to find explanations of what options are available. But it's definitely more approachable and hands-on.</p><p>Also, a variety of good 3rd party resources have been springing up. <a href="http://www.ng-newsletter.com/">ng-newsletter.com</a>, for example, hits the ground running with some basics and quickly ramps up to some real-world, in-the-trenches goodness.</p><h3>3rd Party integration</h3><p>In a similar note, there are also a growing number of projects offering support for Angular, e.g. KendoUI, the AngularCordova project, etc. This is turning Angular into a much more pragmatic pick for a vast range of projects than many of the newer slimmer frameworks in the data binding arena.</p><h3>Features</h3><p>The latest two releases bring a bunch of fixes and pragmatic features (e.g. $interval). On the one hand I do appreciate the new features, but on the other, these are release candidates, which by most definitions, shouldn't include scope creep or major breaking changes...</p><p>Which leads me to</p><h2>What still sucks</h2><h3>Regressions</h3><p>Regressions are still a very big weakness in AngularJS: the activity in the github issues list spiked after 1.2.rc3 was released, and many of the issues are somewhat serious integration-level problems. Their internal test suite seems to severely lack directive-interop tests, which are critical for a framework with so many interdependent components (I say they're interdependent because they all deal with $scope, often with subtle scope isolation/initialization timing related caveats). The end result is that upgrading Angular is nowhere near the plug-and-play experience of jQuery upgrades.</p><h2>Other things I didn't mention before</h2><h3>Components</h3><p>If you haven't seen this term before in the context of AngularJS, components are basically organizational directives, i.e. self-contained ng-includes. They are a mostly useful when a page hosts many loosely related, complex widgets or panels.</p><p>One weird design wrinkle is the ambiguity of directive controllers vs regular controllers. Using a directive controller in a component yields less code and clearer modularity, but it breaks the general convention of being able to find all business logic in the controllers folder and DOM stuff in directives. On the other side of the coin, using a regular controller creates more boilerplate code and makes the scoping of inputs and outputs harder to follow.</p><p>A big problem with components (and directives in general) is that they can't be used recursively to build things like tree structures. In fact, doing so hangs the browser! The only workaround for this is to use ng-include and shadow variables, which is ugly and confusing from a maintainability standpoint.</p><h3>Hiring</h3><p>YMMV here, but in Toronto, hiring an AngularJS developer is pretty damn hard. <a href="http://careers.klick.com/career/angularjs-developer/">We've been looking for a while</a>, but without much success (and we even have a dedicated hiring team). For comparison, another discipline where we historically had difficulty finding good candidates was for backend dev positions, and we've been able to hire 5 since the time we've started advertising for the Angular position. (and yes, <a href="http://careers.klick.com">we're still hiring</a> for both positions and more).</p><p>But the bottom line is that, when the time comes to actually expand the team, the number of people with both a strong front-end background (to deal w/ Angular bugs) and the backend engineering chops to follow the AngularJS way (tm) of designing applications turns out to be surprisingly small.</p><h2>Conclusion</h2><p>Angular continues to improve its weak areas and gain momentum, but there are still some somewhat big technical issues and quirks that make development challenging. The unique positioning of the framework in the context of specializations within the industry also brings recruiting challenges to the table.</p><p>On a separate note, one commenter expressed interest in a post about backbone. Are people interested in analyses of other frameworks as well?</p>Unknownnoreply@blogger.com8tag:blogger.com,1999:blog-4121055019522169395.post-23539218985614153472013-09-03T13:14:00.000-07:002013-09-03T13:14:14.164-07:00Things that suck in AngularJS<p>Every once in a while, I find that someone is interested in AngularJS, but not sure if they should stick to their jQuery comfort zone or make the plunge and learn the new thing. It's relatively easy to come across people singing praises to the paradigm shifts that Angular enforces, and there are plenty of tutorials out there showing how to get Angular to do cool stuff without much effort. There's also pretty good explanations out there for some of the more mysterious concepts (like $apply() and transclusions and animations).</p><p>The reason I'm writing this is not an attempt to rehash any of those. As it turns out, I've been knee deep doing some pretty neat stuff with AngularJS, RESTful web services, web sockets and other cool HTML5 techs at my job, and I think I've got enough experience to list out some very specific things that aren't that great about Angular. Don't get me wrong, it's a great tool for the stuff I'm doing, but I just feel like complaining a little :)</p><p>So, what is sucky in Angular anyways?</p><h2>Documentation</h2><p>Docs are a constant complaint in the community: despite being touted as a testable framework, the unit testing guide has been grossly incomplete for ages. Not only that, but most of the API documentation lacks code examples, and makes little to no effort pointing out arbitrary surprises (e.g. ng-selected takes a string instead of a boolean, .bootstrap()'s second parameter is an array, not a string, etc)</p><p>The page for directives is another (in)famous part of the docs that, despite relating to one of the most important aspects of the framework, is often derided as being overly dry, and spends more time talking about internals than how to actually create directives.</p><h2>DOM integration and directives</h2><p>Many common DOM actions are supported poorly, e.g setting focus on a specific element inside of a repeater, or setting the dimensions/position of an element based on the dimensions/position of another.</p><p>Directives - the blessed way of integrating to the DOM - have a lot of optional arguments that don't work well together, and others that break in subtle, hard-to-reason-about ways. For example, ngModelController.$render breaks once you add scope parameters. Transclusion also silently modifies the scope inheritance semantics if scope parameters are added.</p><p>Directives can also get stuck in infinite loops when two or more of them act on the same ng-model binding and there are change even handlers.</p><p>The problem is aggravated by compiled directives such as ng-repeat and the unstable-only ng-if, since those re-initialize child directives, and can cause event handlers to fire when things haven't really changed.</p><p>Another problem with directives nested in ng-repeats is that there's no easy way to control the lifecycle of a directive. Once a list changes (usually due to an ajax call), the redraw performance of a repeater can get unacceptably slow.</p><p>The fact that asynchrony is abstracted away in ng-include and the templateUrl argument in directives can also cause difficult to troubleshoot bugs.</p><p>I often find that I need to write large comments to explain some subtle side-effect that arises out of an $apply cycle when there are several things happening concurrently in a page.</p><h2>Business Logic</h2><p>In addition to the subtle errors that occasionally arise from asynchronous directives, I often run into problems with strictly business-logic ajax as well: for one thing, there's no equivalent to jQuery's $.when, which makes multi-request dependency management difficult (when you hit multiple web services to derive some conjoined information, for example).</p><p>It's even more difficult to reason about business logic when your app is big enough to contain nested controllers. You need to carefully manage when controllers are instantiated, what data is ready when, which variables hold promises and when they are resolved, and what is available where; all tied by the scope inheritance mechanism, which is unsettlingly reminiscent of global state.</p><p>Bidirectional bindings are two-edged: while they simplify some types of tasks, they make others surprising, e.g. some directives impose types on the variable bound to them, so you sometimes find yourself forced to cast booleans to strings for no seemingly good reason.</p><p>Also, I often find myself wrestling against bi-directionality conflicting w/ event-driven programming style, i.e. when calling http methods in response to user actions, as opposed to data changes. This closely relates to the infinite loop problem I mention above and it's a bit of a case of a "pure" system (in the side-effect sense) forgetting to account for the real-life need for non-idempotent actions.</p><h2>Filter Caching</h2><p>Repeater filters are not straightforward to cache: if I want to display the length of a filtered list, I have to either re-compute the filtered list (very expensive), or introduce assignment logic into the HTML view (untestable and ugly), or refactor the filter into the controller as part of the data initialization (not desirable for data required to compute derivative metadata).</p><h2>3rd-Party integration</h2><p>Calling Angular services, filters and controllers from outside of Angular is verbose and non-intuitive, making it a difficult sell for progressive adoption into a legacy codebase (read: most non-trivial codebases). More importantly, under those circumstances, it sometimes fails in inexplicable undebuggable ways (I'm looking at you, $http, and yes, I called $el.scope().$apply()).</p><h2>Internal Complexity</h2><p>I consider myself to be a reasonably good js developer, but the internals of AngularJS are overwhelmingly non-approachable. Even seemingly simple request changes like the ability to abort http requests require massive amounts of design discussion and implementation attempts because of all the levels of abstraction that need to be reconciled. My general feeling is that the API designers don't care much about orthogonality: several features are missing counterpart/complementary mechanisms (e.g. there's a handy `$timeout` but not a `$clearTimeout`, form.setPristine() was added in unstable, but it's not readily available in the controller and it doesn't have per-field equivalents, etc)</p><p>A lot of the complexity leaks from the abstraction prominently into developers' day-to-day: most Angular developers have seen the non-helpful "$apply() already in progress" error. Also, in my experience, bugs in AngularJS apps require a relatively intimate knowledge of several layers of abstraction simultaneously, and are much harder to debug than traditional jQuery ones.</p><p>Another semi-related note: The unstable branch is rightly named so: it introduces breaking API changes at every release, and new features often have integration problems when combined with other features. It does contain some incredibly useful features, but I'm not even sure how they plan on officially releasing this unstable stuff, since the effort required for developers to migrate from the current stable to the current unstable grows just that much more with every version increment.</p><h2>Testability</h2><p>There are no built-in mechanisms for testing directives.</p><p>Also, angular-mocks is incompatible with the ng-app directive (and .bootstrap(), for that matter), making in-page testing (using jasmine ConsoleReporter) impossible.</p><p>Integration testing can only be done when using ng-app, making multi-application pages untestable. This is a testability showstopper when your project involves a lot of legacy code that is ported gradually (like most legacy-laden projects are).</p><h2>Parting Thoughts</h2><p>This is a list of things that could be improved in AngularJS (1.2) from the point of view of someone whose full time job is pretty much to push techonology to the limit. It's not an attempt to promote Ember (which I haven't had the chance to look at) or Backbone/Knockout/jQuery/whatever, all of which have their own merits -- ok, Backbone sucks, but that's for another post :)</p>Unknownnoreply@blogger.com17tag:blogger.com,1999:blog-4121055019522169395.post-15210902001228689392013-01-04T11:06:00.002-08:002013-01-04T11:06:55.269-08:00Floats and clears in html emails<p>So I was trying out a new technique (ok more like "so old no one remembers it exists") to see if I could do floating and clearing in emails.</p><p>After running a test through Litmus.com, it turns out that it does work in all the major clients (even in Outlook 2010)</p><p>The caveat is that you can only float images, but it should make life a bit easier if you develop emails.</p><p><strong>To float left:</strong></p><pre><img src=”theimage.png” align=”left” /></pre><p><strong>To float right:</strong></p><pre><img src=”theimage.png” align=”right” /></pre><p><strong>To clear:</strong></p><pre><br clear=”left” /></pre><br />
<p>Putting it all together, instead of a using bunch of nested tables, the code would look like this:</p><pre><img align="left" src=" bla.png" />
Here's some text beside the image
<br clear="left" />
Here's more text below the image
</pre>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-4121055019522169395.post-63420096455203325632012-12-13T12:57:00.000-08:002012-12-13T12:57:05.775-08:00The Mathematical Hacker<p><a href="http://www.evanmiller.org/mathematical-hacker.html">Interesting essay on programming and mathematics</a>.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-75036861087828041212012-12-13T07:49:00.000-08:002012-12-13T07:56:09.489-08:00A little iPad app for Santa<p>I had a bit of downtime recently, so <a href="http://lhorie.github.com/appointments-app/">I slapped together a little toy app</a> using a few technologies I've been meaning to play around with. The original idea was to create a proof of concept for bringing Telus' (or Rogers or whoever) technician appointment system onto iPads. A customer rep (or a customer via some web interface) would book appointments to the system, and a technician could then see which ones are close by.</p><p>That sounds a bit dry, so in the spirit of Christmas, I decided to populated the appointments database with some tasks for Santa.</p><p><small>P.S: Dear Santa. I've been a good kid and I'd like a flamethrower.</small></p><p>If you have an iPad, you can see the app <a href="http://lhorie.github.com/appointments-app/">here</a>. Change the radius input to see more pins on the map and feel free to add more if you want to. It works on desktop too, if your browser supports Geolocation, but it might not pinpoint you as accurately.</p><h2>Technologies: Angular.js, Geolocation, Google Maps, Mongo on the cloud</h2><p>One thing I wanted to explore was organizing front end code a little better than the common one-giant-file-full-of-random-jQuery-scripts. So, I looked into Angular.js</p><p>It's essentially a client-side MVC framework. It does routing:</p><pre>$routeProvider.when('/', {
controller: ListCtrl,
templateUrl: 'list.html'
})
</pre><p>Controllers are just functions, but they have magic arguments: in the example below, the $scope object magically makes its members available as variables in the view. This feature is also used to import modules, making it very terse and elegant to manage dependencies in controllers.</p><pre>function ListCtrl($scope) {
$scope.greeting = "hello"
}
</pre><p>Views use plain HTML with extra attributes to provide functionality:</p><pre><-- this would say hello -->
<input ng-model="greeting" />
</pre><p>Models make it super easy to integrate to RESTful JSON services, which helps keeping server-side and client-side logic separated.</p><p>Check the <a href="https://github.com/lhorie/appointments-app/blob/master/appointment.js">Appointment module</a> for an out-of-the-box example of connecting to a mongo db RESTful web interface (via mongolab.com, hosted on the EC2 cloud). The <a href="https://github.com/lhorie/appointments-app/blob/master/geolocation.js">Geolocation module</a> connects to the HTML5 Geolocation API, and to MapQuest's Nominatim service to map GPS points to addresses.</p><p>One of the neat things about Angular.js is that it does a lot of the heavy lifting for data-binding on the UI. Check the ng-repeat directive in the <a href="https://github.com/lhorie/appointments-app/blob/master/list.html">list.html</a> file and $scope.nearby function in <a href="https://github.com/lhorie/appointments-app/blob/master/controller.js">controller.js</a> for an example of filtering the data set by distance to current location.</p><p>Google Maps is something I added mostly for eye candy. The code for it is in the controller.js file and it's fairly straightforward.</p><p>As always, feedback welcome.</p><br />
<br />
<br />
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-21149565594784708332012-11-28T11:04:00.001-08:002012-11-28T11:04:11.064-08:00HTML 5 iOS App Development<p><a href="http://prezi.com/vabpmt8pqnqr/html5-ios-app-development/">I wrote a presentation on HTML5 application development for iOS</a>. There are also some supporting files up on <a href="https://github.com/lhorie/web-app-demo/">GitHub</a> for those who would like to play around.</p><p>Feedback welcome.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-77914290092180433932012-11-13T10:00:00.002-08:002012-11-13T10:00:57.037-08:00Useful Javascript APIs<p><a href="http://www.slideshare.net/nzakas/javascript-apis-youve-never-heard-of-and-some-you-have">Nice summary</a></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-5000008269733819702012-10-16T10:46:00.001-07:002012-10-16T10:46:52.949-07:00How to make a product video on the cheap<p><a href="http://blog.kickofflabs.com/how-to-do-a-great-product-promo-video-for-less-than-200/">Those are some useful links</a></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-30052749858237054442012-10-10T06:49:00.000-07:002012-10-10T06:49:06.206-07:00Canvas effects<p><a href="http://www.html5rocks.com/en/tutorials/canvas/texteffects/">Neat effects</a></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-17021313918247645172012-07-10T07:57:00.001-07:002012-07-10T07:57:46.041-07:00getUserMedia - camera / microphone APIs landing in Chromium<p><a href="http://blog.chromium.org/2012/07/introducing-getusermedia-and-javascript.html">The Chromium team just announced the latest beta now has user media APIs</a>. Javascript is quickly becoming more and more interesting.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-48201693468255641542012-07-09T09:34:00.002-07:002012-07-09T09:34:24.147-07:00Happiness<p><a href="http://www.bakadesuyo.com/why-can-it-be-so-hard-to-be-happy">Cute.</a></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-47873613042297510902012-07-06T06:35:00.001-07:002012-07-06T06:35:20.014-07:00Neural network in js<p><a href="https://github.com/harthur/brain">A bayesian classifier</a>.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-57626843901734792982012-06-08T09:47:00.002-07:002012-06-08T09:47:30.586-07:00speak.js - speech generation in javascript<p><a href="https://github.com/katsuyan/speak.js/blob/master/README.markdown">I'm so playing with this tonight</a>.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-71606691895688968692012-05-29T07:37:00.003-07:002012-05-29T08:10:34.451-07:00(ab)using labels in javascript<p>Something that always felt a bit messy in unobtrusive javascript coding was how we normally use class names for both styling and binding functionality to an element. For example:</p><pre><-- HTML -->
<a class="expander" href="javascript:void(0)"></a>
/* CSS */
.expander {/* some arrow styles */}
/* javascript */
$(".expander").click(toggleAccordion)
</pre><p>There are two problems with this:</p><ol><li>If I have another type of expander button somewhere else that needs to do something different (e.g. maybe somewhere I need to ajax content in first), then I need to clutter the code with more stuff in order to allows the different buttons to do different things</li>
<li>I have no indication of what said button does by inspecting it w/ Firebug/dev tools, let alone by just looking at it. I have to slog through the code to figure out what code might get attached to this element</li>
</ol><h2>Stepping back for a moment</h2><p>As it turns out, there's a third, minor issue: the href attribute of the element doesn't serve any purpose. It doesn't even tell the user where clicking on the element might go. It's just a clunky way of telling the browser to not do its default action when you click on the element. It's a code smell that can be refactored to something like the this:</p><pre>$(".expander").click(false)</pre><p>As it also turns out, browsers as old as IE8 support document.querySelectorAll, so finding elements by href nowadays is not particularly slower than searching by class name. So why not repurpose that useless href back to identifying what a user should expect when clicking on the element?</p><h2>What's javascript:void(0) anyways?</h2><p>javascript:void(0) is an antique from a decade ago that most people just blindly use without really thinking about what it might mean. All this line does is run some javascript that returns undefined. Returning undefined in this context is equivalent to e.preventDefault(), which in this case means "prevent going to a URL".</p><p>There are many ways of returning undefined, the shortest of which is to simply... do nothing.</p><pre><a href="javascript:<span style="color:red">;</span>"></a></pre><p>But we can do better: do nothing in a <em>descriptive</em> way, by using javascript labels:</p><pre><a class="expander" href="javascript:<span style="color:red">expand:;</span>"></a></pre><p>And we can target that via jQuery:</p><pre>$("[href='javascript:expand:;']").click(toggleAccordion)</pre><p>We can attach different behaviors to different ".expander" elements simply by using a different href:</p><pre><a class="expander" href="javascript:<span style="color:red">expandData:;</span>"></a>
$("[href='javascript:expandData:;']").click(ajaxAccordion)
</pre><p>So now we have a clean way of separating styling from behavior on an element, while making "javascript:void(0)" more informative for users and future maintainer selves.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-4121055019522169395.post-89239697005707702382012-05-16T09:42:00.001-07:002012-05-16T09:50:07.426-07:00On learning how to code, or whose life is it anyways?<p>So this drama started by Jeff Atwood about whether people should learn how to code or not still hasn't died.</p><p>The trigger for his post seems to be that some mayor somewhere ought to be spending his time doing mayor work and not learning things that don't necessarily help w/ his day job.</p><p>The thing is, even if he gets paid by tax payers to do his job, it doesn't mean he must do it at all times of the day. Lots of coders go home after work to learn about things like photography or martial arts. And not because they are actually trying to get photos published in a magazine, or actually going into real combat.</p><p><a href="http://sachagreif.com/please-learn-to-code/">Some are advocating everyone should learn how to code</a>, but that's a bit like saying everyone should learn English or Mandarin under the logic that it opens up a whole lot of business opportunities because of the whole global economy thing. Sure, there are many things that are probably worth pursuing if we had infinite time, but since we don't, just let people pursue whatever the heck they want to.</p>Unknownnoreply@blogger.com0