fluid-work IRC Logs-2008-05-22
[08:34:57 EDT(-0400)] * anastasiac (n=team@142.150.154.105) has joined #fluid-work
[09:44:18 EDT(-0400)] * jessm (n=Jess@cpe-069-134-127-060.nc.res.rr.com) has joined #fluid-work
[09:52:12 EDT(-0400)] <jessm> doh, fluidproject.org = down
[09:58:10 EDT(-0400)] <anastasiac> hi, jessm - yes, I've already called nakul about it
[09:58:46 EDT(-0400)] <jessm> anastasiac: excellent
[09:58:48 EDT(-0400)] <jessm> thanks!
[10:16:20 EDT(-0400)] * EricDalquist (n=dalquist@bohemia.doit.wisc.edu) has joined #fluid-work
[10:46:30 EDT(-0400)] <anastasiac> jessm: fluidproject.org is back up
[12:25:34 EDT(-0400)] * apetro-_ (n=apetro@wsip-98-174-242-39.ph.ph.cox.net) has joined #fluid-work
[12:38:04 EDT(-0400)] * colinclark (n=colin@bas1-toronto09-1279543721.dsl.bell.ca) has joined #fluid-work
[13:06:23 EDT(-0400)] <colinclark> anastasiac: So I've been playing around with a simplified API for the Reorderer.
[13:06:39 EDT(-0400)] <anastasiac> ah, interesting. go on...
[13:07:13 EDT(-0400)] <colinclark> This originally came up when I was thinking about the Layout Customizer, and how people will undoubtedly want to be able to reorder portlets without having to hand-roll their own little bitmap structure.
[13:07:23 EDT(-0400)] <anastasiac> indeed!
[13:07:30 EDT(-0400)] <colinclark> But I decided to tackle the simplest problem first. Portlets are pretty complex.
[13:07:39 EDT(-0400)] <colinclark> So I have a version of your sortable todo list...
[13:08:16 EDT(-0400)] <colinclark> anastasiac: Do you have a favoured pastebin server?
[13:08:36 EDT(-0400)] <anastasiac> fluid.pastebin.com
[13:08:53 EDT(-0400)] <colinclark> Cool! I had no idea.
[13:09:20 EDT(-0400)] <anastasiac> put any name you want in front of "pastebin.com" - it works!
[13:09:25 EDT(-0400)] <colinclark> aha
[13:09:26 EDT(-0400)] <colinclark>
[13:09:39 EDT(-0400)] <colinclark> So this is how the initToDoList() function currently looks:
[13:09:40 EDT(-0400)] <colinclark> http://fluid.pastebin.com/m402f1620
[13:09:58 EDT(-0400)] <colinclark> Put another way, this is the bare minimum we ask our clients to do in order to use the Reorderer.
[13:10:06 EDT(-0400)] <colinclark> 1. Fetch the container from the DOM.
[13:10:15 EDT(-0400)] <colinclark> 2. Create an orderable finder.
[13:10:23 EDT(-0400)] <colinclark> 3. Initialize the appropriate LayoutHandler
[13:10:32 EDT(-0400)] <colinclark> 4. Construct a new Reorderer.
[13:10:38 EDT(-0400)] <anastasiac> right
[13:11:05 EDT(-0400)] <colinclark> I have written a really simple function to construct a list Reorderer:
[13:11:18 EDT(-0400)] <colinclark> This is what the initToDoList function looks like now:
[13:11:20 EDT(-0400)] <colinclark> return fluid.Reorderer.list("#todo-list", "[id^=myUniquePrefix]");
[13:11:37 EDT(-0400)] <colinclark> Now I may well have simplified things too much. You can point out the flaws...
[13:11:45 EDT(-0400)] <colinclark> I'll put the implementation in pastebin, one sec.
[13:12:20 EDT(-0400)] <colinclark> http://fluid.pastebin.com/m4593da3f
[13:12:59 EDT(-0400)] <anastasiac> I like it.
[13:13:04 EDT(-0400)] <colinclark> So what I find interesting is that we did the hard work to make sure things were really generic in the guts of the Reorderer. And it took me about ten minutes to whip up a more constrained, less generic but simpler API on top of it.
[13:13:09 EDT(-0400)] <anastasiac> I like the idea of building in default creators like this
[13:13:40 EDT(-0400)] <colinclark> I think for the most part, the concept of item finders and even layout handlers should be invisible to ordinary users.
[13:14:09 EDT(-0400)] <colinclark> Users who are crazy enough to want something very different, or who are building their own LayoutHandlers, can still fall back to the more complex base constructor.
[13:14:34 EDT(-0400)] <anastasiac> I agree. It's good to have it available to users who want that control, but the simpler "here's what to use if you don't want to have to think" version is great
[13:14:58 EDT(-0400)] <anastasiac> I assume similar constructors for grid, module, etc
[13:14:59 EDT(-0400)] <anastasiac> ?
[13:15:07 EDT(-0400)] <colinclark> Yes. I'm just starting in on that now.
[13:15:14 EDT(-0400)] <anastasiac> cool!
[13:15:24 EDT(-0400)] <colinclark> Are there any non-Lightbox examples of sortable grids floating around still?
[13:15:33 EDT(-0400)] <anastasiac> hm...
[13:15:58 EDT(-0400)] <colinclark> This also starts to really push the question of "what is a lightbox?" since you can imagine it's really just this:
[13:16:15 EDT(-0400)] <colinclark> fluid.Reorderer.grid(...);
[13:16:16 EDT(-0400)] <colinclark>
[13:16:25 EDT(-0400)] <anastasiac> exactly
[13:16:29 EDT(-0400)] <colinclark> With a specific orderChangedCallback that assumes something about the structure of the template, of course.
[13:17:17 EDT(-0400)] <anastasiac> very cool stuff
[13:17:37 EDT(-0400)] <anastasiac> re non-lightbox grids: not that I recall or can find
[13:17:50 EDT(-0400)] <colinclark> I couldn't find any either.
[13:17:55 EDT(-0400)] <colinclark> I will have to start writing unit tests.
[13:17:58 EDT(-0400)] <anastasiac> but it would probably be good to have an example... not sure what the sample case might be
[13:18:04 EDT(-0400)] * colinclark slaps himself on the wrist.
[13:18:07 EDT(-0400)] <anastasiac> yay unit tests!
[13:18:28 EDT(-0400)] <colinclark> cowboys don't need unit tests!
[13:18:48 EDT(-0400)] <anastasiac> no cowboys in fluid! we'll have to get jess to add that to her list
[13:18:52 EDT(-0400)] <colinclark>
[13:19:00 EDT(-0400)] <colinclark> no crying, no bleeding, no cowboys?
[13:19:05 EDT(-0400)] <anastasiac> right!
[13:19:15 EDT(-0400)] <colinclark> I can dig that.
[13:19:24 EDT(-0400)] <colinclark> Okay, well I'll stop distracting you now.
[13:19:26 EDT(-0400)] <anastasiac> in particular, no crying bleeding cowboys
[13:19:30 EDT(-0400)] <colinclark> lol
[13:19:34 EDT(-0400)] <colinclark> poor cowboy
[13:19:51 EDT(-0400)] <anastasiac> well, if he's bleeding, I guess it's a good reason to be crying?
[13:19:55 EDT(-0400)] <colinclark> perhaps
[13:20:00 EDT(-0400)] <colinclark> i thought cowboys never cried.
[13:20:07 EDT(-0400)] <anastasiac> ok, I'll stop distracting you
[13:20:09 EDT(-0400)] <colinclark> or cowgirls? i forget
[13:20:16 EDT(-0400)] * colinclark is sick of eating soup.
[13:20:20 EDT(-0400)] <anastasiac>
[13:25:15 EDT(-0400)] <colinclark> anastasiac: Am I correct in thinking that, from an API perspective, the list and grid LayoutHandlers are essentially the same?
[13:25:34 EDT(-0400)] <colinclark> In other words, they expect an item finder and an option orderChangedCallback.
[13:25:38 EDT(-0400)] <colinclark> And that's about it.
[13:25:49 EDT(-0400)] <anastasiac> colinclark, yes. They are the same. Some implementations are different, but the API is the same.
[13:26:03 EDT(-0400)] <colinclark> Perfect. I'm sharing code.
[13:26:16 EDT(-0400)] <colinclark>
[13:26:28 EDT(-0400)] <colinclark> var simpleInit = function (containerSelector, itemSelector, layoutHandlerFn, orderChangedCallback)
[13:26:48 EDT(-0400)] <colinclark> The only difference for a list versus a grid is what you pass for the layoutHandlerFn...
[13:27:00 EDT(-0400)] <colinclark> fluid.Reorderer.list = function (containerSelector, itemSelector, orderChangedCallback) {
[13:27:01 EDT(-0400)] <colinclark> return simpleInit(containerSelector, itemSelector, fluid.ListLayoutHandler, orderChangedCallback);
[13:27:01 EDT(-0400)] <colinclark> };
[13:27:11 EDT(-0400)] <colinclark> vs.
[13:27:11 EDT(-0400)] <colinclark> fluid.Reorderer.grid = function (containerSelector, itemSelector, orderChangedCallback) {
[13:27:12 EDT(-0400)] <colinclark> return simpleInit(containerSelector, itemSelector, fluid.GridLayoutHandler, orderChangedCallback);
[13:27:12 EDT(-0400)] <colinclark> };
[13:27:40 EDT(-0400)] <anastasiac> nice...
[14:25:04 EDT(-0400)] * jessm (n=Jess@cpe-069-134-127-060.nc.res.rr.com) has joined #fluid-work
[14:33:15 EDT(-0400)] <colinclark> anastasiac: Do you see any reason why I shouldn't create an Eclipse project for the markupExamples in the sandbox?
[14:33:26 EDT(-0400)] <colinclark> I discovered those grid examples I was looking for.
[14:34:35 EDT(-0400)] <anastasiac> good on the examples, and no, I don't see any reason not to have a project - makes it easier to work with them
[14:35:33 EDT(-0400)] <colinclark> anastasiac: Thanks. Done. Committed revision 4993.
[14:42:57 EDT(-0400)] * michelled (n=team@142.150.154.197) has joined #fluid-work
[14:56:06 EDT(-0400)] <colinclark> michelled, anastasiac: Ideally, how do you think the Reorderer should handle an invalid argument such as an empty container or an itemFinder that return no items?
[14:56:35 EDT(-0400)] <colinclark> Or, put another way, I've noticed with this new API I'm working on that it's easy to have Reorderer silently fail if you pass a broken selector in.
[14:56:55 EDT(-0400)] <colinclark> We wouldn't have noticed this to the same degree before, but now with a selector-based API, it gets confusing.
[14:57:01 EDT(-0400)] <michelled> I think silent failing is fine. - don't you?
[14:57:06 EDT(-0400)] <colinclark> The code doesn't show any errors, but nothing is reorderable.
[14:57:20 EDT(-0400)] <colinclark> I don't know. That's why I thought I'd ask you guys.
[14:58:09 EDT(-0400)] <michelled> For example, in the gallery, it would be possible to have a folder with no items in it. It is probably not much use to the user, but I wouldn't want the Reorderer to throw an error in this case.
[14:58:27 EDT(-0400)] <colinclark> Yes, very true.
[14:58:58 EDT(-0400)] <colinclark> Would it make sense, for these new functions I'm writing, to throw an exception?
[14:59:31 EDT(-0400)] <colinclark> Hmm. I was thinking that they're bound statically, but I guess an itemFinder could conceivably be called again when the selector was actually valid.
[15:00:32 EDT(-0400)] <colinclark> It's a harder problem than I thought.
[15:00:55 EDT(-0400)] <colinclark> michelle: Silently failing could be confusing to debug, but you're thinking the alternatives are worse, then?
[15:01:17 EDT(-0400)] <colinclark> michelled: ^
[15:02:56 EDT(-0400)] <michelled> yes, I'm thinking that there are times when a reorderer would be created with no items in it. It doesn't do anything and is quite strange but there was the (future) idea that items could be dynamically added and removed
[15:03:19 EDT(-0400)] <colinclark> Yes.
[15:03:21 EDT(-0400)] <michelled> Throwing an error would just cause confusion in such a case
[15:03:37 EDT(-0400)] <colinclark> We could probably support dynamic updates quite easily now with the addition of a refresh() function.
[15:03:55 EDT(-0400)] <michelled> yes
[15:04:11 EDT(-0400)] <colinclark> Too bad. I hate silent failure. But this makes sense.
[15:04:25 EDT(-0400)] <michelled>
[15:16:48 EDT(-0400)] <colinclark> anastasiac: Would a super-simple bit of sample markup for reordering grids be helpful for you in your documentation? Or do you already have something along these lines?
[15:54:12 EDT(-0400)] * RayDavis (n=chatzill@dhcp-169-229-212-41.LIPS.Berkeley.EDU) has joined #fluid-work
[16:10:13 EDT(-0400)] <colinclark> michelled: Do you have time for another quick question?
[16:10:30 EDT(-0400)] <michelled> sure
[16:11:17 EDT(-0400)] <colinclark> So, I'm making some progress on reorderPortlets() by essentially reverse engineering the demo.portal.layout structure.
[16:11:39 EDT(-0400)] <colinclark> So, the new API will essentially take a list of columns and a list of portlets.
[16:12:07 EDT(-0400)] <colinclark> I'll need to search through the children of each column, looking for the subset of the portlets that are within the column.
[16:12:10 EDT(-0400)] <colinclark> Does that make sense?
[16:12:50 EDT(-0400)] <colinclark> And locked portlets are always listed within that layout structure, but have 0 set in the permission bitmap, right?
[16:13:25 EDT(-0400)] <michelled> yes
[16:13:45 EDT(-0400)] <michelled> yes, there are 0's in the
[16:14:02 EDT(-0400)] <colinclark> great.
[16:14:06 EDT(-0400)] <michelled> position before the locked portlet in all the permissions rows
[16:14:06 EDT(-0400)] <colinclark> this almost seems easy.
[16:14:18 EDT(-0400)] <michelled> cool
[17:00:22 EDT(-0400)] <colinclark> michelled: Do you know if there's any easy way to remove items from an existing jQuery?
[17:02:57 EDT(-0400)] <michelled> I don't know off hand - I'm guessing you checked their docs?
[17:04:02 EDT(-0400)] <colinclark> michelled: I did, yes.
[17:04:22 EDT(-0400)] <colinclark> I could speed up my algorithm a bit if I could chop found portlets out of the jQuery.
[17:04:45 EDT(-0400)] <colinclark> I suppose it still might be faster to use a bare array and continually rewrap in it in a jQuery.
[17:05:43 EDT(-0400)] <colinclark> michelled: This is really just a sketch. http://fluid.pastebin.org/37854
[17:11:13 EDT(-0400)] <michelled> It's kinda funny. The first thing the ModuleLayoutHandler is going to do is build the 'findItems' object.
[17:12:03 EDT(-0400)] <colinclark>
[17:12:24 EDT(-0400)] <colinclark> michelled: Back and forth... we can merge these two approaches after our deadline.
[17:12:44 EDT(-0400)] <colinclark> And in the interim, do a bit of profiling to find out how much this will cost.
[17:13:17 EDT(-0400)] <michelled> sounds like a good approach
[17:14:08 EDT(-0400)] <colinclark> michelled: So tell me about the orderChangedCallbackUrl
[17:14:17 EDT(-0400)] <colinclark> (if you have time)
[17:15:07 EDT(-0400)] <colinclark> And does the ModuleLayoutHandler freak out if it doesn't get a grabhandle?
[17:15:28 EDT(-0400)] <RayDavis> Dang. The long-feared GWT thread has begun on sakai-dev.
[17:15:51 EDT(-0400)] <RayDavis> Well, it was just a matter of time.
[17:16:30 EDT(-0400)] <colinclark> RayDavis: Ack!
[17:16:55 EDT(-0400)] <michelled> colinclark: no to the grabhandle question
[17:17:10 EDT(-0400)] <michelled> the manual test does not have a grabhandle
[17:17:38 EDT(-0400)] <colinclark> RayDavis: I'm really disappointed with GWT. I understand why someone would be attracted to it, but it's quite a tradeoff to make.
[17:17:45 EDT(-0400)] <michelled> Interestingly, it was the first option that aTutor came to us with once they had the Reorderer moving around their bits of UI.
[17:17:58 EDT(-0400)] <michelled> So it's really good that uPortal required us to put that in.
[17:17:58 EDT(-0400)] <michelled>
[17:18:22 EDT(-0400)] <colinclark> michelled: Cool!
[17:18:46 EDT(-0400)] <colinclark> michelled: So is ATutor now using the GridLH or the ModuleLH?
[17:19:00 EDT(-0400)] <michelled> GridLH
[17:19:19 EDT(-0400)] <michelled> as to the orderChangedCallbackUrl - the ModuleLayoutHandler comes with a built in strategy for talking to the server. It sends the new layout to the server and expects back the new perms
[17:19:24 EDT(-0400)] <RayDavis> colinclark: Yes, I think your reasoning makes sense. But it seems like one of those "gotta live with it and improve if we can" things with Java programmers. At least until we all get high on Flex.
[17:19:44 EDT(-0400)] <colinclark> RayDavis: Definitely gotta live with it.
[17:20:02 EDT(-0400)] <colinclark> And it's a fair decision. You've got to choose a tool that fits your skillset.
[17:20:31 EDT(-0400)] <colinclark> It's just a sad thing that Sakai has been largely bereft of Web-types for so long.
[17:20:42 EDT(-0400)] <colinclark> RayDavis: I'm curious what it means for the future of MyCamTools, too.
[17:21:01 EDT(-0400)] <RayDavis> I bet the other folks on MyCamTools are curious, too.
[17:21:12 EDT(-0400)] <colinclark> RayDavis: Yes.
[17:22:39 EDT(-0400)] <michelled> colinclark: I'm not sure that the server strategy for the ModuleLayoutHandler is really what uPortal really wants. I'm wondering if we should expose the option of using an orderChangedCallback or an URL.
[17:23:06 EDT(-0400)] <michelled> and for that matter other users of the ModuleLayoutHandler that don't care about permissions.
[17:23:14 EDT(-0400)] <colinclark> michelled: Okay, good to know.
[17:24:38 EDT(-0400)] <colinclark> michelled: I now understand why you thought a new LH was in order for this.
[17:24:55 EDT(-0400)] <colinclark> It's pretty redundant. But it will do for now.
[17:25:25 EDT(-0400)] <michelled>
[17:28:12 EDT(-0400)] <colinclark> michelled: With a more selector-based API, one of the things we'll have to be careful to document is that the selectors should be relative to the container.
[17:28:36 EDT(-0400)] <colinclark> Otherwise, people might naturally constrain their searches to the container, even though we do it for them. And then their selectors will break.
[17:28:51 EDT(-0400)] <michelled> oh, that sucks.
[17:29:37 EDT(-0400)] <michelled> I guess we couldn't check for that, eh?
[17:30:54 EDT(-0400)] <colinclark> We could, but it wouldn't be trivial.
[17:31:37 EDT(-0400)] <colinclark> michelled: Interesting that you've created a public internals property in ModuleLH.
[17:31:43 EDT(-0400)] <colinclark> Seems like a good compromise.
[17:32:27 EDT(-0400)] <michelled> ya, I'd like to squash that but there was no time to the moduleLayout obj
[17:32:41 EDT(-0400)] <colinclark> michelled: It makes sense.
[17:33:58 EDT(-0400)] <michelled> hmmm... I'm glad you can fill in the words I leave out I'm trying to do a few things at once here
[17:35:23 EDT(-0400)] <michelled> the moduleLayout object needs some refactoring. The public internal functions have some good tests which cannot be sacrificed hence their publicity
[17:35:39 EDT(-0400)] <colinclark> RayDavis: What do you do about unit testing private methods?
[17:35:57 EDT(-0400)] <colinclark> This has been a source of interesting debate amongst us for awhile.
[17:36:04 EDT(-0400)] <RayDavis> In Java?
[17:36:31 EDT(-0400)] <colinclark> RayDavis: In any language that has some way to enforce privacy.
[17:37:42 EDT(-0400)] <RayDavis> Generally speaking I haven't found it an issue, since generally what you really want to regression test is visible behavior. But when retrofitting tests to poorly designed code, I remember the problem coming up.
[17:38:27 EDT(-0400)] <colinclark> RayDavis: That's been my thinking, too.
[17:39:17 EDT(-0400)] <colinclark> With code that wasn't designed for it, explicitly breaking encapsulation in some has worked. In other words, making it really clear that just because a particular method is public, it's not there for you.
[17:39:18 EDT(-0400)] <RayDavis> I don't remember a tidy one-size-fits-all answer, I'm afraid. Either I rely on brittle "white-box" knowledge, or I expose the methods by making them protected. There was at least one other trick too, I think....
[17:39:49 EDT(-0400)] <RayDavis> (Or making them public, sure.)
[17:40:14 EDT(-0400)] <colinclark> RayDavis: In JavaScript, we've got either public or "wrapped in a closure and completely invisible to everyone."
[17:41:20 EDT(-0400)] <colinclark> michelled's approach, quite sensibly, is to test anything that can break.
[17:41:30 EDT(-0400)] <RayDavis> Right, that makes the situation more "interesting".
[17:43:04 EDT(-0400)] <colinclark> In that case, my sense is to be very careful about how you design... in other words, if you need to test a function, other people probably want to use it.
[17:43:10 EDT(-0400)] <RayDavis> Hey, this looks like a nice overview: http://www.artima.com/suiterunner/private.html
[17:43:22 EDT(-0400)] <RayDavis> I'll have to bookmark and read it later.
[17:43:37 EDT(-0400)] <RayDavis> But yes, I guess the most common advice is to "design for testing".
[17:44:56 EDT(-0400)] <colinclark> Apparently the JUnit FAQ says "Testing private methods may be an indication that those methods should be moved into another class to promote reusability." Which is a better articulation of what I was trying to get at.
[17:44:59 EDT(-0400)] <RayDavis> Which feels wrong to me as someone who gets heated up about API design, but rarely actually feels wrong to me in practice.
[17:45:14 EDT(-0400)] <RayDavis> "Which feels wrong to me in theory..." I mean.
[17:45:21 EDT(-0400)] <colinclark> Interesing.
[17:45:28 EDT(-0400)] <colinclark> Interesting.
[17:45:57 EDT(-0400)] <RayDavis> Well, you usually don't want to have scalability testing driving the end-user interface either....
[17:46:14 EDT(-0400)] <colinclark>
[17:46:48 EDT(-0400)] <colinclark> It's clearly not cut and dry. And it seems to me that testing something is still more important than refusing testing it for aesthetic reasons.
[17:47:02 EDT(-0400)] <anastasiac> colinclark: just back from interviews. Regarding a super-simple bit of markup for reordering grids: yes, sample code is always useful for documentation! please!
[17:47:17 EDT(-0400)] <colinclark> michelled: I didn't mean to speak for you there. Any thoughts, or are you heads-down in code?
[17:47:40 EDT(-0400)] <colinclark> anastasiac: Okay, I may have something that I culled from the sandbox and simplified. But it needs styling to suck less first.
[17:47:58 EDT(-0400)] <colinclark> anastasiac: I now have fluid.reorderList() and reorderGrid() working.
[17:48:07 EDT(-0400)] <colinclark> And am well into reorderPortlets()
[17:48:08 EDT(-0400)] <anastasiac> cool - feel free to pass it on even without the styling
[17:48:25 EDT(-0400)] <anastasiac> and cool!
[17:48:33 EDT(-0400)] <michelled> colinclark: I'm been reading along while trying to understand stupid event targets that make no sense. glarg
[17:48:34 EDT(-0400)] <anastasiac> excellent!
[17:48:42 EDT(-0400)] <anastasiac> more documentation to write! woohoo!
[17:48:51 EDT(-0400)] <colinclark> michelled: ugh. Sorry to distract you.
[17:49:00 EDT(-0400)] <michelled> I didn't disagree with anything that's why I'm quiet
[17:49:03 EDT(-0400)] <RayDavis> Oh yeah, I just remembered a combo hack for testing: one package-visible superclass and methods, one public-facing subclass with privatizing methods, tests run in the package.
[17:49:10 EDT(-0400)] <colinclark> michelled: lol!
[17:49:30 EDT(-0400)] <RayDavis> I saw her nodding.
[17:50:00 EDT(-0400)] <colinclark> RayDavis: Interesting. This makes sense, but I'd love to see an example of it. Not that I should really be thinking about it at the moment, anyway.
[17:50:10 EDT(-0400)] <RayDavis> You and me both.
[17:50:16 EDT(-0400)] <RayDavis> Neither.
[17:50:29 EDT(-0400)] <michelled>
[17:50:41 EDT(-0400)] <colinclark> anastasiac: Hopefully this simplified API will make your documentation work a little easier, but I'm probably dreaming.
[17:50:45 EDT(-0400)] <RayDavis> Back to writing up "the sad limitations of error handling in swfupload", speaking of stupid events.
[17:52:22 EDT(-0400)] <colinclark> RayDavis: Limitations of error handling?
[17:52:28 EDT(-0400)] <colinclark> Is this on the client side or server?
[17:53:48 EDT(-0400)] <colinclark> RayDavis: I had a conversation awhile back with Eli about the error-handling code in Uploader.js. It doesn't make a lot of sense at the moment... it was cut and pasted from an example. Could this have anything to do with the "sad limitations" you're seeing?
[17:53:51 EDT(-0400)] <RayDavis> colinclark: As one final