зеркало из https://github.com/mozilla/gecko-dev.git
big rewrite of drag & drop code to fix #52519
- fix warnings - change title/url separator to "\n" - clean up image dragging - consolidate code r=jag, a=ben
This commit is contained in:
Родитель
fc538d50a5
Коммит
f526cb3b67
|
@ -429,9 +429,9 @@ function Startup()
|
|||
}
|
||||
|
||||
dump("*** Pulling out the charset\n");
|
||||
if ( window.arguments && window.arguments[1] ) {
|
||||
if ( window.arguments && window.arguments.length > 1 ) {
|
||||
if (window.arguments[1].indexOf('charset=') != -1) {
|
||||
arrayArgComponents = window.arguments[1].split('=');
|
||||
var arrayArgComponents = window.arguments[1].split('=');
|
||||
if (arrayArgComponents) {
|
||||
if (appCore != null) {
|
||||
//we should "inherit" the charset menu setting in a new window
|
||||
|
@ -1857,7 +1857,7 @@ function postURLToNativeWidget() {
|
|||
}
|
||||
|
||||
function checkForDirectoryListing() {
|
||||
if ( window._content.HTTPIndex == "[xpconnect wrapped nsIHTTPIndex]"
|
||||
if ( 'HTTPIndex' in window._content
|
||||
&&
|
||||
typeof window._content.HTTPIndex == "object"
|
||||
&&
|
||||
|
|
|
@ -101,7 +101,7 @@ var personalToolbarObserver = {
|
|||
|
||||
var flavourList = { };
|
||||
flavourList["moz/toolbaritem"] = { width: 2, data: uri };
|
||||
flavourList["text/x-moz-url"] = { width: 2, data: uri + " " + "[ TEMP TITLE ]" };
|
||||
flavourList["text/x-moz-url"] = { width: 2, data: uri + "\n" + "[ TEMP TITLE ]" };
|
||||
flavourList["text/html"] = { width: 2, data: htmlString };
|
||||
flavourList["text/unicode"] = { width: 2, data: uri };
|
||||
return flavourList;
|
||||
|
@ -282,7 +282,7 @@ var proxyIconDNDObserver = {
|
|||
var urlBar = document.getElementById("urlbar");
|
||||
var flavourList = { };
|
||||
flavourList["text/unicode"] = { width: 2, data: urlBar.value };
|
||||
flavourList["text/x-moz-url"] = { width: 2, data: urlBar.value + " " + window._content.document.title };
|
||||
flavourList["text/x-moz-url"] = { width: 2, data: urlBar.value + "\n" + window._content.document.title };
|
||||
var htmlString = "<a href=\"" + urlBar.value + "\">" + urlBar.value + "</a>";
|
||||
flavourList["text/html"] = { width: 2, data: htmlString };
|
||||
return flavourList;
|
||||
|
|
|
@ -93,7 +93,7 @@ function loadDS()
|
|||
|
||||
if (url_ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).loaded)
|
||||
{
|
||||
var ds_uri = "chrome://global/locale/builtinURLs.rdf";
|
||||
ds_uri = "chrome://global/locale/builtinURLs.rdf";
|
||||
gBuiltinUrlsDataSource = gRDFService.GetDataSource(ds_uri); // return nsIRDFDataSource
|
||||
gDataSourceLoaded = (gBuiltinUrlsDataSource != null);
|
||||
}
|
||||
|
|
|
@ -30,128 +30,110 @@ var gSourceDocument, wasDrag;
|
|||
var contentAreaDNDObserver = {
|
||||
onDragStart: function (aEvent)
|
||||
{
|
||||
dump("dragstart\n");
|
||||
var htmlstring = null;
|
||||
if (aEvent.target != aEvent.originalTarget) {
|
||||
// the node is inside an XBL widget,
|
||||
// which means it's likely the scrollbar
|
||||
|
||||
// throw an exception to avoid the drag
|
||||
if (aEvent.originalTarget.localName == "thumb")
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
|
||||
dump("Hrm..not sure if I should be dragging this " + aEvent.originalTarget.localName + ".. but I'll try.\n");
|
||||
}
|
||||
|
||||
var draggedNode = aEvent.target;
|
||||
|
||||
// the resulting strings from the beginning of the drag
|
||||
var textstring = null;
|
||||
var isLink = false;
|
||||
var urlstring = null;
|
||||
// htmlstring will be filled automatically if you fill urlstring
|
||||
var htmlstring = null;
|
||||
|
||||
var domselection = window._content.getSelection();
|
||||
if (domselection && !domselection.isCollapsed &&
|
||||
domselection.containsNode(aEvent.target,false))
|
||||
domselection.containsNode(draggedNode,false))
|
||||
{
|
||||
dump("Dragging the selection..\n");
|
||||
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
|
||||
// the window has a selection so we should grab that rather
|
||||
// than looking for specific elements
|
||||
htmlstring = privateSelection.toStringWithFormat("text/html", 128+256, 0);
|
||||
textstring = privateSelection.toStringWithFormat("text/plain", 0, 0);
|
||||
dump("we cool?\n");
|
||||
// how are we going to get the URL, if any? Scan the selection
|
||||
// for the first anchor? See bug #58315
|
||||
}
|
||||
dump("we cool?");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aEvent.altKey && this.findEnclosingLink(aEvent.target))
|
||||
dump("Dragging DOM node: <" + draggedNode.localName + ">\n");
|
||||
if (aEvent.altKey && findParentNode(draggedNode, 'a'))
|
||||
return false;
|
||||
switch (aEvent.originalTarget.localName)
|
||||
switch (draggedNode.localName.toUpperCase())
|
||||
{
|
||||
case '#text':
|
||||
var node = this.findEnclosingLink(aEvent.target);
|
||||
textstring = "";
|
||||
//select node now!
|
||||
if (node)
|
||||
textstring = node.href;
|
||||
if (textstring != "")
|
||||
{
|
||||
htmlstring = "<a href=\"" + textstring + "\">" + textstring + "</a>";
|
||||
var parent = node.parentNode;
|
||||
if (parent)
|
||||
{
|
||||
var nodelist = parent.childNodes;
|
||||
var index;
|
||||
for (index = 0; index<nodelist.length; index++)
|
||||
{
|
||||
if (nodelist.item(index) == node)
|
||||
break;
|
||||
}
|
||||
if (index >= nodelist.length)
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
if (domselection)
|
||||
{
|
||||
domselection.collapse(parent,index);
|
||||
domselection.extend(parent,index+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
break;
|
||||
case 'AREA':
|
||||
case 'IMG':
|
||||
var imgsrc = aEvent.target.getAttribute("src");
|
||||
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.
|
||||
// need to do some stuff with the window._content.location
|
||||
// (path?) to get base URL for image.
|
||||
|
||||
textstring = imgsrc;
|
||||
htmlstring = "<img src=\"" + textstring + "\">";
|
||||
if ((linkNode = this.findEnclosingLink(aEvent.target))) {
|
||||
htmlstring = '<a href="' + linkNode.href + '">' + htmlstring + '</a>';
|
||||
textstring = linkNode.href;
|
||||
// use alt text as the title of the image, if it's there
|
||||
textstring = draggedNode.getAttribute("alt");
|
||||
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) {
|
||||
urlstring = this.getAnchorUrl(linkNode);
|
||||
htmlstring = this.createLinkText(urlstring, htmlstring);
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
isLink = true;
|
||||
if (aEvent.target.href)
|
||||
{
|
||||
textstring = aEvent.target.getAttribute("href");
|
||||
htmlstring = "<a href=\"" + textstring + "\">" + textstring + "</a>";
|
||||
}
|
||||
else if (aEvent.target.name)
|
||||
{
|
||||
textstring = aEvent.target.getAttribute("name");
|
||||
htmlstring = "<a name=\"" + textstring + "\">" + textstring + "</a>"
|
||||
}
|
||||
urlstring = this.getAnchorUrl(draggedNode);
|
||||
textstring = this.getNodeString(draggedNode);
|
||||
break;
|
||||
case 'LI':
|
||||
case 'OL':
|
||||
case 'DD':
|
||||
|
||||
default:
|
||||
var node = this.findEnclosingLink(aEvent.target);
|
||||
textstring = "";
|
||||
var linkNode = findParentNode(draggedNode, 'a');
|
||||
|
||||
if (linkNode) {
|
||||
urlstring = this.getAnchorUrl(linkNode);
|
||||
textstring = this.getNodeString(linkNode);
|
||||
|
||||
// select node now!
|
||||
if (node)
|
||||
textstring = node.href;
|
||||
if (textstring != "")
|
||||
{
|
||||
htmlstring = "<a href=\"" + textstring + "\">" + textstring + "</a>";
|
||||
var parent = node.parentNode;
|
||||
if (parent)
|
||||
{
|
||||
var nodelist = parent.childNodes;
|
||||
var index;
|
||||
for (index = 0; index<nodelist.length; index++)
|
||||
{
|
||||
if (nodelist.item(index) == node)
|
||||
break;
|
||||
}
|
||||
if (index >= nodelist.length)
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
if (domselection)
|
||||
{
|
||||
domselection.collapse(parent,index);
|
||||
domselection.extend(parent,index+1);
|
||||
// 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
|
||||
dump("Couldn't normalize selection: " + ex + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// default text value is the URL
|
||||
if (!textstring) textstring = urlstring;
|
||||
|
||||
// if we haven't constructed a html version, make one now
|
||||
if (!htmlstring && urlstring)
|
||||
htmlstring = this.createLinkText(urlstring, urlstring);
|
||||
|
||||
// now create the flavour lists
|
||||
var flavourList = { };
|
||||
if (htmlstring)
|
||||
flavourList["text/html"] = { width: 2, data: htmlstring };
|
||||
if (isLink)
|
||||
flavourList["text/x-moz-url"] = { width: 2, data: textstring };
|
||||
if (urlstring)
|
||||
flavourList["text/x-moz-url"] = { width: 2,
|
||||
data: urlstring + "\n" + textstring };
|
||||
if (textstring)
|
||||
flavourList["text/unicode"] = { width: 2, data: textstring };
|
||||
return flavourList;
|
||||
},
|
||||
|
@ -168,7 +150,7 @@ var contentAreaDNDObserver = {
|
|||
|
||||
onDrop: function (aEvent, aData, aDragSession)
|
||||
{
|
||||
var data = aData.length ? aData[0] : aData;
|
||||
var data = (('length' in aData) && aData.length) ? aData[0] : aData;
|
||||
var url = retrieveURLFromData(data);
|
||||
if (url.length == 0)
|
||||
return true;
|
||||
|
@ -187,6 +169,7 @@ var contentAreaDNDObserver = {
|
|||
break;
|
||||
default:
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
getSupportedFlavours: function ()
|
||||
|
@ -198,21 +181,53 @@ var contentAreaDNDObserver = {
|
|||
return flavourList;
|
||||
},
|
||||
|
||||
findEnclosingLink: function (aNode)
|
||||
createLinkText: function(url, text)
|
||||
{
|
||||
while (aNode) {
|
||||
var nodeName = aNode.localName;
|
||||
if (!nodeName) return null;
|
||||
nodeName = nodeName.toLowerCase();
|
||||
if (!nodeName || nodeName == "body" ||
|
||||
nodeName == "html" || nodeName == "#document")
|
||||
return null;
|
||||
if (nodeName == "a")
|
||||
return aNode;
|
||||
aNode = aNode.parentNode;
|
||||
return "<a href=\"" + url + "\">" + text + "</a>";
|
||||
},
|
||||
|
||||
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;
|
||||
}
|
||||
return null;
|
||||
|
||||
if (index >= nodelist.length) {
|
||||
dump("BAD: Could not find our position in the parent\n");
|
||||
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)
|
||||
{
|
||||
if (linkNode.href)
|
||||
return linkNode.href;
|
||||
else if (linkNode.name)
|
||||
return linkNode.name
|
||||
return 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();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -957,9 +957,9 @@ function fillContextMenu(name)
|
|||
var lastWasSep = false;
|
||||
for (var commandIndex = 0; commandIndex < cmdArray.length; commandIndex++)
|
||||
{
|
||||
var cmd = cmdArray[commandIndex];
|
||||
cmd = cmdArray[commandIndex];
|
||||
if (!cmd) continue;
|
||||
var cmdResource = cmd.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
cmdResource = cmd.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
if (!cmdResource) break;
|
||||
|
||||
// handle separators
|
||||
|
|
|
@ -320,7 +320,7 @@ function DropOnTree ( event )
|
|||
else if (bestFlavor.value == "text/x-moz-url")
|
||||
{
|
||||
// pull the URL out of the data object
|
||||
var data = dataObj.data.substring(0, len.value / 2);
|
||||
data = dataObj.data.substring(0, len.value / 2);
|
||||
sourceID = data;
|
||||
|
||||
// we may need to synthesize a name (just use the URL)
|
||||
|
@ -340,11 +340,11 @@ function DropOnTree ( event )
|
|||
}
|
||||
|
||||
// pull the (optional) name out of the URL
|
||||
var space = sourceID.indexOf(" ");
|
||||
if (space >= 0)
|
||||
var separator = sourceID.indexOf("\n");
|
||||
if (separator >= 0)
|
||||
{
|
||||
name = sourceID.substr(space+1);
|
||||
sourceID = sourceID.substr(0, space);
|
||||
name = sourceID.substr(separator+1);
|
||||
sourceID = sourceID.substr(0, separator);
|
||||
}
|
||||
|
||||
dump(" Node #" + i + ": drop '" + sourceID + "'\n");
|
||||
|
@ -450,7 +450,7 @@ function DropOnTree ( event )
|
|||
try
|
||||
{
|
||||
RDFC.Init(Bookmarks, parentNode);
|
||||
var nodeIndex = RDFC.IndexOf(sourceNode);
|
||||
nodeIndex = RDFC.IndexOf(sourceNode);
|
||||
|
||||
if (nodeIndex >= 1)
|
||||
{
|
||||
|
|
|
@ -95,7 +95,7 @@ var historyDNDObserver = {
|
|||
var flavourList = { };
|
||||
flavourList["text/unicode"] = { width: 2, data: uri };
|
||||
flavourList["text/html"] = { width: 2, data: htmlString };
|
||||
flavourList["text/x-moz-url"] = { width: 2, data: uri + " " + title };
|
||||
flavourList["text/x-moz-url"] = { width: 2, data: uri + "\n" + title };
|
||||
return flavourList;
|
||||
},
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче