Funk Rock http://rossboucher.com Just another WordPress weblog Wed, 20 Aug 2008 00:16:57 +0000 http://wordpress.org/?v=2.0.4 en iPhone Touch Events in JavaScript http://rossboucher.com/2008/08/19/iphone-touch-events-in-javascript/ http://rossboucher.com/2008/08/19/iphone-touch-events-in-javascript/#comments Tue, 19 Aug 2008 18:44:40 +0000 Ross Apple Web Projects Technology http://rossboucher.com/2008/08/19/iphone-touch-events-in-javascript/ Yesterday I gave a presentation at the San Francisco JavaScript Meetup about the new JavaScript touch events API in iPhone 2.0. I thought I’d share the slides, in case people were interested in viewing them after the fact.

I owe a great deal of thanks to Neil Roberts from SitePen, who’s post on the topic was my main source of information. My co-founder Tom Robinson was also helpful, thanks to his iPhone light-table.

One of the interesting things I was able to talk about was reusing existing mouse based libraries with the iPhone by using touch events to simulate mouse events. The basic idea behind it was to address the fact that mouse events don’t work particularly well on the phone. It’s unpredictable when you’ll get them, if at all (you won’t if you attach only to document, for example). Mousemove in particular doesn’t work in any meaningful way.

In contrast, the touch events are completely predictable and reliable (excepting the existing bugs). We can use these events to simulate the existing mouse events with a fair amount of accuracy. In particular, when one finger is down on the screen, touchstart, touchend, and touchmove correspond nicely with mousedown, mouseup, and mousemove. There’s some difference in the way mousemove works, since we can’t get mousemove events when the finger is not touching the screen, but this is an acceptable trade off. It doesn’t make sense on the iPhone anyway because there’s no persistent cursor.

I took this jQuery based drag and drop example to see if I could get it working on the iPhone without modification. Here’s the working iPhone demo. The only existing code that I modified was some CSS to make the page fit nicely on the iPhone screen, and a viewport meta tag. The added code to get drag and drop working is really simple:

function touchHandler(event)
{
    var touches = event.changedTouches,
        first = touches[0],
        type = “”;
    
    switch(event.type)
    {
        case “touchstart”: type = “mousedown”; break;
        case “touchmove”:  type=“mousemove”; break;        
        case “touchend”:   type=“mouseup”; break;
        default: return;
    }
        
    //initMouseEvent(type, canBubble, cancelable, view, clickCount,
    //           screenX, screenY, clientX, clientY, ctrlKey,
    //           altKey, shiftKey, metaKey, button, relatedTarget);
    
    var simulatedEvent = document.createEvent(“MouseEvent”);
    simulatedEvent.initMouseEvent(type, true, true, window, 1,
                              first.screenX, first.screenY,
                              first.clientX, first.clientY, false,
                              false, false, false, 0/*left*/, null);
                                                                            
    first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init()
{
    document.addEventListener(“touchstart”, touchHandler, true);
    document.addEventListener(“touchmove”, touchHandler, true);
    document.addEventListener(“touchend”, touchHandler, true);
    document.addEventListener(“touchcancel”, touchHandler, true);    
}

I’ve captured the touch events and then manually fired my own mouse events to match. Although the code isn’t particularly general purpose as is, it should be trivial to adapt to most existing drag and drop libraries, and probably most existing mouse event code. Hopefully this idea will come in handy to people developing web applications for the iPhone.

Update: In posting this, I noticed that calling preventDefault on all touch events will prevent links from working properly. The main reason to call preventDefault at all is to stop the phone from scrolling, and you can do that by calling it only on the touchmove callback. The only downside to doing it this way is that the iPhone will sometimes display its hover popup over the drag origin. If I discover a way to prevent that, I’ll update this post.

]]>
http://rossboucher.com/2008/08/19/iphone-touch-events-in-javascript/feed/
Resizing TextAreas http://rossboucher.com/2008/07/28/resizing-textareas/ http://rossboucher.com/2008/07/28/resizing-textareas/#comments Tue, 29 Jul 2008 00:06:30 +0000 Ross Web http://rossboucher.com/2008/07/28/resizing-textareas/ Yesterday I was working on making a textarea element automatically resize itself to fit its content without a scroll bar. I’ve seen this done before, so it isn’t something strictly new, but I did notice that a lot of people are doing hacks with rows/columns, so I thought I’d share my own approach.

In my case, I wanted a fixed minimum height, and then I wanted the box to grow as the user typed additional text. Assuming you have a reference to your textarea, and a MIN_HEIGHT variable defined somewhere, the javascript is actually very simple:

textArea.style.height = MIN_HEIGHT + “px”;
textArea.style.height = Math.max(MIN_HEIGHT, textArea.scrollHeight) + “px”;


We need to do the first set because otherwise Firefox and Safari will not shrink if the user deletes text. I should note that the textarea was styled with a fixed width in pixels, which shouldn’t be strictly necessary.

The real reason I wanted this auto-expanding and contracting view was actually because I wanted to use it in my own custom scroller. For the scroller to work properly, it needs to know the size of whatever its scrolling inside of it. The other problem with putting a textarea into my custom scroller was knowing where to scroll too. Since textarea’s have their own caret, and since most browsers will scroll the textarea to follow the caret no matter what you set overflow to, I needed a way to know where exactly the caret was in the textarea.

Both Firefox and Safari have the selectionStart and selectionEnd properties on textarea elements. When there’s no selection, these two numbers are the same; they tell you the character index of the caret. Strictly speaking, knowing the index of the caret isn’t enough; I need to know the vertical offset. There’s no easy way to do this, so I reused one of the hack’s I’ve been playing around with lately.

What I did was create a duplicate of the textarea’s text content inside another element (a div in our case). We make sure to style the textarea and div the same so that the rendered text would look exactly the same, except one would be editable and the other wouldn’t. The trick is, in our new element, I surround each character with it’s own span. Then, I can use the caret index we got before as an index into the childNode array of our div element to get a reference to the specific character we’re dealing with. Here’s a relatively simple implementation of what I’m talking about:

var start = textArea.selectionStart,
    end = textArea.selectionEnd,
    imposter = document.createElement(’div’),
    referenceSpan = document.createElement(’span’),
    stringValue = textArea.value;

//You may need to copy more than just these two styles
imposter.style.height = textArea.style.height;
imposter.style.width  = getComputedStyle(textArea, “”).getPropertyValue(’width’);

for(var i=0; i {
    referenceSpan.innerHTML = stringValue.charAt(i).replace(“\n”,
);
    imposter.appendChild(referenceSpan.cloneNode(true));
}

document.body.appendChild(imposter);

var caretOffsetTop = imposter.childNodes[start - 1].offsetTop - imposter.offsetTop,
    caretHeight = imposter.childNodes[start-1].offsetHeight;

document.body.removeChild(imposter);


At the end of that block we have the vertical position of the caret in the textarea (or at least an incredibly good approximation). There are a few things I’ve glossed over; the most obvious is that if you call this on every keypress you’ve turned an O(1) operation into an O(n) operation.

The enterprising individual will want to cache and and keep track of the state of the textarea rather than build from scratch, but I can tell you from personal experience that it’s a real pain, and may not be worth the effort. For most uses, and in pretty much any version of Firefox or Safari, the above code will work well enough. The other thing to watch out for is that many browsers won’t report the size/position of whitespace characters, so you’ll need to scan for the nearest non-whitespace character.

Right now this doesn’t work in Internet Explorer. IE uses a different mechanism — document.selection.createTextRange() — to return information about the position of the caret. Unfortunately, the character index is not one of the properties of the TextRange object. The object does have an offsetTop property, but it seems to return the offset into the whole window, and I’m having difficulty keeping that in sync with the scrolling textarea. If anybody has any feedback on that front, or on the hack in general, I’d like to hear it.

]]>
http://rossboucher.com/2008/07/28/resizing-textareas/feed/
Aftermath of 280 Slides http://rossboucher.com/2008/06/19/aftermath-of-280-slides/ http://rossboucher.com/2008/06/19/aftermath-of-280-slides/#comments Thu, 19 Jun 2008 23:49:48 +0000 Ross Web Projects Technology http://rossboucher.com/2008/06/19/aftermath-of-280-slides/ We launched 280 Slides two weeks ago, and it’s been a great experience. After putting five months of non stop work into it, it’s a good feeling to be able to point to it and say “That’s what I’ve been doing.” It’s also fantastic to be getting all kinds of feedback from people who like (and dislike) the application. It really does help you focus on what matters to people.

