зеркало из https://github.com/mozilla/gecko-dev.git
pulling content-area drag&drop out of JS and into C++ so it is available to embedding. Now built-in to <browser> tag. r=brade/sr=ben. bug#45605
This commit is contained in:
Родитель
a57b218080
Коммит
af7a046424
|
@ -39,171 +39,16 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* Note that most of this routine has been moved into C++ in order to
|
||||
* be available for all <browser> tags as well as gecko embedding. See
|
||||
* mozilla/content/base/src/nsContentAreaDragDrop.cpp.
|
||||
*
|
||||
* Do not add any new fuctionality here other than what is needed for
|
||||
* a standalone product.
|
||||
*/
|
||||
|
||||
var contentAreaDNDObserver = {
|
||||
onDragStart: function (aEvent, aXferData, aDragAction)
|
||||
{
|
||||
if (aEvent.getPreventDefault())
|
||||
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;
|
||||
|
||||
var draggedNode = aEvent.target;
|
||||
|
||||
// the resulting strings from the beginning of the drag
|
||||
var titlestring = null;
|
||||
var urlstring = null;
|
||||
// htmlstring will be filled automatically if you fill urlstring
|
||||
var htmlstring = null;
|
||||
var isAnchor = false;
|
||||
var domselection = aEvent.view.getSelection();
|
||||
if (domselection && !domselection.isCollapsed &&
|
||||
domselection.containsNode(draggedNode,false))
|
||||
{
|
||||
// track down the anchor node, if any
|
||||
|
||||
var firstAnchor = this.findFirstAnchor(domselection.anchorNode);
|
||||
|
||||
if (firstAnchor && domselection.containsNode(firstAnchor,false)) {
|
||||
isAnchor = true;
|
||||
urlstring = firstAnchor.href;
|
||||
}
|
||||
|
||||
var privateSelection = domselection.QueryInterface(Components.interfaces.nsISelectionPrivate);
|
||||
if (privateSelection)
|
||||
{
|
||||
|
||||
// the window has a selection so we should grab that rather
|
||||
// than looking for specific elements
|
||||
htmlstring = privateSelection.toStringWithFormat("text/html", 128+256, 0);
|
||||
titlestring = privateSelection.toStringWithFormat("text/plain", 0, 0);
|
||||
} else {
|
||||
titlestring = domselection.toString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aEvent.altKey && findParentNode(draggedNode, 'a'))
|
||||
return false;
|
||||
|
||||
var local_name = draggedNode.localName;
|
||||
|
||||
if (local_name) {
|
||||
local_name.toUpperCase();
|
||||
}
|
||||
|
||||
switch (local_name)
|
||||
{
|
||||
case 'AREA':
|
||||
var areasrc = draggedNode.getAttribute("href");
|
||||
|
||||
// use alt text as the title of the area, if it's there
|
||||
titlestring = draggedNode.getAttribute("alt");
|
||||
urlstring = areasrc;
|
||||
if (!titlestring)
|
||||
titlestring = urlstring;
|
||||
htmlstring = "<img src=\"" + urlstring + "\">";
|
||||
break;
|
||||
case 'IMG':
|
||||
var imgsrc = draggedNode.getAttribute("src");
|
||||
// var baseurl = window._content.location.href;
|
||||
// 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
|
||||
titlestring = draggedNode.getAttribute("alt");
|
||||
urlstring = imgsrc;
|
||||
if (!titlestring)
|
||||
titlestring = urlstring;
|
||||
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) {
|
||||
isAnchor = true;
|
||||
urlstring = this.getAnchorUrl(linkNode);
|
||||
htmlstring = this.createLinkText(urlstring, htmlstring);
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
urlstring = this.getAnchorUrl(draggedNode);
|
||||
titlestring = this.getNodeString(draggedNode);
|
||||
// this causes d&d problems on windows -- see bug 68058
|
||||
//aDragAction.action = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
||||
isAnchor = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
var linkNode = findParentNode(draggedNode, 'a');
|
||||
|
||||
if (linkNode) {
|
||||
urlstring = this.getAnchorUrl(linkNode);
|
||||
titlestring = this.getNodeString(linkNode);
|
||||
// select node now!
|
||||
// this shouldn't be fatal, and
|
||||
// we should still do the drag if this fails
|
||||
try {
|
||||
this.normalizeSelection(linkNode, domselection);
|
||||
} catch (ex) {
|
||||
// non-fatal, so catch & ignore
|
||||
}
|
||||
|
||||
isAnchor = true;
|
||||
// this causes d&d problems on windows -- see bug 68058
|
||||
//aDragAction.action = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
||||
}
|
||||
else {
|
||||
// Need to throw to indicate that the drag target should not
|
||||
// allow drags.
|
||||
throw Components.results.NS_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// default text value is the URL
|
||||
if (!titlestring) titlestring = urlstring;
|
||||
|
||||
// if we haven't constructed a html version, make one now
|
||||
if (!htmlstring && urlstring)
|
||||
htmlstring = this.createLinkText(urlstring, titlestring);
|
||||
|
||||
// now create the flavour lists
|
||||
aXferData.data = new TransferData();
|
||||
if (urlstring && isAnchor) {
|
||||
aXferData.data.addDataForFlavour("text/x-moz-url", urlstring + "\n" + titlestring);
|
||||
}
|
||||
|
||||
aXferData.data.addDataForFlavour("text/unicode", isAnchor ? urlstring : titlestring);
|
||||
aXferData.data.addDataForFlavour("text/html", htmlstring);
|
||||
|
||||
// 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.
|
||||
return true;
|
||||
},
|
||||
|
||||
onDragOver: function (aEvent, aFlavour, aDragSession)
|
||||
{
|
||||
if (aEvent.getPreventDefault())
|
||||
return;
|
||||
|
||||
// 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) {
|
||||
aDragSession.canDrop = false;
|
||||
return;
|
||||
}
|
||||
// this causes d&d problems on windows -- see bug 68058
|
||||
//aDragSession.dragAction = Components.interfaces.nsIDragService.DRAGDROP_ACTION_LINK;
|
||||
},
|
||||
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
{
|
||||
var url = retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
|
||||
|
@ -220,6 +65,10 @@ var contentAreaDNDObserver = {
|
|||
viewSource(url);
|
||||
break;
|
||||
}
|
||||
|
||||
// keep the event from being handled by the dragDrop listeners
|
||||
// built-in to gecko if they happen to be above us.
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
|
||||
getSupportedFlavours: function ()
|
||||
|
@ -230,66 +79,6 @@ var contentAreaDNDObserver = {
|
|||
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
|
||||
return flavourSet;
|
||||
},
|
||||
|
||||
createLinkText: function(url, text)
|
||||
{
|
||||
return "<a href=\"" + url + "\">" + text + "</a>";
|
||||
},
|
||||
|
||||
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;
|
||||
},
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
return linkNode.href || linkNode.name || null;
|
||||
},
|
||||
|
||||
getNodeString: function(node)
|
||||
{
|
||||
// use a range to get the text-equivalent of the node
|
||||
var range = document.createRange();
|
||||
range.selectNode(node);
|
||||
return range.toString();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче