widgets for third-party sites

July 4th, 2011

For the past couple weeks or so I’ve been driving myself crazy researching the ways people are developing widgets to run on other people’s sites. I’ve been writing and rewriting the same piece of JavaScript on the daily as I find new information or start to doubt the information I’d decided previously was The Right Way. Though a big part of the problem has been the 90 gazillion blog posts and presentations tackling the subject in whole or in part, I thought I would write down what I came up with. Mostly to get some feedback on it, but also just to kind of collect that research and its outcome.

General structure

This was the part that I found the least information on, and I don’t really get why that is. If you have this piece of code running on someone else’s site and you don’t have concerns about where the HTML or the CSS or the data is going to come from, my understanding of modern terminology leads me to believe that what you have, sir or madam, is a plugin. Anything bigger than a plugin needs other stuff to support it, and unless you want to manage all that stuff as long-ass strings in JavaScript, I’d assume you’d keep it in a different file.

However, your buddy with the third-party site probably did not ask you to add as many extra requests as possible to the loading of the page housing your widget. It seems like minimizing the number of times your widget goes and gets other files or objects from your own servers would be a primary goal. The way I’ve decided to handle this is to err on the side of efficient requests where possible and to make a bunch of requests where I don’t see a good way around it. Specifically, the static data – HTML and CSS – lives in its own files on a node server, but when the third-party site requests the widget code, the contents of those files get added to the JS as variables. Data has to be collected separately, but I’ll get to that..

The HTMLs

I’ve seen a lot of people who seem to be suggesting that when your widget calls for data, it should get it already wrapped up in its HTML, which I hate. It’s just a little more processing to run pure data through a template, and it allows the consumer of the widget the option of easily switching out the markup if you expose a config property that provides a path to a customized template. Because creating a view model on top of the pure data seemed like a giant pain in the ass, I used John Resig’s Micro Templating. It’s small and efficient, bakes in caching of the templates, and allows enough logical flexibility to cover pretty much any need.

Configs

The widget I’m working on needs a good deal of setup info. Not only does it need data corresponding to anywhere from 1-n different objects, it needs to be able to find the places where those objects are rendered and be able to choose among a few options for how the widget itself will get rendered. It also needs normal widget stuff like an API key and all that. This adds up to one big-ass config. Asking the consumer to append all that data to the querystring that loads the widget code is possible, but seems awfully fragile to me. Better that they just keep it in a big object literal and the widget goes and finds it once it’s loaded. However, because all the config data isn’t part of the additional request, we have to deal with complicated cross-domain messaging issues when we do get the data, instead of the data being pre-loaded like the HTML and CSS.

Cross-domain stuff

By far this seems like the piece of the equation with the most information and the least clear answer. There are a few simple, modern ways around the cross-domain problem, but they only work with newer browsers, and IE, in a move surprising 100% of no one, has decided to implement their own version of the standard in their newer offerings. I actually made a flow chart trying to describe the choices to be made in picking a solution stack (and a stack is what you need, unless you somehow can manage to only support WebKit) that seemed to get some lulz, so I assume it’s close enough to accurate to at least be funny.

Because I need to send and receive a decent-sized chunk of data, but had the option to break it up into smaller requests/responses, I ultimately decided to use CORS and JSONP where CORS was unsupported. Previously, I’d ultimately decided to try and send/receive all the data for however many objects the widget needed to be rendered for at once, but I was skeptical about fitting all that in the URL of an iframe. So now I make one request per object and that seems like the best solution for making good use of resources and maintaining my sanity. I looked into easyXDM, but it seemed to me in reading the docs that I was going to need to manually manage all the same fallbacks, just accessed through a nice clean abstraction. I may have misunderstood that, but once I figured out how I could accomplish my goals without reading the documentation necessary to understand how that tool works, I decided to just try to get it done DIY-style.

External libraries

I had a fun debate with some friends on twitter about the merits of using jQuery vs. using a microlibrary or something completely hand-rolled. My point about jQuery was that there are decent odds that the third party site would be using it or that the end user would have it cached. I still think that’s true, but I needed so damned little of it that it seemed better to just write a couple of custom functions to do things like get elements from selectors. The totally efficient thing to do would be to make the signatures of those custom functions match jQuery or some other common library so that I could easily switch between them, but the code has to get loaded either way and now I have no external dependencies. Although I did copy and paste other code, like Micro Templating, into my widget code. That feels icky, but also efficient.

Lots of thinking for very little processing

I still feel weird that so much frustration went into this project, because it actually does so little. The external site calls the node.js server, which responds with the widget code and the static files embedded within that. It iterates through the objects defined in the config, makes its request to get the data for each, runs it through a template, and inserts it into container defined in the config by either a class name or an ID. The init() portion of the code may be the smallest piece. Did I do that right? I have my doubts, but I’m also not sure what I’d change. If you have comments, I’d love to hear ‘em.

no country for old hackers

July 1st, 2011

This was actually a presentation that I was hoping to submit to a conference I really wanted to speak at. The reason I didn’t ultimately submit anything is the same as the topic of the presentation/post, in part. How’s that for meta? And since I’ve been thinking of it as a presentation, I’m just going to write it like I’d say it. Sorry if that’s weird.

Who here would consider themselves an old hacker? Who’s here reading this because those words resonated? Some of you, I hope, or this might not make any sense. If you’re a web developer, calling yourself an old hacker is kind of ridiculous, in the scope of computer programming as a whole. But, relatively speaking, I think we all know what that means. It means you tested in Mosaic. It means you had the lecture about how there was no upgrade path for IE5/Mac and therefore we were going to have to support it until the end of time. It means you’ve been guilty of table-based layouts and you had your mind blown by “To Hell with Bad Browsers” and then again by AJAX. Or maybe it just means you remember the browser wars and found it difficult to trust $ over getElementById.

At any rate, here you are.

I want to ask you something. I don’t want the answer you’d give in an interview, but the real answer. I want to know if it’s the same as mine. Why did you keep doing it? Web development, especially for front-end people, was fucking idiotic at the outset. Things like presentational attributes were a revelation. The whole world was in Times New Roman. The power of the web was less than the power of the manual lawn mower your parents had in the shed out back and were yelling at you to step away from the computer and get to work with. But you, you were on Geocities, or Angelfire, or some college server, or your own server, if your freak flag flew that way. You were writing HTML, even though HTML was giving you fuck-all in return. Why did you keep doing that?

True, at that point the web was young, and the only people on it were our people. It was exciting to be able to put something out there and know that anyone anywhere in the world could theoretically end up seeing it. This was before endless privacy debates about whether google was stealing our thoughts – at the time, it was amazing just to have a platform.

