mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
78882 - Dragging a bookmark into the personal toolbar causes all items to be deleted, r=ben, sr=alecf
This commit is contained in:
parent
35dcb93929
commit
f07156eb73
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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__
|
||||
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user