I like the general idea, seems a lot simpler.
I have a few questions to start off with:
a) What does "clipboard" have to do with anything? Is this an
implementation detail sneaking through into the API naming? How about
desktop.droppedItems or something?
b) You mention that this makes the entire client area a drop target.
What about iframes?
- a
On Thu, Nov 13, 2008 at 12:02 AM, Nigel Tao <[EMAIL PROTECTED]> wrote:
>
> Here's an idea that I haven't thought all the way through yet, but
> wanted to write down before I forget.
>
> The current model, with the Gears Drag and Drop API, is that you pick
> which DOM elements on the page are interested in (file) drops,
> register JS callbacks that are similar to the browser's inbuilt drag
> and drop callbacks, except that they have extra information (i.e. file
> blobs) in the callback arguments. Gears will intercept the browser's
> inbuilt DnD event flow, and inject this extra information
> automatically when invoking those callbacks.
>
> Typically, a web-app developer that wants file drops will also want to
> "protect" the rest of the page, so that missing the designated DOM
> element drop target by 1 pixel won't jarringly navigate away from the
> web-app. For someting like a YouTube uploader page, or a GMail "add an
> attachment to this e-mail that I'm composing" page, I think it would
> be a better user experience for the whole of the "client area" (i.e.
> the big, middle chunk of the browser window that isn't the chrome) to
> accept drops, rather than a fraction of the client area. Even if the
> developer didn't want the whole page to be a drop target, they still
> might want to call registerDropTarget(window.document.document,
> options) with options containing empty callback functions (e.g.
> 'ondragenter': function() {return false;}), since on some browsers, if
> DOM element A has a position:absolute style and looks like it is over
> DOM element B, then a drop on A may not trigger B's event handlers (my
> hypothesis is that this is because an absolutely positioned A does not
> have B in its ancestor chain), so you need to catch the event at the
> root element or else users will be confused when they think they're
> dropping over your accepting DIV but instead they end up navigating
> away from your web-app.
>
> The current implementation also hasn't been stress tested with
> multiple drop targets, especially if they're overlapping. There may be
> a misunderstanding in which JS handler or C++ (i.e. Gears) event
> handler is responsible for calling things like event.preventDefault
> and event.stopPropagation. And, the way Gears currently intercepts
> events at the C++ level (on IE and Firefox, but not Safari) before
> forwarding them up to JavaScript may be problematic if we're
> intercepting multiple times.
>
> Yet another point is that, by designating a given DOM element, Gears
> currently creates objects (that Ref() the element) that should be
> explicitly released for long lived web-apps (e.g. there needs to be
> explicit clean-up every time you're done with GMail's compose window)
> to avoid increasing memory usage over the life of the page. This is
> the reason why desktop.registerDropTarget returns an object, which has
> only one member function: unregister().
>
> The current API design was a combination of trying to follow the
> spirit of HTML5's proposal, yet constrained to what was practically
> achievable with browsers as shipped today.
>
> As I think I mentioned in my previous (big) e-mail about Drag and Drop
> API design, the ideal API might look something like Gears simply and
> invisibly adding the ability to query
> event.dataTransfer.getData('files') in the case of file drops.
> However, we can't consistently (across all platforms) manipulate or
> impersonate the dataTransfer object, so instead, we've provide this
> information via a context.files argument (and what used to be called
> event.files).
>
> Here is a different API proposal. Rather than Gears invoking
> designated callbacks with file information when events happen, what if
> instead elements just participate in a browser's natural event flow,
> and call Gears to get file information. Gears is the callee rather
> than the caller, and provides a clipboard API like so:
>
> Option X (the proposed API)
> -------------------------------
> <div ondrop="myOnDrop()">
> ...
> var desktop = google.gears.factory.create('beta.desktop');
> desktop.enableClipboard();
> function myOnDrop() {
> var shiftKey = window.event.shiftKey;
> var clipboard = desktop.getClipboard();
> var files = clipboard.getFiles();
> if (files && files.length > 0) {
> // ... do some stuff with files
> }
> }
> -------------------------------
>
> instead of
>
> Option Y (the current API)
> -------------------------------
> <div id="foo">
> ...
> var desktop = google.gears.factory.create('beta.desktop');
> var fooDiv = document.getElementById('foo');
> var dropTarget = desktop.registerDropTarget(fooDiv);
> dropTarget.ondrop = function(context) {
> var shiftKey = context.event.shiftKey;
> var files = context.files
> if (files && files.length > 0) {
> // ... do some stuff with files
> }
> };
> ...
> // somewhere else
> dropTarget.unregister();
> -------------------------------
>
> The desktop.enableClipboard() call sets up the client area to
> intercept drag and drop events exactly once (and to prevent file drops
> from causing navigation), and clipboard.getFiles() call only returns
> the blobs during an actual drop, otherwise it returns empty. Gears
> doesn't implicitly inject itself into event handling, but is instead
> explicitly called by JavaScript via desktop.getClipboard(), and
> desktop.getClipboard().getFiles() is the equivalent of the ideal
> event.dataTransfer.getData('files').
>
> This (option X) is more or less exactly how Drag and Drop is
> implemented in Safari, under the hood, with Gears C++ (and
> Objective-C) doing some slight contortions to present the option X
> implementation via an option Y API. The Safari implementation would be
> simpler if we just presented an option X style API in the first place,
> and I think that the IE and Firefox C++ implementations and the
> JavaScript API will likewise be simpler and shorter.
>
> Comments?
>