Magical though it was to participate in that, at least for me, sticking with it ultimately came down to something else: the mythical wild west of computer programming. In college I had to read “Where Wizards Stay Up Late” and though that book is a little long on facts and short on poetry, the picture it painted was something I very much aspired to. At the time, I didn’t know there was an alternative. Without knowing it, I was used to doing cutting-edge shit by that point, because the only coding I’d ever done had been front-end web dev. We’ve since disavowed tables for layout, with good reason, but think back for a second on how much it changed when you realized everything didn’t have to be laid out in a single column, before float, when <br> was your only tool. That, my friends, was a hack. A messy one, but one that served us well at the time, and one that allowed our field’s better half, web design, to progress despite the available tools. Best practices were an extremely science fiction-y joke. There were few rules and endless constraints. If you wanted something, you had to go out and kill it for yourself.

Maybe you think it’s irresponsible of me to romanticize that era. After all, it produced little of lasting quality and we spent years weening ourselves and our superiors off those bad habits. It’s not the habits I miss, though. It’s the fun. It’s the discovery. It’s the hacking shit together and hoping it holds.

So this is why I didn’t submit this proposal. This is the question I’m scared to ask. What today offers that same unlimited potential? We can make shit that would’ve been unimaginably awesome to our 17-year-old selves, but everything’s reversed. We have plenty of (good, useful, valid) rules and very few constraints. The shortcuts have signs telling you to stay on the path strapped to chains that prevent you ignoring that good advice. There is always a right way. The west has been won, the territory has been discovered and cartographed and gentrified. And we benefit, certainly. The web benefits. The world benefits. Everything got better when JavaScript libraries started popping up. It got better again when browsers began implementing native features to do the shit we used to hack together. But now what do we do with ourselves?

I spent about a year being really, really mad at A List Apart. I used to wait for new issues to be published to see what the next FIR or sliding doors would be. And then, at some point, every issue was about content editing or UX. It took me a while to get it: what else were they supposed to write about? They led the charge and they won. We won. Once everyone started agreeing, we stopped needing hacks. We stopped reading PiE and ALA and we all went and downloaded jQuery. Then we stopped downloading jQuery and started downloading microlibraries cause, shit, everything’s native now. It’s strange and lonely to find that no one is arguing with you anymore.

I suppose ALA had stopped pushing the envelope because ALA’s bread and butter was HTML and CSS and that envelope wasn’t gonna be pushed no further. JavaScript, the toy language, had matured in the shadow of its siblings’ growth spurts and was suddenly very sexy. For me it remained sexy right up until CoffeeScript. And, if you know me, you know I do not mean CoffeeScript replaced JavaScript in my affections. I heard Brendan Eich talk about hopefully implementing pieces of CoffeeScript in JavaScript at jsconf and my heart just sank. If you straighten JavaScript’s nose and give it Lasik and put it on that paleo diet it’s not going to be the same sexy language I fell in love with. Metaphors aside, my heart sank because you can’t say anything to dispute CoffeeScript. Obviously there’s nothing wrong with making a language easier to write. The same as with Haml or SASS, no one’s making me use it. But I can’t pretend it doesn’t kill me that the most exciting thing we can think of to do with JavaScript is to clean it up to appeal to people who don’t like JavaScript.

Obviously there are still interesting problems in JavaScript beyond all those terrible little curly braces. People are doing great things with movies and animations and that’s awesome, but the field of real world use cases is pretty narrow. Node.js is fucking stellar and I love it, but it’s still server-side and it’s just not the same when no one’s ever going to see your mistakes. The bulk of the interesting problems I see right now are how we compose various off-the-shelf pieces. We move so fast, with such immense power, that it’s almost unreasonable to stop and figure out how to do these things for ourselves. In your free time? Sure. Yeah, go and rewrite the entirety of YUI or something from the ground up just for the joy of thinking about it, all on your own. As an answer, that’s almost cruel.

And that’s just the libraries and the language. What about the browsers? Imagine you did think of something in JavaScript that had yet to be coded, some essential hack that was missing from our libraries. How long would that remain relevant? All those placeholder polyfills are destined to become the latex jellyfish washed up on next year’s beaches. Our hacks are only a slightly faster solution than sitting and waiting patiently.

I’m not saying I give up, but when this entire landscape has changed completely, I’m going to miss it. I think domestication has become inevitable. Unless the web fragments again, and it’s once more us against them, I think we’re on the road to efficient and productive normalcy. Which is great in almost every way except that it’s just not as fun. The web is on its way to becoming a commodity. That awesome Wilderness Downtown thing that Google did? That was super cool. CPU fans all over the world were very, very excited about it. But my boss has yet to ask me to implement it on our site. We live for demos and proofs of concept. We go back to our dayjobs and implement someone else’s boilerplate, skip the unnecessary syntax, run the unit tests, push to the cloud and clock back out. It’s not really that black and white, but it’s never gonna be the same.

I haven’t given up. I just wonder sometimes how long we’ve got before we all have to stop being hackers and be software engineers.

separation of concerns is a bunch of bull

June 24th, 2011

A couple days ago I was booking myself some air travel. I finished filling out all the forms and submitted my payment info and finally it dropped me on the confirmation page. The confirmation itself was tiny, and the rest of the page was taken up by hotel offers, several of which were stupid expensive for non-business travel. Most were in the $100s, but one was $239. The full header text on the hotel module read, “only $239 more per night” and that 1) seemed like a fucking nonsense way to describe $239, and 2) got me thinking about templates.

I don’t know how the travel site does their templates. Probably on the server, since that’s the way most sites still do them. It doesn’t really matter, though, whether it’s client-side or server-side. There’s an opportunity to not say “only $239″ and instead say “on sale for $239″ or “a hell of a deal for $239″ or something that sounds slightly less ridiculous and emphasizes that the hotel’s best feature is not its price but like the twice-daily full-body massage and salt scrub you better get for $239. However, to do something like that would mean introducing extra logic. Not logic about data, like is this price part of a sale that will expire halfway through the user’s stay, or is this hotel also right by a convention center, but logic about how the data is displayed. So I can kind of sympathize with whoever did not put something like that into the template for the hotel module, because that particular grey area gives me fits.

As part of trying to push client-side templates down everyone’s throat at my last job, I started relying heavily on the concept of a view model – an additional layer between the template and its data that prepares all that data to be rendered. And I loathed the sort of things I was creating properties for in the view model, things like the plural form of words or what text to display if some array of objects was empty. Mostly, I loathed the fact that no matter how many fucking view model properties you create, at some point, if you want to keep your HTML in your HTML, you’re going to have to put logic in there and that’s just that. I loathed the feeling that trying to do a sincere and thorough job of “separating concerns” was tantamount to pushing a big damn boulder up a steep hill.

I have been doing this computer science shit for a long-ass time. I studied it in school for four years. I cannot think of any real world system I’ve seen in that time that achieves perfect separation of concerns. I posit that the reason for that is that separation of concerns is bullshit.

