2006-07-29 09:38:04 +04:00
|
|
|
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
2006-07-29 09:33:03 +04:00
|
|
|
*
|
2006-07-29 09:38:04 +04:00
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.1 (the "License"); you may not use this file except in
|
|
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/NPL/
|
2006-07-29 09:33:03 +04:00
|
|
|
*
|
2006-07-29 09:38:04 +04:00
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
2006-07-29 09:33:03 +04:00
|
|
|
*
|
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
2006-07-29 09:38:04 +04:00
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
2006-07-29 09:33:03 +04:00
|
|
|
*
|
2006-07-29 09:38:04 +04:00
|
|
|
* Contributor(s):
|
2006-07-29 09:33:03 +04:00
|
|
|
* Alec Flett <alecf@netscape.com>
|
|
|
|
* Ben Goodger <ben@netscape.com>
|
|
|
|
* Mike Pinkerton <pinkerton@netscape.com>
|
|
|
|
* Blake Ross <blakeross@telocity.com>
|
2006-07-29 09:38:04 +04:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the NPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the NPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
2006-07-29 09:33:03 +04:00
|
|
|
|
|
|
|
var contentAreaDNDObserver = {
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
onDragStart: function (aEvent, aXferData, aDragAction)
|
2006-07-29 09:34:46 +04:00
|
|
|
{
|
2006-07-29 09:36:53 +04:00
|
|
|
if (aEvent.getPreventDefault())
|
2006-07-29 09:34:47 +04:00
|
|
|
throw Components.results.NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
// only drag form elements by using the alt key,
|
|
|
|
// otherwise buttons and select widgets are hard to use
|
|
|
|
if ('form' in aEvent.target && !aEvent.altKey)
|
|
|
|
throw Components.results.NS_ERROR_FAILURE;
|
2006-07-29 09:34:46 +04:00
|
|
|
|
|
|
|
var draggedNode = aEvent.target;
|
|
|
|
|
|
|
|
// the resulting strings from the beginning of the drag
|
2006-07-29 09:35:41 +04:00
|
|
|
var titlestring = null;
|
2006-07-29 09:34:46 +04:00
|
|
|
var urlstring = null;
|
|
|
|
// htmlstring will be filled automatically if you fill urlstring
|
|
|
|
var htmlstring = null;
|
2006-07-29 09:37:00 +04:00
|
|
|
var isAnchor = false;
|
2006-07-29 09:36:55 +04:00
|
|
|
var domselection = aEvent.view.getSelection();
|
2006-07-29 09:33:03 +04:00
|
|
|
if (domselection && !domselection.isCollapsed &&
|
2006-07-29 09:34:46 +04:00
|
|
|
domselection.containsNode(draggedNode,false))
|
2006-07-29 09:33:03 +04:00
|
|
|
{
|
2006-07-29 09:36:53 +04:00
|
|
|
// track down the anchor node, if any
|
2006-07-29 09:35:50 +04:00
|
|
|
|
2006-07-29 09:36:53 +04:00
|
|
|
var firstAnchor = this.findFirstAnchor(domselection.anchorNode);
|
|
|
|
|
2006-07-29 09:37:00 +04:00
|
|
|
if (firstAnchor && domselection.containsNode(firstAnchor,false)) {
|
|
|
|
isAnchor = true;
|
2006-07-29 09:36:53 +04:00
|
|
|
urlstring = firstAnchor.href;
|
2006-07-29 09:37:00 +04:00
|
|
|
}
|
|
|
|
|
2006-07-29 09:33:03 +04:00
|
|
|
var privateSelection = domselection.QueryInterface(Components.interfaces.nsISelectionPrivate);
|
|
|
|
if (privateSelection)
|
|
|
|
{
|
2006-07-29 09:36:35 +04:00
|
|
|
|
2006-07-29 09:34:46 +04:00
|
|
|
// the window has a selection so we should grab that rather
|
|
|
|
// than looking for specific elements
|
2006-07-29 09:33:03 +04:00
|
|
|
htmlstring = privateSelection.toStringWithFormat("text/html", 128+256, 0);
|
2006-07-29 09:35:41 +04:00
|
|
|
titlestring = privateSelection.toStringWithFormat("text/plain", 0, 0);
|
2006-07-29 09:36:53 +04:00
|
|
|
} else {
|
|
|
|
titlestring = domselection.toString();
|
2006-07-29 09:33:03 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-07-29 09:34:46 +04:00
|
|
|
if (aEvent.altKey && findParentNode(draggedNode, 'a'))
|
2006-07-29 09:33:03 +04:00
|
|
|
return false;
|
2006-07-29 09:38:12 +04:00
|
|
|
|
|
|
|
var local_name = draggedNode.localName;
|
|
|
|
|
|
|
|
if (local_name) {
|
|
|
|
local_name.toUpperCase();
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (local_name)
|
2006-07-29 09:33:03 +04:00
|
|
|
{
|
|
|
|
case 'AREA':
|
|
|
|
case 'IMG':
|
2006-07-29 09:34:46 +04:00
|
|
|
var imgsrc = draggedNode.getAttribute("src");
|
2006-07-29 09:33:03 +04:00
|
|
|
var baseurl = window._content.location.href;
|
2006-07-29 09:34:46 +04:00
|
|
|
// need to do some stuff with the window._content.location
|
|
|
|
// (path?) to get base URL for image.
|
|
|
|
|
|
|
|
// use alt text as the title of the image, if it's there
|
2006-07-29 09:35:41 +04:00
|
|
|
titlestring = draggedNode.getAttribute("alt");
|
2006-07-29 09:34:46 +04:00
|
|
|
urlstring = imgsrc;
|
|
|
|
htmlstring = "<img src=\"" + urlstring + "\">";
|
|
|
|
|
|
|
|
// if the image is also a link, then re-wrap htmlstring in
|
|
|
|
// an anchor tag
|
|
|
|
linkNode = findParentNode(draggedNode, 'a');
|
|
|
|
if (linkNode) {
|
2006-07-29 09:35:41 +04:00
|
|
|
isAnchor = true;
|
2006-07-29 09:34:46 +04:00
|
|
|
urlstring = this.getAnchorUrl(linkNode);
|
|
|
|
htmlstring = this.createLinkText(urlstring, htmlstring);
|
2006-07-29 09:33:03 +04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'A':
|
2006-07-29 09:34:46 +04:00
|
|
|
urlstring = this.getAnchorUrl(draggedNode);
|
2006-07-29 09:35:41 +04:00
|
|
|
titlestring = this.getNodeString(draggedNode);
|
|
|
|
// this causes d&d problems on windows -- see bug 68058
|
|
|
|
//aDragAction.action = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
|
|
|
isAnchor = true;
|
2006-07-29 09:33:03 +04:00
|
|
|
break;
|
2006-07-29 09:34:46 +04:00
|
|
|
|
2006-07-29 09:33:03 +04:00
|
|
|
default:
|
2006-07-29 09:34:46 +04:00
|
|
|
var linkNode = findParentNode(draggedNode, 'a');
|
|
|
|
|
|
|
|
if (linkNode) {
|
|
|
|
urlstring = this.getAnchorUrl(linkNode);
|
2006-07-29 09:35:41 +04:00
|
|
|
titlestring = this.getNodeString(linkNode);
|
2006-07-29 09:34:46 +04:00
|
|
|
// select node now!
|
|
|
|
// this shouldn't be fatal, and
|
|
|
|
// we should still do the drag if this fails
|
|
|
|
try {
|
2006-07-29 09:35:41 +04:00
|
|
|
this.normalizeSelection(linkNode, domselection);
|
2006-07-29 09:34:46 +04:00
|
|
|
} catch (ex) {
|
|
|
|
// non-fatal, so catch & ignore
|
2006-07-29 09:33:03 +04:00
|
|
|
}
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
|
2006-07-29 09:35:41 +04:00
|
|
|
isAnchor = true;
|
|
|
|
// this causes d&d problems on windows -- see bug 68058
|
|
|
|
//aDragAction.action = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
2006-07-29 09:33:03 +04:00
|
|
|
}
|
2006-07-29 09:34:49 +04:00
|
|
|
else {
|
|
|
|
// Need to throw to indicate that the drag target should not
|
|
|
|
// allow drags.
|
|
|
|
throw Components.results.NS_OK;
|
|
|
|
}
|
2006-07-29 09:33:03 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-07-29 09:34:46 +04:00
|
|
|
|
|
|
|
// default text value is the URL
|
2006-07-29 09:35:41 +04:00
|
|
|
if (!titlestring) titlestring = urlstring;
|
2006-07-29 09:34:46 +04:00
|
|
|
|
|
|
|
// if we haven't constructed a html version, make one now
|
|
|
|
if (!htmlstring && urlstring)
|
2006-07-29 09:37:00 +04:00
|
|
|
htmlstring = this.createLinkText(urlstring, titlestring);
|
2006-07-29 09:34:46 +04:00
|
|
|
|
|
|
|
// now create the flavour lists
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
aXferData.data = new TransferData();
|
2006-07-29 09:37:28 +04:00
|
|
|
if (urlstring && isAnchor) {
|
2006-07-29 09:36:56 +04:00
|
|
|
aXferData.data.addDataForFlavour("text/x-moz-url", urlstring + "\n" + titlestring);
|
2006-07-29 09:36:59 +04:00
|
|
|
}
|
2006-07-29 09:37:28 +04:00
|
|
|
|
|
|
|
aXferData.data.addDataForFlavour("text/unicode", isAnchor ? urlstring : titlestring);
|
|
|
|
aXferData.data.addDataForFlavour("text/html", htmlstring);
|
|
|
|
|
2006-07-29 09:35:41 +04:00
|
|
|
// we use the url for text/unicode data if an anchor is being dragged, rather than
|
|
|
|
// the title text of the link or the alt text for an anchor image.
|
2006-07-29 09:38:11 +04:00
|
|
|
return true;
|
2006-07-29 09:33:03 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
onDragOver: function (aEvent, aFlavour, aDragSession)
|
|
|
|
{
|
2006-07-29 09:35:51 +04:00
|
|
|
if (aEvent.getPreventDefault())
|
|
|
|
return;
|
|
|
|
|
2006-07-29 09:36:55 +04:00
|
|
|
// if the drag originated w/in this content area, bail
|
|
|
|
// early. This avoids loading a URL dragged from the content
|
|
|
|
// area into the very same content area (which is almost never
|
|
|
|
// the desired action). This code is a bit too simplistic and
|
|
|
|
// may have problems with nested frames, but that's not my
|
|
|
|
// problem ;)
|
|
|
|
if (aDragSession.sourceDocument == aEvent.view.document) {
|
2006-07-29 09:33:03 +04:00
|
|
|
aDragSession.canDrop = false;
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
return;
|
|
|
|
}
|
2006-07-29 09:35:41 +04:00
|
|
|
// this causes d&d problems on windows -- see bug 68058
|
|
|
|
//aDragSession.dragAction = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
2006-07-29 09:33:03 +04:00
|
|
|
},
|
|
|
|
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
onDrop: function (aEvent, aXferData, aDragSession)
|
2006-07-29 09:33:03 +04:00
|
|
|
{
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
var url = retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
|
|
|
|
|
2006-07-29 09:33:03 +04:00
|
|
|
// valid urls don't contain spaces ' '; if we have a space it isn't a valid url so bail out
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
if (!url || !url.length || url.indexOf(" ", 0) != -1)
|
|
|
|
return;
|
|
|
|
|
2006-07-29 09:33:03 +04:00
|
|
|
switch (document.firstChild.getAttribute('windowtype')) {
|
|
|
|
case "navigator:browser":
|
2006-07-29 09:35:45 +04:00
|
|
|
loadURI(getShortcutOrURI(url));
|
2006-07-29 09:33:03 +04:00
|
|
|
break;
|
|
|
|
case "navigator:view-source":
|
|
|
|
viewSource(url);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
getSupportedFlavours: function ()
|
|
|
|
{
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
var flavourSet = new FlavourSet();
|
|
|
|
flavourSet.appendFlavour("text/x-moz-url");
|
|
|
|
flavourSet.appendFlavour("text/unicode");
|
2006-07-29 09:36:57 +04:00
|
|
|
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
return flavourSet;
|
2006-07-29 09:33:03 +04:00
|
|
|
},
|
|
|
|
|
2006-07-29 09:34:46 +04:00
|
|
|
createLinkText: function(url, text)
|
|
|
|
{
|
|
|
|
return "<a href=\"" + url + "\">" + text + "</a>";
|
|
|
|
},
|
|
|
|
|
2006-07-29 09:36:53 +04:00
|
|
|
findFirstAnchor: function(node)
|
|
|
|
{
|
|
|
|
if (!node) return null;
|
|
|
|
|
|
|
|
while (node) {
|
|
|
|
if (node.nodeType == Node.ELEMENT_NODE &&
|
|
|
|
node.localName.toLowerCase() == "a")
|
|
|
|
return node;
|
|
|
|
|
|
|
|
var childResult = this.findFirstAnchor(node.firstChild);
|
|
|
|
if (childResult)
|
|
|
|
return childResult;
|
|
|
|
|
|
|
|
node = node.nextSibling;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
|
2006-07-29 09:34:46 +04:00
|
|
|
normalizeSelection: function(baseNode, domselection)
|
|
|
|
{
|
|
|
|
var parent = baseNode.parentNode;
|
|
|
|
if (!parent) return;
|
|
|
|
if (!domselection) return;
|
|
|
|
|
|
|
|
var nodelist = parent.childNodes;
|
|
|
|
var index;
|
|
|
|
for (index = 0; index<nodelist.length; index++)
|
|
|
|
{
|
|
|
|
if (nodelist.item(index) == baseNode)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (index >= nodelist.length) {
|
|
|
|
throw Components.results.NS_ERROR_FAILURE;
|
2006-07-29 09:33:03 +04:00
|
|
|
}
|
2006-07-29 09:34:46 +04:00
|
|
|
|
|
|
|
// now make the selection contain all of the parent's children up to
|
|
|
|
// the selected one
|
|
|
|
domselection.collapse(parent,index);
|
|
|
|
domselection.extend(parent,index+1);
|
|
|
|
},
|
|
|
|
|
|
|
|
getAnchorUrl: function(linkNode)
|
|
|
|
{
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
return linkNode.href || linkNode.name || null;
|
2006-07-29 09:34:46 +04:00
|
|
|
},
|
|
|
|
|
|
|
|
getNodeString: function(node)
|
|
|
|
{
|
|
|
|
// use a range to get the text-equivalent of the node
|
|
|
|
var range = document.createRange();
|
|
|
|
range.selectNode(node);
|
|
|
|
return range.toString();
|
|
|
|
}
|
|
|
|
|
2006-07-29 09:33:03 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
function retrieveURLFromData (aData, flavour)
|
2006-07-29 09:33:03 +04:00
|
|
|
{
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
switch (flavour) {
|
2006-07-29 09:34:46 +04:00
|
|
|
case "text/unicode":
|
2006-07-29 09:34:47 +04:00
|
|
|
// this might not be a url, but we'll return it anyway
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
return aData;
|
2006-07-29 09:34:46 +04:00
|
|
|
case "text/x-moz-url":
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
var data = aData.toString();
|
2006-07-29 09:34:47 +04:00
|
|
|
var separator = data.indexOf("\n");
|
|
|
|
if (separator != -1)
|
|
|
|
data = data.substr(0, separator);
|
|
|
|
return data;
|
2006-07-29 09:34:46 +04:00
|
|
|
case "application/x-moz-file":
|
2006-07-29 09:37:02 +04:00
|
|
|
return aData.URL;
|
2006-07-29 09:33:03 +04:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
Bookmarks Window Updates, includes fixes for
27495, 38004, 42080, 43146, 43753, 47494, 50835, 53403, 55447, 55448, 55787
r=blake, a=hyatt
2006-07-29 09:35:40 +04:00
|
|
|
|
|
|
|
|