78882 - Dragging a bookmark into the personal toolbar causes all items to be deleted, r=ben, sr=alecf

This commit is contained in:
hewitt%netscape.com 2001-05-20 05:58:25 +00:00
parent 35dcb93929
commit f07156eb73
6 changed files with 93 additions and 32 deletions

View File

@ -34,7 +34,7 @@ native nsSize (nsSize);
interface nsIDOMDocument;
interface nsIDOMNode;
[scriptable, uuid(CBA22C53-FCCE-11d2-96D4-0060B0FB9956)]
interface nsIDragSession : nsISupports
@ -68,6 +68,12 @@ interface nsIDragSession : nsISupports
*/
readonly attribute nsIDOMDocument sourceDocument;
/**
* The dom node that was originally dragged to start the session, which will be null if the
* drag originated outside the application.
*/
readonly attribute nsIDOMNode sourceNode;
/**
* Get data from a Drag&Drop. Can be called while the drag is in process
* or after the drop has completed.

View File

@ -135,6 +135,21 @@ nsBaseDragService :: GetSourceDocument ( nsIDOMDocument** aSourceDocument )
return NS_OK;
}
//
// GetSourceNode
//
// Returns the DOM node where the drag was initiated. This will be
// nsnull if the drag began outside of our application.
//
NS_IMETHODIMP
nsBaseDragService :: GetSourceNode ( nsIDOMNode** aSourceNode )
{
*aSourceNode = mSourceNode.get();
NS_IF_ADDREF ( *aSourceNode );
return NS_OK;
}
//-------------------------------------------------------------------------
@ -157,7 +172,8 @@ NS_IMETHODIMP nsBaseDragService::InvokeDragSession (nsIDOMNode *aDOMNode, nsISup
if ( aDOMNode ) {
// stash the document of the dom node
aDOMNode->GetOwnerDocument ( getter_AddRefs(mSourceDocument) );
mSourceNode = aDOMNode;
// When the mouse goes down, the selection code starts a mouse capture. However,
// this gets in the way of determining drag feedback for things like trees because
// the event coordinates are in the wrong coord system. Turn off capture by

View File

@ -64,9 +64,9 @@ protected:
nsSize mTargetSize;
PRUint32 mDragAction;
nsCOMPtr<nsIDragTracker> mCurrentlyTracking;
nsCOMPtr<nsIDOMNode> mSourceNode;
nsCOMPtr<nsIDOMDocument> mSourceDocument; // the document at the drag source. will be null
// if it came from outside the app.
};
#endif // nsBaseDragService_h__

View File

@ -98,24 +98,27 @@ var personalToolbarObserver = {
onDrop: function (aEvent, aXferData, aDragSession)
{
var dropElement = aEvent.target.id;
var xferData = aXferData.data.split("\n");
var elementRes = RDFUtils.getResource(xferData[0]);
var dropElementRes = RDFUtils.getResource(dropElement);
var personalToolbarRes = RDFUtils.getResource("NC:PersonalToolbarFolder");
var childDB = document.getElementById("innermostBox").database;
var inner = document.getElementById("innermostBox");
var childDB = inner.database;
const kCtrContractID = "@mozilla.org/rdf/container;1";
const kCtrIID = Components.interfaces.nsIRDFContainer;
var rdfContainer = Components.classes[kCtrContractID].getService(kCtrIID);
var rdfContainer = Components.classes[kCtrContractID].createInstance(kCtrIID);
var parentContainer = this.findParentContainer(aDragSession.sourceElement);
// if dragged url is already bookmarked, remove it from current location first
var parentContainer = this.findParentContainer(aDragSession.sourceNode);
if (parentContainer)
{
rdfContainer.Init(childDB, parentContainer);
rdfContainer.RemoveElement(elementRes, true);
rdfContainer.RemoveElement(elementRes, false);
}
// determine charset of link
var linkCharset = aDragSession.sourceDocument ? aDragSession.sourceDocument.characterSet : null;
// determine title of link
var linkTitle;
if (xferData.length >= 2)
linkTitle = xferData[1]
@ -124,41 +127,50 @@ var personalToolbarObserver = {
// look up this URL's title in global history
var potentialTitle = null;
var historyDS = gRDFService.GetDataSource("rdf:history");
var historyTitleProperty = RDFUtils.getResource(NC_RDF("Name"));
var titleFromHistory = historyDS.GetTarget(elementRes, historyTitleProperty, true);
var titlePropRes = RDFUtils.getResource(NC_RDF("Name"));
var titleFromHistory = historyDS.GetTarget(elementRes, titlePropRes, true);
if (titleFromHistory)
titleFromHistory = titleFromHistory.QueryInterface(Components.interfaces.nsIRDFLiteral);
if (titleFromHistory)
potentialTitle = titleFromHistory.Value;
linkTitle = potentialTitle;
if (linkTitle)
childDB.Assert(elementRes, historyTitleProperty,
gRDFService.GetLiteral(linkTitle), true);
}
rdfContainer.Init (childDB, personalToolbarRes);
var dropIndex = rdfContainer.IndexOf(dropElementRes);
// determine the drop position
var dropPosition = this.determineDropPosition(aEvent);
var dropElement = aEvent.target.id;
var dropElementRes, dropIndex, dropPosition;
if (dropElement == "innermostBox")
{
dropElementRes = personalToolbarRes;
dropPosition = this.DROP_ON;
}
else
{
dropElementRes = RDFUtils.getResource(dropElement);
rdfContainer.Init(childDB, personalToolbarRes);
dropIndex = rdfContainer.IndexOf(dropElementRes);
if (dropPosition == undefined)
dropPosition = this.determineDropPosition(aEvent);
}
switch (dropPosition) {
case this.DROP_BEFORE:
if (dropIndex<1) dropIndex = 1;
rdfContainer.Init(childDB, personalToolbarRes);
rdfContainer.InsertElementAt(elementRes, dropIndex, true);
this.insertBookmarkAt(xferData[0], linkTitle, linkCharset, personalToolbarRes, dropIndex);
break;
case this.DROP_ON:
if (dropIndex<1) dropIndex = 1;
// do something here to drop into subfolders
rdfContainer.Init(childDB, dropElementRes);
rdfContainer.AppendElement(elementRes);
this.insertBookmarkAt(xferData[0], linkTitle, linkCharset, dropElementRes, -1);
break;
case this.DROP_AFTER:
default:
// compensate for badly calculated dropIndex
rdfContainer.Init(childDB, personalToolbarRes);
if (dropIndex < rdfContainer.GetCount()) ++dropIndex;
if (dropIndex<0) dropIndex = 0;
rdfContainer.Init (childDB, personalToolbarRes);
rdfContainer.InsertElementAt(elementRes, dropIndex+1, true);
this.insertBookmarkAt(xferData[0], linkTitle, linkCharset, personalToolbarRes, dropIndex);
break;
}
return true;
},
@ -277,6 +289,14 @@ var personalToolbarObserver = {
return RDFUtils.getResource(treeitem.id);
}
return null;
},
insertBookmarkAt: function(aURL, aTitle, aCharset, aFolderRes, aIndex)
{
const kBMSContractID = "@mozilla.org/browser/bookmarks-service;1";
const kBMSIID = Components.interfaces.nsIBookmarksService;
const kBMS = Components.classes[kBMSContractID].getService(kBMSIID);
kBMS.insertBookmarkInFolder(aURL, aTitle, aCharset, aFolderRes, aIndex);
}
};

View File

@ -45,6 +45,9 @@ interface nsIBookmarksService : nsISupports
void AddBookmarkToFolder(in string aURI, in nsIRDFResource aFolder,
in wstring aTitle, in wstring docCharSet);
void insertBookmarkInFolder(in string aURI, in wstring aTitle, in wstring docCharSet,
in nsIRDFResource aFolder, in long aIndex);
void UpdateBookmarkLastVisitedDate(in string aURL, in wstring docCharset);
string FindShortcut(in wstring aName);

View File

@ -396,7 +396,8 @@ public:
const char* aShortcutURL,
nsIRDFResource* aNodeType,
nsIRDFResource** bookmarkNode,
const PRUnichar* aCharset);
const PRUnichar* aCharset,
PRInt32 aIndex);
nsresult SetIEFavoritesRoot(const char *IEFavoritesRootURL)
{
@ -1366,7 +1367,8 @@ BookmarkParser::AddBookmark(nsCOMPtr<nsIRDFContainer> aContainer,
const char* aShortcutURL,
nsIRDFResource* aNodeType,
nsIRDFResource** bookmarkNode,
const PRUnichar* aCharset)
const PRUnichar* aCharset,
PRInt32 aIndex)
{
nsresult rv;
nsAutoString fullURL;
@ -1464,7 +1466,10 @@ BookmarkParser::AddBookmark(nsCOMPtr<nsIRDFContainer> aContainer,
}
// The last thing we do is add the bookmark to the container. This ensures the minimal amount of reflow.
rv = aContainer->AppendElement(bookmark);
if (aIndex < 0)
rv = aContainer->AppendElement(bookmark);
else
rv = aContainer->InsertElementAt(bookmark, aIndex, PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add bookmark to container");
return(rv);
}
@ -2481,6 +2486,17 @@ nsBookmarksService::AddBookmarkToFolder(const char *aURI,
nsIRDFResource *aFolder,
const PRUnichar* aTitle,
const PRUnichar *aCharset)
{
return InsertBookmarkInFolder(aURI, aTitle, aCharset, aFolder, -1);
}
NS_IMETHODIMP
nsBookmarksService::InsertBookmarkInFolder(const char *aURI,
const PRUnichar* aTitle,
const PRUnichar *aCharset,
nsIRDFResource *aFolder,
PRInt32 aIndex)
{
// XXX Constructing a parser object to do this is bad.
// We need to factor AddBookmark() into its own little
@ -2510,7 +2526,7 @@ nsBookmarksService::AddBookmarkToFolder(const char *aURI,
LL_L2I(now32, now64);
rv = parser.AddBookmark(container, aURI, aTitle, now32,
0L, 0L, nsnull, kNC_Bookmark, nsnull, aCharset);
0L, 0L, nsnull, kNC_Bookmark, nsnull, aCharset, aIndex);
if (NS_FAILED(rv)) return rv;
@ -4345,7 +4361,7 @@ nsBookmarksService::WriteBookmarksContainer(nsIRDFDataSource *ds, nsOutputFileSt
}
}
}
strm << indentation;
strm << " ";
if (isContainer == PR_TRUE)