Hundreds of years ago, our superstitious ancestors would tell their willful offspring stories about monsters and demons to try and trick them into behaving in a way that an admonishment to be careful alone would not. Separation of concerns, I think, serves much the same role for developers. As a concept, it keeps us in line and without that principle our code, collectively, would without question be much more fucked. For the most part, we stick as close as we can to the protection separation of concerns offers us from the giant scary “these concerns are not separate” boogeyman who lives in the forest. But, y’all, there is no concerns-not-separate boogeyman. There is only trying hard to write nice code, or not.

Back to templates. If you count all the client-side templating engines you know of, I bet you run out of fingers. Most of them do the same thing, so why are there so goddamned many? I blame the separation of concerns mythology. Everybody wants a damn logicless templating system and as far as I can tell, no one has managed to invent one or will ever manage to invent one. The ones that describe themselves as logicless continue to have basic operators that perform logical tasks. The ones that do nothing but plug in properties or the output of functions merely necessitate the offloading of all the logic to an additional view model, and since they can’t function without that piece of the equation, I’d say they still fail to be logicless. HTML is your logicless templating engine. As soon as you begin adding dynamic information, you can kiss logicless goodbye, because logic is where dynamic pieces of a display come from.

I’m not saying that you can’t abstract every piece of display logic out into a view model. You absolutely can, and I will totally come bring you flowers in the nuthouse when you get all done with that. But you don’t change anything in doing so. One argument people like to make is that removing logic makes it possible for non-developer designers to work with the HTML, which is – sorry guys – horseshit. If your designer understands the best practices of good HTML, if he or she can do the necessary pattern matching and visualization, he or she can grasp what is template syntax and what is not and move those bits around and not break them, etc. If he or she does not, you’re going to be adding the dynamic data after they put their HTML together in Dreamweaver anyway.

There are a few template solutions that try to get around this problem by avoiding template syntax altogether and just using existing attributes of HTML. As far as I’m concerned, that’s the same damn thing, just as fragile and problematic, only with the additional penalty of having all the template infrastructure continue to exist in the final rendered product. If your designer can fuck up a template tag, they can fuck up a CSS class or data attribute.

So here’s the thing. The concerns that we work so hard to separate are intrinsically linked. It’s not impossible to abstract them away from each other, but they still maintain some awareness of each other. The view – the HTML – cannot be separated from the data in contains. It’s not an empty vessel that can be filled with anything, it’s marked up to have semantic meaning and an appearance that increases the utility of the data displayed. You show me a completely dumb view and I will show you an interface that fucking sucks. There should be logic in HTML, if the HTML isn’t static. It should react to its contents and show different things in different ways. When the changes are big, hell yes, create different templates and let the controller determine which to display. But I firmly believe that, when you get down to things like replacing the word “only” with something that makes more sense, trying to achieve perfect granularity is going to make you crazy and offer very little payoff.

Something that is “only” $239 is not a different type of object than something that is “on sale for” $239. It’s not in a different state. It’s stored in the same table in some database. The same type of object carries it around on the backend adding properties to it. It’s delivered to the client with the same JSON structure. It’s displayed using the same markup and the same styling. The only difference is a couple of words, words that don’t affect the data, that have been pulled out specifically for the purposes of display. Why not let the fucking template handle that? There are plenty of other places that logic could go, but ultimately it’s a view model or the view itself. I’m tired of adding tiny little things like that to view models, or worse, creating view models specifically for them.

Separation of concerns is a fantasy. It’s a very useful fantasy that guides us to produce better code, but like all fantasies it’s still fundamentally bullshit. From now on, when the only reason someone can give me for doing something or not doing something is, “But separation of concerns.. !” I’m going to start calling that what it is.

nested callbacks in jquery begone!!

June 1st, 2011

A week or two ago I noticed a bunch of people having trouble because of their nested callbacks, or with flow control in general, in jQuery. I said something about this on twitter, saying people should use jQuery’s Deferred object, and several people commented that Deferred is a really difficult concept to explain. I kind of disagree. Or rather, I think the difficulty comes from how we’re trying to explain it. So I wanted to share my experience, which begins not with “Oh jQuery has this new cool Deferred thing I guess I should go figure out WTF that is,” but with me doing lots and lots of nested callbacks.

I had this application that needed to send a bunch of updates to the server, and then redraw. The structure of the data being updated was sort of like object.rows[n].images[], and all those pieces – the parent object, each of its rows, and the images for each row if present – had to be updated via their own API calls. So the code looked sort of like this:

app.saveObj = function(obj) {
	obj.rowsToSave = obj.rows.length;
	$.post(someURL,obj,function(data) {
		$.each(obj.rows,function() {
			var row = this;
			row.parentId = data.id;
			obj.imgsToSave += row.imgs.length;
			$.post(otherURL,row,function(data2) {
				$.each(row.imgs,function() {
					this.rowId = data2.id;
					$.post(uploadURL,this,function() {
						obj.imgsToSave--;
						if (obj.imgsToSave == 0) {
							obj.rowsToSave--;
							if (obj.rowsToSave == 0) {
								app.renderObj(obj);
							}
						}
					});
				});
				if (row.imgs.length == 0) {
					obj.rowsToSave--;
					if (obj.rowsToSave == 0) {
						app.renderObj(obj);
					}
				}
			});
		});
	});
};

Or something like that. That’s essentially pseudo-code, and I know there were lots of functions that abstracted certain parts of that out, but it was more of less like that. I know there was some goofy shit with passing references to parents and parents-of-parents around in the callbacks, and those counters were definitely in there (unavoidably, I think). That’s nuts. At the time I’d never heard of deferreds or promises, and I thought flow control was a feature of shower heads. But even totally ignorant of the real solutions, I knew enough to feel immensely dirty about my own.

I think there are a lot of people in that same boat right now.. There are a couple different solutions that I learned about along the way, but if you’re using jQuery, the Deferred object is kind of the most obvious. I formed that opinion thanks to these resources, which you should totally check out if you haven’t:

(Ordered by when I saw them)
Rebecca Murphey’s post Deferreds coming to jQuery?
Eric Hynds’ post Using Deferreds in jQuery 1.5
Dan Heberden’s jqcon presentation Deferreds – Putting Laziness to Work

Looking at the mess of code above and knowing what I know now, here’s how it could be rewritten to be somewhat less shameful:

app.saveRows = function(obj) {
	var d = new $.Deferred(),
		count = obj.rows.length;
	$.each(obj.rows,function(i, row) {
		row.parentId = obj.id;
		$.post(otherURL,row,function(data2) {
			count--;
			$.when(app.saveImgs(row))
			.then(function() {
				if (count == 0) {
					d.resolve();
				}
			});
		});
	});
	return d.promise();
};