We’ve had some great press mentions too (both Slides and Cappuccino):

TechCrunch
Ajaxian
TUAW
Guardian.co.uk

And quite a few blogs. (and twitter)

There’s also been a fair amount of confusion regarding MobileMe and SproutCore. Just to clarify, MobileMe is not based on Objective-J or Cappuccino, and 280 Slides is not based on SproutCore. 280 Slides isn’t part of MobileMe, and we have no affiliation to Apple. Oh, and there are three of us, not two.

]]>
http://rossboucher.com/2008/06/19/aftermath-of-280-slides/feed/
Safari’s Web Inspector http://rossboucher.com/2008/04/21/safari-web-inspector/ http://rossboucher.com/2008/04/21/safari-web-inspector/#comments Mon, 21 Apr 2008 21:12:42 +0000 Ross Apple Web Technology http://rossboucher.com/2008/04/21/safari-web-inspector/ The WebKit team announced the list of participants they’ll be working with on this year’s Google Summer of Code today. Of particular interest to me was this applicant. Anyone who does serious web work can attest to the difficulty of debugging anything in Safari, meaning that most web developers have pretty much given up and develop in Firefox full time. This is such a shame, since Safari is almost universally a better browser — it’s faster, it supports more of the things I care about, and for all the reasons Gruber listed (and more), it’s the browser I use personally.

The thing is, the WebKit team has known for some time that they have serious issues with debugging. In fact, I’ve been told better debugging support is the number one requested feature. We saw some attention paid to the issue with Drosera, but it turned out to be nothing more than lip service. Our code brings Drosera to a halt in seconds, as do most of the complicated sites we’ve tried it on. Safari desperately needs a profiler, stack traces, and someday step through debugging. Even beyond advanced tools like what Drosera promised and what Firebug has, WebKit fails on some of the most basic levels. This bug is damning. It should be a P1. Any callback function (read: any AJAX request, event handler, etc.) fails to report the error it encounters. Almost every error in our code base is reported as “undefined” by Safari.

Keishi, you’ve got an important job ahead of you. You’ve been tasked with doing what might be the most important thing the WebKit project has done in a long time. Safari has been kicking ass in pretty much every other area, but it’s ignored by web developers precisely because it’s so cruel towards them. I wish you the best of luck in doing this project, and if you’re looking for feature requests, I’ve got at least a million. At the top of my list? Solve the most important limitation of Firebug — not properly recognizing anonymous (eval’d) code. I have high hopes for what this could be by the end of summer, and I’ll definitely be following the progress.

]]>
http://rossboucher.com/2008/04/21/safari-web-inspector/feed/
Lions in a Cage http://rossboucher.com/2008/03/23/lions-in-a-cage/ http://rossboucher.com/2008/03/23/lions-in-a-cage/#comments Mon, 24 Mar 2008 01:45:08 +0000 Ross Web Technology Life http://rossboucher.com/2008/03/23/lions-in-a-cage/ Paul Graham wrote an essay last week where he compared employees of big companies to lions in a cage at the zoo. Sort of.

I was in Africa last year and saw a lot of animals in the wild that I’d only seen in zoos before. It was remarkable how different they seemed. Particularly lions. Lions in the wild seem about ten times more alive. They’re like different animals. And seeing those guys on their scavenger hunt was like seeing lions in a zoo after spending several years watching them in the wild.

Technically, Paul is comparing the startling impact of seeing lions in a cage after seeing them in the wild to his experience seeing these employees (’those guys on their scavenger hunt”) after spending the last three years watching founders at Y Combinator. Nevertheless, the article (and this quote in particular) caused quite the controversy around the Internet (or at least around the tiny subset of the Internet that reads Paul’s essays, myself included).

It’s not hard to read that last sentence and interpret it as a claim that working for a big company is like being an animal in a cage. I don’t think it was Paul’s intention to say exactly that, but even if it were, I think the point is immaterial to the essay as a whole. It is, at its worst, an exaggeration to prove a point, something I think we can all admit to doing from time to time (indeed it’s something that great writers have always done).

The central thesis of the essay is that being an employee is harmful to individual programmers, and that being a startup founder is a better way to live. In fact, he states this explicitly:

Watching employees get transformed into founders makes it clear that the difference between the two is due mostly to environment—and in particular that the environment in big companies is toxic to programmers.

It seems to me that Jeff Atwood’s (and others) primary argument is that some employees have actually enjoyed working for big companies, himself included, and Paul is thus making a generalization that is not true. But Paul makes no claim about employees being unhappy. Though he doesn’t address the topic directly, he sets up the entire essay by saying that he isn’t talking about some special property of founders, he believes there is something missing from the life of an employee. The absence of something you don’t even know you’re missing is hardly likely to make you unhappy on its own.

When I left Apple, it was not because I was unhappy. I was working with phenomenal individuals on an interesting set of problems. I left because I was excited about the potential of our company. And despite having worked in a great environment, at an amazing company (Apple was my dream job), I feel that all the things Paul said about founders at Y Combinator ring true. I am definitely “more worried and happier at the same time.” So is John Gruber. When I had lunch with my old team on Friday, at least one person mentioned noticing the change as well.

I think Paul’s food analogy was a much better one to illustrate the point. There is plenty of science to back up the claim that most of the food we eat is unhealthy (and I’m just as guilty as anyone else), however the position is still controversial. People who avoid highly processed foods, high fructose corn syrup, refined sugar, white flour, and lots of red meat are generally healthier. These people will tell you that they are happier, and more active, and that it’s directly related to what they eat. Yet these people are also ridiculed by the majority as fringe environmentalists, lunatics, or hippies. Most people will live their entire life eating what everyone else does and will be perfectly happy doing so, but until you’ve actually gone out and changed your lifestyle and started eating “like a hippy,” you can’t possibly know whether or not you would feel better than you already do.

Eating like a hippy isn’t for everyone and neither is starting a startup, but a lot more people would thrive in a startup environment than you think, just as a lot more people really would feel better eating like a hippy. Not everyone will be convinced by Paul’s essay, and that’s okay. There are parts I disagree with as well, in particular with respect to getting some experience at a company before starting your own. As a whole, though, the essay is consistent with what I’ve experienced at Y Combinator, and other founders I’ve talked to agree.

]]>
http://rossboucher.com/2008/03/23/lions-in-a-cage/feed/
Optimus Maximus http://rossboucher.com/2008/02/22/optimus-maximus/ http://rossboucher.com/2008/02/22/optimus-maximus/#comments Fri, 22 Feb 2008 18:16:47 +0000 Ross Technology http://rossboucher.com/2008/02/22/optimus-maximus/ Those of you who read Engadget, or follow tech blogs, or are otherwise incredibly geeky, have surely heard of the Optimus Maximus. Vaporware for years, Engadget has finally got their hands on one. The verdict?

Typing on it, well, sucks.

This is a shining example of people building tech products that appeal to geeks, but overlooking the most basic, important functions. Sure, it’s nice to look at, and it sounds really cool to hot swap your keys. But, if it can’t type, then what good is it to anyone? What, I’m supposed to have two keyboards at my desk? One for typing, and one for … having little pictures? There’s a reason the iPhone is also a great phone.

