From f526cb3b674635ebb997e2c7913ef36b7a16c43c Mon Sep 17 00:00:00 2001 From: "alecf%netscape.com" Date: Fri, 10 Nov 2000 02:54:17 +0000 Subject: [PATCH] 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 --- xpfe/browser/resources/content/navigator.js | 6 +- xpfe/browser/resources/content/navigatorDD.js | 4 +- .../resources/content/builtinURLs.js | 2 +- .../resources/content/contentAreaDD.js | 243 ++++++++++-------- .../bookmarks/resources/bookmarks.js | 4 +- .../bookmarks/resources/bookmarksDD.js | 12 +- xpfe/components/history/resources/history.js | 4 +- 7 files changed, 145 insertions(+), 130 deletions(-) diff --git a/xpfe/browser/resources/content/navigator.js b/xpfe/browser/resources/content/navigator.js index 862ee49ca6c5..9ea0f81f3d51 100644 --- a/xpfe/browser/resources/content/navigator.js +++ b/xpfe/browser/resources/content/navigator.js @@ -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" && diff --git a/xpfe/browser/resources/content/navigatorDD.js b/xpfe/browser/resources/content/navigatorDD.js index b8bb21a70307..80bcbbb63ccf 100644 --- a/xpfe/browser/resources/content/navigatorDD.js +++ b/xpfe/browser/resources/content/navigatorDD.js @@ -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 = "" + urlBar.value + ""; flavourList["text/html"] = { width: 2, data: htmlString }; return flavourList; diff --git a/xpfe/communicator/resources/content/builtinURLs.js b/xpfe/communicator/resources/content/builtinURLs.js index d8a44f86fc69..53b7d7878553 100644 --- a/xpfe/communicator/resources/content/builtinURLs.js +++ b/xpfe/communicator/resources/content/builtinURLs.js @@ -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); } diff --git a/xpfe/communicator/resources/content/contentAreaDD.js b/xpfe/communicator/resources/content/contentAreaDD.js index 4d6176f32bc1..202d884066bc 100644 --- a/xpfe/communicator/resources/content/contentAreaDD.js +++ b/xpfe/communicator/resources/content/contentAreaDD.js @@ -29,130 +29,112 @@ 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 = "" + textstring + ""; - var parent = node.parentNode; - if (parent) - { - var nodelist = parent.childNodes; - var index; - for (index = 0; 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 = ""; - if ((linkNode = this.findEnclosingLink(aEvent.target))) { - htmlstring = '' + htmlstring + ''; - textstring = linkNode.href; + // use alt text as the title of the image, if it's there + textstring = draggedNode.getAttribute("alt"); + urlstring = imgsrc; + htmlstring = ""; + + // 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 = "" + textstring + ""; - } - else if (aEvent.target.name) - { - textstring = aEvent.target.getAttribute("name"); - htmlstring = "" + textstring + "" - } + urlstring = this.getAnchorUrl(draggedNode); + textstring = this.getNodeString(draggedNode); break; - case 'LI': - case 'OL': - case 'DD': + default: - var node = this.findEnclosingLink(aEvent.target); - textstring = ""; - //select node now! - if (node) - textstring = node.href; - if (textstring != "") - { - htmlstring = "" + textstring + ""; - var parent = node.parentNode; - if (parent) - { - var nodelist = parent.childNodes; - var index; - for (index = 0; index= nodelist.length) - throw Components.results.NS_ERROR_FAILURE; - if (domselection) - { - domselection.collapse(parent,index); - domselection.extend(parent,index+1); - } + var linkNode = findParentNode(draggedNode, 'a'); + + if (linkNode) { + urlstring = this.getAnchorUrl(linkNode); + textstring = 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 + 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 = { }; - flavourList["text/html"] = { width: 2, data: htmlstring }; - if (isLink) - flavourList["text/x-moz-url"] = { width: 2, data: textstring }; - flavourList["text/unicode"] = { width: 2, data: textstring }; + if (htmlstring) + flavourList["text/html"] = { width: 2, data: htmlstring }; + 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,32 +181,64 @@ var contentAreaDNDObserver = { return flavourList; }, - findEnclosingLink: function (aNode) - { - 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 null; + createLinkText: function(url, text) + { + return "" + text + ""; + }, + + 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) { + 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(); + } + }; function retrieveURLFromData (aData) { switch (aData.flavour) { - case "text/unicode": - case "text/x-moz-url": - return aData.data.data; // XXX this is busted. - break; - case "application/x-moz-file": + case "text/unicode": + case "text/x-moz-url": + return aData.data.data; // XXX this is busted. + break; + case "application/x-moz-file": var dataObj = aData.data.data.QueryInterface(Components.interfaces.nsIFile); if (dataObj) { var fileURL = nsJSComponentManager.createInstance("@mozilla.org/network/standard-url;1", diff --git a/xpfe/components/bookmarks/resources/bookmarks.js b/xpfe/components/bookmarks/resources/bookmarks.js index d9534d6397ce..72bf951b0389 100644 --- a/xpfe/components/bookmarks/resources/bookmarks.js +++ b/xpfe/components/bookmarks/resources/bookmarks.js @@ -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 diff --git a/xpfe/components/bookmarks/resources/bookmarksDD.js b/xpfe/components/bookmarks/resources/bookmarksDD.js index 5a037b795553..3d0416cf42a0 100644 --- a/xpfe/components/bookmarks/resources/bookmarksDD.js +++ b/xpfe/components/bookmarks/resources/bookmarksDD.js @@ -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) { diff --git a/xpfe/components/history/resources/history.js b/xpfe/components/history/resources/history.js index 7a5db14cbc7a..3bd3ffe7a959 100644 --- a/xpfe/components/history/resources/history.js +++ b/xpfe/components/history/resources/history.js @@ -95,8 +95,8 @@ 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; }, -}; \ No newline at end of file +};