app.saveImgs = function(row) {
	var d = new $.Deferred(),
		count = row.imgs.length;
	$.each(row.imgs,function() {
		$.post(uploadURL,this,function() {
			count--;
			if (count == 0) {
				d.resolve();
			}
		});
	}
	return d.promise();
};

app.saveObj = function(obj) {
	$.when($.post(someURL,obj,function(data) { obj.id = data.id; }))
	.then(app.saveRows(obj))
	.then(app.renderObj(obj));
};

I don’t want to present this as though it’s super elegant or a magical solution. It’s actually more lines of code and, as far as I know, the stupid counters can’t be gotten around. Yeah, $.Deferred.resolve() is basically substituted for calling the callback. On the other hand, it seems much cleaner to me than the fake example, and you’re just going to have to trust me when I say that it’s worlds cleaner than the code I actually wrote. Mostly, it’s sustainable. The callbacks wait neatly chained for the event that indicates they should be called instead of being carried around through nested function call after nested function call (though the first example is condensed, that’s essentially what’s happening there – keeping the anonymous callback functions inline just makes it appear more connected).

I just fixed the front page of this site after a year, and added in deferreds to help manage some nasty bullshit with animations (not my strong suit) getting messed up if the animation function was called again before it had finished. I had two concurrent animations running each time I wanted to “flip a page”, and then they both had a couple of cleanup things they’d do upon completion. Now that list of final tasks happens only once both have run, and it’s out of the callbacks and nicely chained. It’s readable and consistent. As before, it’s not really solving a problem for me – the bug with the animations was related to a variable changing by the time the callbacks ran – but it makes for better code.

For me, the difficulty in understanding deferreds came in realizing that they aren’t magic. JavaScript only works this one way, so you still have to be able to think of your code in terms of, “I need this to happen and then I need something to trigger a different thing.” You have to map out the dependencies in your head or on paper and figure out the places where you need to wait. To me, nesting and passing callbacks has always felt conceptually like a lot of overlapping loops, loops that get paused part of the way through and then your app has several levels of functions waiting to move forward. I like deferreds because they make those feel more separate. Do this thing, and only once it’s done, begin this other thing. Under the hood I assume it’s still just passing around references to functions, but deferreds are a much easier way to think about this stuff.

So anyway. If you’ve also been waiting to grasp the nature of the problem deferreds magically solve to look into them them, you should stop. You should also stop nesting and passing around callbacks. It’s difficult to read, it’s difficult to manage, and it scales just like shit. I’m not really the best person to be talking about this, but I can say fairly confidently that deferreds offer an improvement. And, you know, maybe there is a magical solution somewhere in there that I just don’t know about yet. If you find one, you should tell me.

things that actually matter

May 8th, 2011

I had just gotten some very relevant facts about this and was about to update with corrections, when Alex Sexton posted his comment below. Please scroll down and read that before taking this without a giant grain of salt. I definitely jumped to some incorrect conclusions, and he’s got the real story down in the comment section.

I was really disappointed to see that jsconf is now the most recent “incident” on the geek feminism wiki. If you’re not familiar, that wiki collects things like sexual assaults and jokes about things being so simple even your mom could do it. That is, damaging and insulting shit. I may catch a lot of hell for this, but I didn’t find the presentation that happened during lunch on Monday at jsconf sexist. I assumed the guys presenting were trying to call attention to the lack of women at the conference in a humorous way. It definitely ended up being awkward, but my impression was that their hearts were in the right place. As for the thing about homeless transvestites, I admit I was only half paying attention, but I don’t think it’s unreasonable to simply mention homeless transvestites. Homeless transvestites exist. Anyway, someone explained later that the homeless transvestite thing was part of a botched anecdote about one of the presenters getting flashed, which had the potential to be a funny story.

However.. jsconf and nodeconf were the first two conferences where I’ve ever actually felt uncomfortable as a woman, and neither had anything to do with grade school humor onstage. This is why it fucking annoys me that what gets blown out of proportion on the internet is “OMG someone was mentioning women by name”. That’s not something anybody can do anything about now. If you saw the presenters afterward, it was pretty evident that they felt awful about it. I’d like to talk about shit that can actually be corrected, and I think it’s going to be a lot less well received than “don’t make jokes about how there aren’t enough women at this conference”.

“Are you a wife, or a girlfriend?”

Admittedly, I haven’t been to a whole ton of technical conferences. However, jsconf was the first I’ve ever been to where anyone assumed upon meeting me that I was there to do anything other than learn about tech shit. And – with apologies to any of the organizers or anyone else involved who may read this – I blame this on jsconf’s Significant Others Track. (Colloquially referred to as “the ladies”.) It was difficult for me to even purchase the ticket to my first serious technical conference because I was afraid I wasn’t qualified to be there, that I wasn’t good enough or smart enough. I don’t have any facts, but my guess is that a lot of women go through that, and it keeps a lot of women from ever attending a conference. But no one ever treated me as though I didn’t belong, until this week.

My impression was that the Significant Others were exclusively women (and babies), and that they outnumbered the women actually attending the conference. For me, this created a really upsetting dynamic where it was statistically correct to assume that any woman you saw hanging around the conference venue was not there as a developer. Good lord, it’s hard enough just mustering the confidence to attend these things. But generally, once you’re in the door, you’re safe. People know without asking why you’re there and there’s mutual respect among the attendees just for showing up. I shouldn’t have to wear a sign around my neck saying that I’ve been doing this for over a decade and paid a fucking grand to be there to be entitled to that default level of respect, to not be assumed to be there merely as arm candy. Filling a conference with women who are not developers makes it that much fucking harder to be a female developer at that conference.

I told a friend how I felt about this and she pointed out that the SO track makes jsconf more family friendly, and allows men who might not otherwise be able to attend to come to the conference without leaving their wives/kids/girlfriends behind. My opinion is that if you want to be family friendly there are better ways to accomplish that. If you just want men to be able to bring their families, nothing fucking prevents them from doing that at any other conference. Their SOs can still go tour all over the city while they do their important man stuff, assuming they’re homemakers or otherwise in the position to take a week off to go chasing after their man while he pursues his professional interests.

I was really not trying to hate on the SO track but, bluntly, I do hate it. I hate that there’s a special place for women at this conference and it’s not in the seats watching the presentations. I hate that, as many times as I’ve had to jump the fence between what a woman is supposed to be doing and what I personally want to be doing, I come this much closer to my goal – as far as where I want to be and the kind of developer I want to be – to find that same fence erected again where I least expected it. I hate that the comfort and community involvement of wives and girlfriends is more important than the comfort and involvement of female developers because we are outnumbered. But I’ll try to quit ranting and actually say something productive.

the perfect couples’ getaway

Rather than offer free SO track tickets, it would be super cool if jsconf/nodeconf offered discounted tickets to the actual conference for significant others whose partners had already purchased regular price tickets. Don’t think anyone would use them? Maybe not, but then what the fuck are they doing at a JavaScript conference? You want a family vacation, take a fucking family vacation. You want to interact with the JavaScript community, go and fucking do that. If you want your girlfriend to interact with the JavaScript community, buy her a fucking ticket. I did actually meet someone on the SO track who was interested in front-end dev, so there. She was already a developer, just not working with JS. While I’m sure there were plenty of women on the SO track with no interest in dev, I’m betting there was more than one with the aptitude and motivation to have actually gotten something out of the conference itself.

In a pretend world where something like this would exist, it would be really awesome. Yeah, any woman who took advantage of it would have to get over the whole arm candy stigma, but it’s a lot easier to go to a conference if you know someone there. If that someone has to be a husband or a boyfriend, it’s better than nothing. We need more female developers so we don’t keep losing female developers due to the lack of female developers. As far as I’m concerned, anything that gets ‘em in the door is rad.

what about the children

I had a really interesting conversation with a friend at jsconf about getting kids into development. I had another conversation with another friend about how daycare would be a lot more inclusive than an SO track. At some point these ideas merged and I began wondering why jsconf doesn’t have a kids track. There were certainly plenty of kids there. I guess you’re probably not supposed to take your kids out of school for a week so they can go to a JavaScript conference, but what if you could? What if young kids were learning how to make a simple webpage while their folks were learning about collision detection and unit testing? What if single parents could attend as easily as dudes with wives? What if people could trade a couple hours watching babies or teaching kids for a free jsconf ticket? I think that would be fucking awesome.

I guess this goes back to the big thing I don’t understand, which is why, if jsconf is supposed to be a family event, there aren’t family JavaScript activities. With the amount of talent present and given that offspring of developers are going to grow up around development anyway, it seems like a natural place to teach kids fun, simple development shit. It’d be like the best bring-your-kid-to-work-day ever.

the ladies’ room is called that for a reason

Nodeconf was a complete sausagefest, but I don’t want to pick on them too much. As far as I know, there are no famous women within that community. There weren’t any female speakers. With no female role models, you’re just not going to see many women getting involved. The ground has yet to truly be broken there, but that’s not the organizers’ faults. (Ahem. Ladies.) However, there was one fairly wrong thing that happened. To their credit, it was corrected almost immediately, but it still kind of blows my mind it even happened in the first place.

Developers – male and female – can sometimes be more logical than is healthy, and I assume that it was in the name of efficiency that the women’s bathroom was relabeled a unisex bathroom, with a single stall reserved for ladies only. Like I said, I think the sign was gone before the first talk had ended, but it’s important to know why this was uncool. There were totally way more men than the men’s room could accommodate and so few women in attendance that I only saw another person in the ladies’ room once. But the ladies’ room is the one thing that’s ours by default. We had to fight to be taken seriously as developers, fight to get good jobs and interesting projects, fight to overcome the fear that we’re not good enough.. we shouldn’t have to fight for a bathroom without boy-pee on the floors. I feel like seeking out more diverse participants is an endeavor best left to more mature communities than node’s. But that doesn’t mean you can reclaim resources already dedicated to diverse participants if you don’t see enough people using them. It’s always good to keep a women’s bathroom around and work toward the day when there’s a line out the door.

I am so tired of talking about this

Something you might not know about me: I write approximately one women in technology blog post per month. I usually don’t publish them. I get angry and then, by the time I’m halfway through writing, I’m sick of it. This one is going to make it cause I think the stuff about the significant others needs to be said and I don’t think anyone else agrees with me and is going to say it. The bathrooms thing shouldn’t need to be said, but apparently folks need a reminder sometimes.

There was one thing about the lunchtime presentation at jsconf that bugged me. It wasn’t the things being said, but the way they were said. It felt as if the presenters didn’t think of the women at the conference as their peers, as being exactly like them in every way but their sex. I’m scared to talk about this stuff. I’m scared to isolate myself, to always be part of some exclusive third party my male peers have to tiptoe around when mentioning us. I would rather be down in the mud listening to dick jokes and #twss than be part of a group that’s on some pedestal where no one can talk about us or to us without complete political correctness and unfailing reverence.

I think with a slight shift, the lunchtime presentation could have been fucking hilarious (while also a little tragic). If they’d brought up a close female friend they knew they could fuck around with instead of a guy as their first “guest”, there could have been some very funny teasing of the giant elephant in the room. I think. It made me wonder if those guys knew any of the female developers there well enough to fuck around with them on stage. The change in tone when they finally did bring a woman up made me feel like maybe not, or maybe they did know her well enough for that but were worried about what the audience would think.

I no longer think the scrutiny we apply to this issue is healthy. I’m actually having doubts about the All-Girl Hack Night, based on this week. I’m tremendously worried about mentioning the bathroom thing outside of an intentionally-not-hashtagged tweet, lest that too fucking end up on the geek feminism wiki. We need to be able to talk about this shit without fear of repercussion. That means men, too. We need to be able to make jokes about it. We need to do this so we can stop fucking discussing it.

keyboards

April 4th, 2011

When I was in college, I worked in the computer lab. One of the very first things they told us during training is perhaps the best thing I’ve ever learned in my entire career working with computers: never touch someone else’s keyboard. It doesn’t matter if the keyboard involved is actually yours, and someone else is just sitting in front of it. You don’t touch it. This is a pretty good metaphor for anything that has to do with helping someone else solve a problem, even problems that don’t involve physical keyboards.

What they wanted us to avoid was something that’s sadly common among geeks – the tendency to push the other person out of the way and say, “Nevermind, I’ll fix it.” Maybe we sometimes think it’s more efficient if we just fix whatever the issue is. In that moment, we’re probably right. But that momentary efficiency creates long-term inefficiency by breeding helpless users, colleagues, clients, whoever. It’s also a total dick move.

I’m not going to say anything about the relative merits of teaching dudes to fish vs. giving them fish. We all know that. This is a post about the dick move part of the equation, and how that’s a big fucking problem among computer geeks to this day.

There’s always been this incredibly stupid yet romanticized picture of computer people living in basements, working in isolation, and getting things done the Good Old American Way, with no help from anyone. There’s been a tendency to treat developers and sysadmins and various types of geeks as heroes when they stay up all night and finally fix something (that probably wouldn’t have been broken if maybe they weren’t the only people working on the problem to begin with). There’s been a disincentive to collaborate and a territoriality that appears a hell of a lot like it’s driven by the fear that omg someone else may be better at something. And it’s all a bunch of stupid, useless bullshit. We know people, geeks or not, do better when they collaborate, when they aren’t afraid to be wrong, and when their egos take a backseat to their work.

What does that have to do with not grabbing the keyboard? Everything. Grabbing someone else’s keyboard is a physical and therefore very obvious way of demonstrating superiority. It implies not only that you know something the other person is ignorant of, but that your time is too damned valuable to waste it explaining it to them. It’s a lot like being that jackass who always has to shout out the answer to a question first and loudest before anyone else gets a chance to respond. Same goes for any time you don’t help someone understand the solution to a problem but instead take it upon yourself to fix it, whether or not input devices are involved.

I don’t spend a lot of time lately helping people save their files in Word. Mostly I spend my time working on code. And while this shit is annoying and rude when it’s explaining word processors, it’s downright fucking dangerous when it’s the codebase of a live product. If you’re a keyboard-grabber, maybe you think the joke’s on me. Maybe you think you’ve found an awesome way to ensure you’re always the most valuable person on your dev team by hoarding as much knowledge as you can. Maybe you think the long hours and late nights you spend fixing things you could have delegated are worth it. Hell, maybe you even think that because you’re the one who always gets shit done, you’re completely fucking awesome.

Well, you’re not. You’re being a total pain in the ass.

I’ve never been a keyboard-grabber. Don’t mistake that for horn-tooting, I go the opposite direction to a definite fault. I’m ashamed to contemplate how many hours I’ve wasted trying to force business people who just wanted to change the pictures on their websites to learn CSS instead of using HTML attributes because “this is better!” Being this way means that when I encounter keyboard-grabbers who I have to work with, I have a difficult time not trying to drag them to some kind of middle ground. Well, that’s a lie. I don’t try not to. I jump in there all, “Motherfuckers we are going to COLLABORATE. RIGHT NOW.” But whatever. In this case it’s worked out and what I was gonna say was how and why.

I think not fixing problems in isolation is scary for people who are used to being cowboys. For one, it spreads the value of your knowledge around, diluting the value of your personal stockpile. For another, you can’t control the outcome, and there’s the possibility that you may have to suffer through someone else not getting it for weeks or months, when you could have fixed the problem in a couple hours. But mostly I think it may be scary because you’re changing what you know works for you, and the value isn’t apparent. I don’t mean the value to the team, which I shouldn’t have to explain the immenseness of. I mean the value to you, professionally.

Somebody smart wrote somewhere that you should always try to be the dumbest person in the room. Being the smartest person in the room sounds good on paper, but the smartest person in the room isn’t getting any smarter, they’re just standing around looking pretty. The dumbest person in the room is learning shit without even having to open their mouth. When they do open their mouth, they can ask questions and not care if they make them sound dumb, because asking dumb questions is what the dumbest person in the room is supposed to do. If you set yourself up as the person with all the answers, who has to fix whatever’s broken and bless whatever’s imagined, you don’t get to ask any dumb questions. If nobody ever gets to be smarter than you, you never get any smarter. You can read shit on the internet and make little side projects with flavor of the month technologies, but unless someone’s actively challenging your assumptions, you’re learning less than you could be.

When you stop grabbing people’s keyboards and explain things to them so they learn it for themselves, you create intellectual antagonists. You give them the opportunity to be like, “But wait isn’t Way X bad and isn’t Way Z more performant,” and then you’re all, “What? Dude no Way X is The One True Way STFU and copy that thing over to there,” and then secretly you look it up and it turns out Way Z is totally better than Way X for some completely different reason and OMG THAT N00B JUST BLEW BOTH YOUR MINDS. This is absolutely the best thing ever.

I’ve been lucky enough to see a few hierarchies of smartness completely fall apart. It’s always really obvious when this happens, because beforehand everyone is just glaring at each other not saying anything and afterward nobody can fucking shut up about node.js or OOCSS or closures or whatever. You also get something that may seem anti-collaborative: healthy competition. You’re not waiting for one dude in suspenders and long, flowing robes to update your company blog, you’re all racing each other to push stuff to github and then filing issues and making pull requests and generally knocking each other’s egos down daily while also having a really fucking good time. Maybe that’s not how it always plays out exactly, but you get what I mean.

I said how and why, and that was the why, I guess. The how is shorter: stop grabbing people’s fucking keyboards.

too much jquery.. ?

January 30th, 2011

This weekend I tried to take part in a virtual MDN documentation sprint. I say tried because, while I was present in IRC for some part of it and submitted some updates, I don’t think I got a lot done. I changed a couple things that had been bugging me about the Rich-Text Editing in Mozilla page, but it turns out that more accurate information had existed the whole time on a different page, so that didn’t really add a lot. Having finished that one little thing and feeling not very helpful, I went in search of something else to do and saw an item on the sprint wishlist about updating the Getting Started with AJAX page. I was like, “Sweet, this is easy stuff, I can do that!”

HA.

I cannot, as it turns out, do that. Not without many hours of research. I used to be able to do that, but now I do this: $.ajax(...); I do it too much. I do it so much, in fact, that I no longer have any idea what current versions of browsers actually require to complete a successful XHR.

I’m not a jQuery hater – far from it. I use the shit out of some jQuery, I’m always trying to fix the ways I use it incorrectly, and I think it’s extremely handy. Initially I was no fan of it, but at that point I was categorically against any sort of JavaScript library. Once I started using it, I came to appreciate it very quickly, and once I began to appreciate it.. Well, that’s how we get to now, where apparently I can’t write fucking JavaScript anymore.

I realize I’m hardly the first person to be concerned about reliance on abstractions preventing front-end developers from having a solid grasp of JavaScript, but – pardon me, cause this is douchey – I didn’t think that applied to me. Having once had that solid grasp and having applied that knowledge on the daily for a few years, it just never occurred to me that I would lose it if I didn’t use it. I thought the people to be worried about were those who were new to JavaScript and, having started out with libraries, never learned the fundamental concepts. It’s now much more clear to me how stupid that was. Browsers change all the time (well, most of them). To believe that the correct way of writing JavaScript in 2008 is still the correct way to do it in 2011 is just ridiculous.

For example: when I was trying to update that AJAX document, one of the first things I did was to remove the word “nonstandard” as an adjective describing XMLHttpRequest. That took about half an hour. I was pretty sure it was standard, but I’d never really checked. I still don’t really know. The W3C has a document on it, but it’s marked “Candidate Recommendation”. Does that make it standard? Does the fact that modern browsers have implemented it in a standard way make it standard? Is it not standard until all the browser-specific caveats have been removed from the implementations? Not only was I unfamiliar with the state of those caveats, I didn’t really know the disposition of XHR as a standardized concept, and still am not 100% confident in my research on the subject.

And dude, that is sad. I extol the virtues of XHRs at work constantly, in every planning meeting, in every design session. I’m like one of those people on twitter who talks about how awesome Justin Bieber is even though they’ve never met him. I am a creepy XHR stalker/fan who’s based her devotion on an impression that leaves out much of the detail. No one who likes to present herself as a professional front-end developer should be doing that.

So, having realized this, what do I do about it? This is the rub. Probably the best way to maintain a good understanding of JavaScript is to be a library author. I don’t mean add another publicly released library to the slew of excellent ones already available, but write internal libraries, creating the same abstractions that I’d normally depend on jQuery or any other library to provide. But that’s a little ridiculous. I do write a lot of my own widgets, but that’s just because I don’t want all the options and config stuff that come with a big, complex, do-everything plugin someone else wrote. Abstractions like jQuery’s ajax() are more universal, because they simply wrap a standard* up in a shorter function call. It’s good that people can rely on that stuff being in the libraries they use and that that knowledge is useful across a variety of projects. It’s probably pretty dumb to create a new XHR abstraction for each new application one works on.

Maybe it’s obvious that I’m not sure what to do about my JavaScript knowledge getting stale. I’m not into doing things just to prove I can, but in this case, I’m not sure what would be a better approach. Part of me thinks there may not even be a benefit to staying current on the implementations of common, slightly mundane things like writing out an XHR long-hand. I don’t know anyone (aside from library authors, who I only know of) who does their work in plain ol’ JavaScript. I like to believe we’re moving back to that, though. I always picture jQuery et al as projects that exist to hasten their own obsolescence. Maybe that’s crazy and, as someone who merely implements this stuff, I should just embrace the fact that I’m losing the right to call myself a JavaScript developer in exchange for the security of not constantly reinventing the wheel.

there were about ten women at hack night tonight. it was awesome.

January 25th, 2011

To tell the truth, I had zero interest in going to hack night tonight. I spent the day working from home, even further isolated from a team who’s already all the way in New York, with no heat or hot water while backhoes drove around outside my window, dudes clanged pipes together under my house, and my tile guy tried to explain to me why the tiles at the edges of my bathroom weren’t going to be able to be set. I was tired, beaten-down, and I just wanted to watch Netflix and fall asleep. Luckily for me, I’m the organizer of the hack night, it was my fucking idea, and I was obligated to go despite my shitty disposition.

It was awesome.

Around 7:15, I gave up on any more people showing up. We had around twenty RSVPs and there were about half that number of women there. (In hindsight, it occurs to me that both Refresh and Austin JS were also unusually small this month, but it didn’t then.) I was briefly disappointed, cause we gained two new sponsors this month – Windows Phone 7 for snacks and drinks, and TabbedOut for our awesome venue – and I wanted to show them that their support wasn’t wasted. But you know what? Even with only a small turnout, it wasn’t wasted at all.

What happened, despite the room not being completely packed, was that we spent several hours doing nothing but talking. I think perhaps one woman got any work done. Sounds bad, right? Sounds like the beginning of one of those ridiculous analyses where they say women aren’t as productive because of their inherent social drive? Consider what we talked about:

  • CodeIgniter
  • CodeIgniter vs. Drupal
  • CodeIgniter vs. MS WebMatrix
  • MS Web Matrix vs. PHP
  • PHP vs. CodeIgniter
  • iOS development
  • XCode
  • Android development
  • Eclipse
  • MonoDroid
  • PhoneGap
  • curl
  • the HTTP spec
  • the W3C
  • the HTML5 logo
  • the evolution of web standards
  • IE6-only intranets
  • redis
  • CouchDB
  • noSQL vs. RDBMS
  • more stuff I can’t even remember

Which is to say, we had one of the best technical conversations I can remember having in quite some time. It wasn’t constrained to a single discipline and it wasn’t limited by showboating or competitiveness. Everyone at the table was teaching everyone else all the cool stuff we wanted to know about. Someone would ask, “what about _____?” and someone else would pipe up with her experiences with it. And we just went on like that for several hours. I had to demand that people remember to drink the drinks and eat the snacks because everyone was fixed at the table, jumping from technology to technology as fast as they could digest the information.

Seriously, it was awesome. I don’t know how to force that to happen again, but I know that I’m more excited about this group right now than I’ve been since the first time we met. I hope we do a lot more of this.

a wishlist for contenteditable

January 5th, 2011

For the past month, off and on, I’ve been working on this text editor. It’s basically functional now, and I stand by my assertion that building bespoke text editors with contenteditable is a worthwhile consideration for sites that need minimal editing options. I even managed to add spell-check. That feature’s only available in IE (I’ll get to why), but that’s fine since built-in spell checking is now the norm and most other browsers include it. However, working this closely with contenteditable has given me a real clear picture of its shortcomings as implemented now, what things I really wish were standard, and what standards I wish browsers were currently equipped to support.

wrap a selection with arbitrary HTML

Initially, formatBlock sounds very promising. Mozilla’s excellent designMode command documentation says developers can use this command to wrap a selection in almost any block-level element. Sadly, those block-level elements, in practice, wrap the entire line that contains the selection instead of separating it out and moving the selection and its parent to a new line. This is in keeping with the behavior of insertUnorderedList, for example, but is annoying because this command doesn’t work any other way. The MDC docs offer em and button as examples of tags you could potentially insert, but in my tests those failed and execCommand returns false. Read a little further in Mozilla’s documentation and you’ll find that IE supports an even smaller subset of HTML tags, which barely even matters because wrapping HTML around a selection is already only useful in such a small number of cases. This pretty much rules out advanced editing or truly being able to use contenteditable to edit a webpage.

wrap a selection with a CSS class

With the exception of IE, browsers carry out commands like bold or italic by wrapping the selection being acted upon in a span with inline CSS specifying the formatting. Wrapping selections in spans (or fonts *cough-IE-cough*) with a class assigned instead of that inline CSS should be pretty easy, but the option just doesn’t seem to be there. I’ve looked. Again, even if you’re of the school that believes contenteditable is just for editing webpages and not for rich text editors or other vulgar uses, this seems like a necessity. It’s not reasonable to expect to offer enough diverse HTML tags that editors will be able to produce whatever functionality and styling they need without having that class for JavaScript and CSS to use as a hook, especially when the tags contenteditable produces differ between browsers.

a designMode command to create a selection

So we don’t beat up on IE too much, I’ll mention right away that IE does have this, and it works pretty well. This, as a matter of fact, is the secondary reason that my text editor ended up only supporting spell check for IE. IE has a command, findText, that takes a string and looks for it in the contenteditable area. This came up prior to the spell check when I was trying to help our automation engineer figure out how to programmatically mimic selecting some text and clicking text editor buttons to format it, so I had to find a solution for Firefox as well. It’s super elegant. You ready? We wrapped the text to be selected in an <i> and used range.selectNode to highlight it. Had this not been automated, that wouldn’t have worked, cause you can’t just type HTML into a contenteditable area, we would’ve had to calculate the offset and length of the selection within it’s containing node or textnode. FYI, once you talk about selections spanning one or more nodes, that ceases to be any fun. It would be great if other browsers would support findText.

my cursor? please?

There’s some strange intialization most browsers seem to require in a contenteditable area. Firefox, for example, will allow you to click into the area and type normally, but you don’t get a cursor until it’s added the <br> that I guess lets it know the area has changes. I’ve been experimenting with various kinds of placeholder text – because putting so much as a space inside the editor allows any browser to click into it normally – but everything I’ve tried is a little screwy. It would be much nicer if offering to let the user create a new text node were a browser’s default behavior in an empty contenteditable area.

for mobile webkit to support it

Or, at least, if mobile webkit is not going to support contenteditable, for it to quit pretending that it does (feature sniffing for execCommand doesn’t work – webkit claims everything is peachy). Clicking into a contenteditable area doesn’t bring up the user’s keyboard. Links within the area continue to function as links, no matter what kind of JavaScript I’ve applied (this may be because I suck). It appears that in mobile webkit all child nodes of the contenteditable area inherit the same bizarre implementation of contenteditable the parent has and become useless buttons. Which is to say, you can attempt to move your cursor into the middle of a text node and instead the text node will be highlighted and you will not get a cursor of any sort. From what I’ve read online, this is a very vexing problem for the developers of these browsers, but I really hope they’re able to figure it out.

for more consistent results

Guess what fontName, fontColor, and fontSize produce in IE? A span with its style attribute filled with font-family:'Comic Sans MS';font-size:70px;font-color:#f0f;? Nope! Give up? It’s font tags! Just like 19-fucking-96. I have not yet installed IE9 because for a long time I didn’t have Windows7, and then I did but I’d stopped caring. Maybe IE9 fixes this. But we all know it’s going to be another decade before IE9′s older siblings go back to the primordial tar pit they crawled out of and until then, using built-in designMode formatting commands means that your user generated content has motherfucking font tags in it. There’s not a lot that can be done about the other browsers and their inline CSS, but my personal wish is that browsers will implement some reserved classes (e.g., .agent-format-italic or something) and attach those instead. Probably best to just be happy that most browsers are using spans, though. But, IE? That font bullshit? Not cool, buddy.



You may feel like this is awfully complainy for someone who started this blog post declaring her modest triumph over this same technology. Like I said, I still think this is loads better than having to download and customize someone else’s editor. But to get my very simple one working, I’ve had to employ some dirty tricks, and that’s the only thing that frustrates me. To wit:

  • Browser-sniffing to get around mobile webkit
  • Wrapping misspelled words in font tags because I can’t use classes or arbitrary HTML
  • That nasty business with selecting text in Firefox I mentioned
  • Having to go through the hidden textarea to strip out HTML comments because either innerHTML or contenteditable won’t admit they’re there
  • Having to insert hrs before and after pasted text so that I can find it and clean up the markup
  • Generally bringing shame upon my family

So I guess let that serve as a warning to you if you decide to go down this path. Although I wish contenteditable were more mature and more standardized, I’ve also had fun working with it. Since we all got JavaScript frameworks and HTML5 and CSS3 support, it’s getting rarer and rarer that it’s necessary to hack something. Dirty and shameful though it’s been, it’s also been interesting.

making a really simple text editor

December 10th, 2010

A few months ago I started thinking I should write my own text editor. Not because the existing options were bad, mind you, but because they were too much. At work, we take a lot of user content. This content gets displayed on pages that aren’t designed to support font colors, images, tables, etc. Yet it can get long, and it’s nice to provide people the ability to bold or italicize their text, to break it up with numbered or bulleted lists, and to add links instead of pasting in URLs. All the existing options handle that use case just fine. But the overhead – both in terms of file size and in terms of time to configure – was starting to get to me.

This week, I finally went and wrote my own solution. It’s still a work in progress but, having waded through the code for a bunch of RTEs, it was a hell of a lot easier than I expected to get it to the point it’s at now.

Sometimes there are reasons to avoid a custom solution, but in this case, I feel a custom solution was warranted. We use text editors at work in a variety of applications, and none of those are applications that we’re trying to turn into MySpace. This means, as a company, we have two options with regard to an existing editor. We can either download it, customize it, and then try to make the same updates in each new application, or we can “fork” whatever’s available at the moment and start passing around a customized plugin that needs minimal setup. I should be clear that by “customize,” in most cases, I mean “turn a bunch of shit off”. Not having to turn the same shit off over and over or risk changing the plugin itself so much that it can’t be updated make writing a custom solution worthwhile to me. Especially considering how fucking easy it is.

The editor I came up is really just a div that makes use of contenteditable. There’s some trickier shit, and I’ll discuss that toward the end, but by and large it’s doing what browsers support natively. To my mind, that means this sort of tool is edging toward the threshold of “writing markup” and away from “writing JavaScript plugins”. To anyone lucky enough to only be supporting modern browsers and IEs 7+, who doesn’t need word processing in a web page, who’s still downloading and customizing the shit out of someone else’s generic use case text editor, I would ask why? The tools required to do this job are now pretty standard. Yes, they generate slightly different markup and, yes, there are still more complicated things to deal with when it comes to working with selected text. But those challenges are surmountable.

If you haven’t yet fooled around with contenteditable and you take any sort of user content, I’d encourage you to. If you need convincing that this is powerful and very handy stuff, please consider Mozilla’s rundown of designMode commands. You can do the basic stuff in all modern and semi-modern browsers. You can do the cool stuff in browsers that aren’t IE. You can go beyond editing text if you need to. And it’s as simple as:

document.execCommand("bold",null,null);

What you get with contenteditable is probably not everything you need, but it’s close. I wrote my own function to strip out HTML, because I wanted to be able to white-list some tags. Spell-check is something I’m still trying to figure out how to handle. And even defining a URL for a link requires you to look into ranges and selections a little bit.

What I found a little odd about all the designMode commands was that they don’t operate on a DOM node as I’d normally think of it, but on whatever’s currently selected in the document. This kind of makes sense, because otherwise it would be tricky to define a text node of arbitrary size and content to make bold, for example. And I guess it’s just an artifact of dealing with text rather than the tidy hierarchies of elements you’d generally establish to style something or be able to wrap it in a link, like wrapping a span around the numeric portion of a character counter. On the positive side, it doesn’t require a whole ton of code. It seems like I’ve got selections and ranges in modern browsers and IE supported with just these functions (knock wood):

function getRange() {
	return window.getSelection ?
		window.getSelection().getRangeAt(0) :
		document.selection.createRange();
}
function setSelection(range) {
	if (range.select) {
		range.select();
	} else {
		var selection = window.getSelection();
		selection.removeAllRanges();
		selection.addRange(range);
	}
}

As you can see, there are two different ways of handling this stuff. Unfortunately, that’s not the end of it. When you select a range, you may or may not get a text node you can work with. Modern browsers will let you take that node and make it a jQuery object (or whatever else you want to do to it). In IE, you need to get the node’s parent before you can work with it, then add that parent to the set of elements you’re working with. That probably doesn’t sound that onerous, right? It’s really not. Little feature sniffing, no big deal. What worries me is how I’m going to handle spell-checking. It seems you could use ranges to wrap misspelled words in some tag to message that to the user, but ranges don’t come from a string of HTML you ran a regular expression on to figure out what’s a word and what’s a tag. If you get just the text in the editor, it’s going to be tricky to find the offset and starting/ending nodes that define a range. Maybe I’m just looking at it wrong and, although ranges are the obvious way to handle other text editing functions, they’re no good for that scenario.

But like I said, don’t let that dissuade you. Lots of browsers have native spell-checking and it works fine in an element with contenteditable applied. If you need a simple text editor, you can probably write your own pretty easily. I think it’s worth considering that a text editor may not need to be a special fancy plugin but might be able to be just another form field you use JavaScript to add a little bling to. It really seems to me that it’s getting close.