When I try for a pure GWT solution by adding all the drag/drop listeners to 
the RichTextArea I get the enter, a few overs, and then strangely I get the 
leave event.  The drop event never occurs.  How can I fix this?  If I can 
get the onDrop event to fire it seems I could do the same work I was doing 
in JSNI with the DropEvent object.

Console log from the various handlers...
onDragEnter: An event type
onDragOver: An event type
onDragOver: An event type
onDragOver: An event type
onDragOver: An event type
onDragLeave: An event type

-Dave

On Wednesday, May 29, 2013 6:07:29 PM UTC-6, dhoffer wrote:
>
> What is the best way to implement native DnD for RichTextArea?  I need to 
> support users dropping items into the RichTextArea that originated from 
> outside the browser (from another web app).
>
> Currently what I have partially works (in production seems to work about 
> 50% of the time) in hosted mode it's only working on the first Drop (could 
> be because of recent changes).  Currently we are doing this with JSNI. 
>  I'll paste the full code below but the key parts are that on the drop 
> event I need to get the 'text' data, e.g.
>
> var data = event.dataTransfer.getData("Text");
>
> Then I parse that data/URI and build a div which I then append to the 
> original element.
>
> Some of the things I'm not sure about are...what Document to be working 
> with.  The original code used document in the JSNI method but I see online 
> that $doc should be used.  Or I could pass into the JSNI method the 
> document, e.g. 
>
>  IFrameElement fe = getElement().cast();
>  Document document = fe.getContentDocument();
>
> Or ideally I'd prefer to do this with a more pure GWT solution and use 
> less JSNI if that's possible.  How best to respond to these native drops? 
>  Why would this code only be working for the first drop?  (Note, we have 
> several instances of this widget in the application)  Here is the full 
> code. (The first set of methods ininitDnD just parse URI...nothing 
> interesting until the allowDrop/droppedHandler/addEvent methods)
>
>
> // This will be called only once at startup.
>     protected void onInitializeOnce() {
>         super.onInitializeOnce();
>
>         Document document = getContentDocument();
>         BodyElement body = getBodyElement();
>         initDnD(document, body);
>     }
>
>  private native void initDnD(Document document, Element elem) /*-{
>
>         function strictEncodeURIComponent(string) {
>             return encodeURIComponent(string).replace(/[!'()*]/g, escape);
>         }
>
>         encode = strictEncodeURIComponent;
>         decode = decodeURIComponent;
>
>         var parseURI = function (string) {
>             var pos, t, parts = {};
>             
>             pos = string.indexOf('#');
>             if (pos > -1) {
>                 // escaping?
>                 parts.fragment = string.substring(pos + 1) || null;
>                 string = string.substring(0, pos);
>             }
>
>             // extract query
>             pos = string.indexOf('?');
>             if (pos > -1) {
>                 // escaping?
>                 parts.query = string.substring(pos + 1) || null;
>                 string = string.substring(0, pos);
>             }
>
>             // extract protocol
>             if (string.substring(0, 2) === '//') {
>                 // relative-scheme
>                 parts.protocol = '';
>                 string = string.substring(2);
>                 // extract "user:pass@host:port"
>                 string = parseURIAuthority(string, parts);
>             } else {
>                 pos = string.indexOf(':');
>                 if (pos > -1) {
>                     parts.protocol = string.substring(0, pos);
>                     if (string.substring(pos + 1, pos + 3) === '//') {
>                         string = string.substring(pos + 3);
>
>                         // extract "user:pass@host:port"
>                         string = parseURIAuthority(string, parts);
>                     } else {
>                         string = string.substring(pos + 1);
>                         parts.urn = true;
>                     }
>                 }
>             }
>
>             // what's left must be the path
>             parts.path = string;
>
>             // and we're done
>             return parts;
>         };
>         var parseURIHost = function (string, parts) {
>             // extract host:port
>             var pos = string.indexOf('/'),
>                     t;
>
>             if (pos === -1) {
>                 pos = string.length;
>             }
>
>             if (string[0] === "[") {
>                 // IPv6 host - 
> http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-04#section-6
>                 // I claim most client software breaks on IPv6 anyways. To 
> simplify things, URI only accepts
>                 // IPv6+port in the format [2001:db8::1]:80 (for the time 
> being)
>                 var bracketPos = string.indexOf(']');
>                 parts.hostname = string.substring(1, bracketPos) || null;
>                 parts.port = string.substring(bracketPos + 2, pos) || null;
>             } else if (string.indexOf(':') !== string.lastIndexOf(':')) {
>                 // IPv6 host contains multiple colons - but no port
>                 // this notation is actually not allowed by RFC 3986, but 
> we're a liberal parser
>                 parts.hostname = string.substring(0, pos) || null;
>                 parts.port = null;
>             } else {
>                 t = string.substring(0, pos).split(':');
>                 parts.hostname = t[0] || null;
>                 parts.port = t[1] || null;
>             }
>
>             if (parts.hostname && string.substring(pos)[0] !== '/') {
>                 pos++;
>                 string = "/" + string;
>             }
>
>             return string.substring(pos) || '/';
>         };
>         var parseURIAuthority = function (string, parts) {
>             string = parseURIUserinfo(string, parts);
>             return parseURIHost(string, parts);
>         };
>         var parseURIUserinfo = function (string, parts) {
>             // extract username:password
>             var pos = string.indexOf('@'),
>                     firstSlash = string.indexOf('/'),
>                     t;
>
>             // authority@ must come before /path
>             if (pos > -1 && (firstSlash === -1 || pos < firstSlash)) {
>                 t = string.substring(0, pos).split(':');
>                 parts.username = t[0] ? decode(t[0]) : null;
>                 parts.password = t[1] ? decode(t[1]) : null;
>                 string = string.substring(pos + 1);
>             } else {
>                 parts.username = null;
>                 parts.password = null;
>             }
>
>             return string;
>         };
>         var parseURIQuery = function (string) {
>             if (!string) {
>                 return {};
>             }
>
>             // throw out the funky business - "?"[name"="value"&"]+
>             string = string.replace(/&+/g, '&').replace(/^\?*&*|&+$/g, '');
>
>             if (!string) {
>                 return {};
>             }
>
>             var items = {},
>                     splits = string.split('&'),
>                     length = splits.length;
>
>             for (var i = 0; i < length; i++) {
>                 var v = splits[i].split('='),
>                         name = encodeURIQuery(v.shift()),
>                 // no "=" is null according to 
> http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#collect-url-parameters
>                         value = v.length ? decodeURIQuery(v.join('=')) : 
> null;
>
>                 if (items[name]) {
>                     if (typeof items[name] === "string") {
>                         items[name] = [items[name]];
>                     }
>
>                     items[name].push(value);
>                 } else {
>                     items[name] = value;
>                 }
>             }
>
>             return items;
>         };
>         var encodeURIQuery = function (string) {
>             return encode(string + "").replace(/%20/g, '+');
>         };
>         var decodeURIQuery = function (string) {
>             return decode((string + "").replace(/\+/g, '%20'));
>         };
>
>         function allowDrop(event) {
>             if (event.stopPropagation) {
>                 event.stopPropagation();
>             }
>             if (event.preventDefault) {
>                 event.preventDefault();
>             }
>             return false;
>         }
>
>         function droppedHandler(event) {
>             // Try to use the 'text' everytime.
>             try {
>                 alert("event= " + event);
>                 var data = event.dataTransfer.getData("Text");
>                 alert("data=" + data);
>                 if (data != null && data != "") {
>                     try {
>                         var parsedURI = parseURI(data);
>                         var urlParameters = parseURIQuery(parsedURI.query);
>                         var appsrc = urlParameters['appsrc'];
>                         if (appsrc != null && appsrc == "COREFX") {
>                             try {
>                                 // For some versions of IE, need to do 
> this to prevent duplicates.
>                                 event.dataTransfer.setData('Text', '');
>                             }
>                             catch (e) {
>                             }
>
>                             if (event.preventDefault) {
>                                 event.preventDefault();
>                             }
>
>                             var title = data;
>                             if (urlParameters['title'] != null) {
>                                 title = urlParameters['title'];
>                             }
>                             var newContentWrapper = 
> document.createElement('div');
>                             newContentWrapper.setAttribute('draggable', 
> true);
>                             newContentWrapper.setAttribute('ondragstart', 
> "dragStart(event)");
>
>                             var newContent = document.createElement('a');
>                             newContent.setAttribute('href', data);
>                             newContent.setAttribute('class', 
> "external_system");
>
>                             if (urlParameters['icon'] != null) {
>                                 var icon = 
> decodeURI(urlParameters['icon']);
>                                 var newContentIcon = 
> document.createElement('img');
>                                 newContentIcon.setAttribute('src', icon);
>                                 newContent.appendChild(newContentIcon);
>                             }
>
>                             var newContentTitle = 
> document.createTextNode(title);
>                             newContent.appendChild(newContentTitle);
>
>                             newContentWrapper.appendChild(newContent);
>                             var targetElement = event.target || 
> event.srcElement;
>                             targetElement.appendChild(newContentWrapper);
>                             return false;
>                         }
>                     }
>                     catch (e) {
>                     }
>                 }
>             }
>             catch (error) {
>             }
>             return true;
>         }
>
>         var addEvent = (function () {
>             if (document.addEventListener) {
>                 return function (el, type, fn) {
>                     if (el && el.nodeName || el === window) {
>                         el.addEventListener(type, fn, false);
>                     } else if (el && el.length) {
>                         for (var i = 0; i < el.length; i++) {
>                             addEvent(el[i], type, fn);
>                         }
>                     }
>                 };
>             } else {
>                 return function (el, type, fn) {
>                     if (el && el.nodeName || el === window) {
>                         el.attachEvent('on' + type, function (eventParam) {
>                             if (!eventParam) {
>                                 eventParam = window.event;
>                             }
>                             return fn.call(el, eventParam);
>                         });
>                     } else if (el && el.length) {
>                         for (var i = 0; i < el.length; i++) {
>                             addEvent(el[i], type, fn);
>                         }
>                     }
>                 };
>             }
>         })();
>         addEvent(elem, 'drop', droppedHandler);
>         addEvent(elem, 'dragover', allowDrop);
>     }-*/;
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to