At $1500 it might not matter, because only crazy people are going to buy one anyway.

]]>
http://rossboucher.com/2008/02/22/optimus-maximus/feed/
Why I Love Vimeo http://rossboucher.com/2008/02/20/why-i-love-vimeo/ http://rossboucher.com/2008/02/20/why-i-love-vimeo/#comments Wed, 20 Feb 2008 22:36:15 +0000 Ross Web Technology http://rossboucher.com/2008/02/20/why-i-love-vimeo/ My good friend Brian sent me a link to his demo reel yesterday, which he uploaded to Vimeo. I’d never heard of it before, but I was impressed with the site.

The most obvious reason to fall in love with Vimeo is the quality of the videos they are serving up. Default quality looks leaps and bounds better than YouTube’s video, but the really great part is that they offer HD video in full 720p. The quality is really amazing. For Brian, this was a no brainer — after all, who wants their demo reel to be viewed in a super compressed low quality format?

Brian used Vimeo to make himself look better, and I decided we should too. We already had YouTube search integration in our upcoming product, so I decided to take a look at Vimeo’s API and integrate some results from their site too. It only took about an hour to get everything hooked up and working, using the same system we had already built for YouTube, and the higher quality video really does make our app look better.

Since we were going for quality, we wanted to highlight the search results that came from an HD source. Unfortunately, there was no way to determine whether or not a video was HD with the current API. I decided to send an e-mail to the contact listed on the developer pages, Ted Roden. Within minutes, Ted had responded saying that he thought having an HD flag in the response was a great idea, and first thing the next morning, I had a message in my inbox explaining how the new information worked.

But the story doesn’t end there. A few hours later, after realizing how long our searches were taking, I fired off another e-mail to Ted asking for a few tips to speed things up. You see, the design of their API was such that search results only contained a video id, and a separate call was needed to get the full information for each video object. On top of that, yet another call was needed for thumbnails, and since we use two, that was 3 calls per search result. Needless to say, the overhead from all those requests added up pretty quickly, so I wanted to know if there was another way to get the same job done. Ted responded and asked what information I needed in the search results to do what I was doing, and I let him know. An hour later, he posted this to the Vimeo forums, and sent me a message letting me know that the search results could now return all the information about every video object in one call. The average time for one of our searches was sped up by an order of magnitude!

And so I just want to highlight the excellent support I received from Vimeo, and Ted. Sometimes startups can be really amazing to work with.

]]>
http://rossboucher.com/2008/02/20/why-i-love-vimeo/feed/
Cold Brewed Coffee http://rossboucher.com/2008/02/15/cold-brewed-coffee/ http://rossboucher.com/2008/02/15/cold-brewed-coffee/#comments Fri, 15 Feb 2008 20:11:49 +0000 Ross Projects Life http://blog.rossboucher.com/2008/02/15/cold-brewed-coffee/ A while ago, the New York Times had an article about cold brewed coffee that peaked my interest. I’m not much of a coffee drinker, but iced coffee is, on occasion, a pretty exceptional summer time drink, so I filed the article in the back of my mind for future reference.

Some time later, Francisco, aware of my irrational love for Dunkin’ Donuts (or, more accurately, my rational hatred for Krispy Kreme), brought back a few bags of Dunkin’ Donuts coffee for me from his trip to New York. Not having a coffee maker, or any desire to drink it really, it sat in the cabinet for a few months, until yesterday.

The weather is already pretty nice again here in Cupertino, and combined with the discovery of this article, I had no excuse not to give cold brewed coffee a chance. Substitute taco bell cups (gross) for a couple red cups, recalculate the ingredients proportionally, and I was ready to go. 24 hours later, I’m enjoying a great cup of iced coffee that was practically free (compared with $2.80 at that other coffee place)!

A picture’s worth a thousand words, so here’s 5k (courtesy of iPhone).

Cold BrewingFiltrationTiny HolesCoffee ConcentrateIced Coffee

]]>
http://rossboucher.com/2008/02/15/cold-brewed-coffee/feed/
On Browser Share http://rossboucher.com/2008/02/11/on-browser-share/ http://rossboucher.com/2008/02/11/on-browser-share/#comments Tue, 12 Feb 2008 00:41:27 +0000 Ross Web Technology http://blog.rossboucher.com/2008/02/11/on-browser-share/ A lot of people working on web applications these days seem to be oblivious to the rest of the world beyond their own team. Naturally, most of these people are using Firefox to do their browsing, and subsequently to do their development and testing as well. This makes sense, given, well, just about everything about Internet Explorer (and the fact that only about 5% of us own macs). Unfortunately, the browsing public at large is nothing like these people.

Depending on who you ask, Firefox’s share of the browser market hovers somewhere between 15 and 20%, while Internet Explorer dominates with 70% or more (and Safari is slowly building ground at around 6%). Given this, I have to ask, why on earth do developers think its okay to write Firefox only software? If asked, most of them will tell you, “Oh, I’m just a startup, I don’t have time to invest in IE,” or “the market I’m going after all uses Firefox.” I’m not buying.

Except for the most demanding of projects, making something work in IE is hardly the burden people make it out to be. Sure you have to spend extra time to workaround the missing pieces, or the flawed implementations, but if you wait until after you’ve launched a product, you’re going to have to spend weeks or months in “compatibility” development, where you write zero new features. Meanwhile, you’re turning away 80% of the potential users of your product, and many of them will never come back.

At the other end of the spectrum, it’s highly doubtful you’re really targeting people who only use Firefox. Even if you had done market research, which you almost certainly haven’t at this stage in the game, at the very least you’re likely talking about a group of people who use Firefox and Safari, in which case you really should have put in the extra effort to at least make Safari work. The differences between Firefox and Safari, at this point, are miniscule — in most cases it is trivial to make something that works in Firefox work in Safari. And if you buy the argument that Safari users are very similar on average to Firefox users, you are still excluding as much as a quarter of your potential market not working in Safari. But, like I said, this probably doesn’t even apply to you, because it’s highly unlikely you can know for sure what percentage of potential users are using Internet Explorer.

Of course, there may be exceptions. Legitimately complex applications, or incredibly focused markets, for example, might validate focusing on Firefox alone (or preferably with Safari). A good example of this is recently launched Heroku. This team has tackled a hard problem on the client side (an in browser text editor) that could be difficult to reproduce faithfully in Internet Explorer. Furthermore, by targeting Ruby on Rails developers specifically, they probably are talking about a smaller market that is likely to use Firefox more than Internet Explorer. But even Heroku, who’s goal is to bring Rails to the kind of people who don’t want to go through the hassles of deployment on their own, is probably shutting out at least some potential users who would honestly try it out, if it worked in the browser they were using. It is difficult to say how many, but analyzing their own traffic, they may be able to get a good idea. (Aside: since the rails community seems particularly Mac friendly, this might make an even stronger case for having Safari support, though, in some of my own research, it has seemed that some of the Firefox features they rely on for text selection may legitimately not have duplicates in Safari).

Ironically enough, many of the same people who would advocate Firefox only support, would outright refuse to use a service that was Internet Explorer only. Yet somehow, they cannot manage to imagine a user who would not be immediately willing to go download a new browser, and fundamentally change their online behavior, just at the opportunity to try out the “next big thing” on the web.

]]>
http://rossboucher.com/2008/02/11/on-browser-share/feed/
What’s Old is New http://rossboucher.com/2008/02/11/whats-old-is-new/ http://rossboucher.com/2008/02/11/whats-old-is-new/#comments Mon, 11 Feb 2008 09:57:10 +0000 Ross Site http://blog.rossboucher.com/2008/02/11/whats-old-is-new/ I don’t have anything to say today, except the fact that I’ve gotten rid of some cruft from the site, in the beginnings of bringing it back. I even linked it up to rossboucher.com instead of having it relegated to blog.rossboucher.com. Thus, in theory at least, I will force myself to use it.

Major changes: a new header image (taken at the conservatory in Golden Gate Park), no more silly navigation to a bunch of useless empty pages, and a solid color background. All in all, not much, but its enough of a refresh to satisfy my desire to redo the whole thing for a while, which allows me to focus on the more important things going on right now (which we’ll discuss later).

That’s all for now.

]]>
http://rossboucher.com/2008/02/11/whats-old-is-new/feed/