mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Part of fix for bug # 25876: bookmarks drag&drop behavior modification. Approval: jevering Review: pinkerton
This commit is contained in:
parent
df001914ec
commit
7ba13725d3
@ -69,8 +69,10 @@ nsMimeMapperMac :: MapMimeTypeToMacOSType ( const char* aMimeStr, PRBool inAddIf
|
||||
|
||||
// first check if it is already in our list.
|
||||
for ( MimeMapConstIterator it = mMappings.begin(); it != mMappings.end(); ++it ) {
|
||||
if ( it->second == aMimeStr )
|
||||
if ( it->second == aMimeStr ) {
|
||||
format = it->first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if it's not there, do a mapping and put it there. Some things we want to map
|
||||
|
@ -77,3 +77,39 @@ function OpenBookmarkURL(node, datasources)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getAbsoluteID(root, node)
|
||||
{
|
||||
var url = node.getAttribute("ref");
|
||||
if ((url == null) || (url == ""))
|
||||
{
|
||||
url = node.getAttribute("id");
|
||||
}
|
||||
try
|
||||
{
|
||||
var rootNode = document.getElementById(root);
|
||||
var ds = null;
|
||||
if (rootNode)
|
||||
{
|
||||
ds = rootNode.database;
|
||||
}
|
||||
|
||||
// add support for anonymous resources such as Internet Search results,
|
||||
// IE favorites under Win32, and NetPositive URLs under BeOS
|
||||
var rdf = Components.classes["component://netscape/rdf/rdf-service"].getService();
|
||||
if (rdf) rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService);
|
||||
if (rdf && ds)
|
||||
{
|
||||
var src = rdf.GetResource(url, true);
|
||||
var prop = rdf.GetResource("http://home.netscape.com/NC-rdf#URL", true);
|
||||
var target = ds.GetTarget(src, prop, true);
|
||||
if (target) target = target.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
if (target) target = target.Value;
|
||||
if (target) url = target;
|
||||
}
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
return(url);
|
||||
}
|
||||
|
@ -29,9 +29,11 @@
|
||||
xmlns:html="http://www.w3.org/TR/REC-html40"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
ondraggesture="return TopLevelDrag(event);"
|
||||
align="vertical">
|
||||
|
||||
<html:script src="chrome://bookmarks/content/bm-panel.js" />
|
||||
<html:script src="chrome://bookmarks/content/bookmarksDD.js"/>
|
||||
|
||||
<html:div style="width:100px;height:100px" flex="1">
|
||||
|
||||
@ -42,6 +44,9 @@
|
||||
<tree id="bookmarksTree" context="contextual" ref="NC:BookmarksRoot"
|
||||
style="height: 100%; width:100%;"
|
||||
multiple="true"
|
||||
ondragover="return DragOverTree(event);"
|
||||
ondraggesture="return BeginDragTree(event);"
|
||||
ondragdrop="return DropOnTree(event);"
|
||||
datasources="rdf:bookmarks rdf:files rdf:localsearch rdf:internetsearch"
|
||||
onclick="return clicked(event, event.target.parentNode.parentNode)">
|
||||
|
||||
|
@ -45,9 +45,13 @@ catch (ex) {
|
||||
}
|
||||
|
||||
|
||||
// XXX this currently controls whether bookmarks D&D is enabled or not
|
||||
gDragDropEnabled = true;
|
||||
|
||||
|
||||
function TopLevelDrag ( event )
|
||||
{
|
||||
debug("TOP LEVEL bookmarks window got a drag");
|
||||
dump("TOP LEVEL bookmarks window got a drag");
|
||||
return(true);
|
||||
}
|
||||
|
||||
@ -72,10 +76,6 @@ function BeginDragTree ( event )
|
||||
|
||||
var dragStarted = false;
|
||||
|
||||
var dragService =
|
||||
Components.classes["component://netscape/widget/dragservice"].getService(Components.interfaces.nsIDragService);
|
||||
if ( !dragService ) return(false);
|
||||
|
||||
var trans =
|
||||
Components.classes["component://netscape/widget/transferable"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( !trans ) return(false);
|
||||
@ -84,14 +84,36 @@ function BeginDragTree ( event )
|
||||
Components.classes["component://netscape/supports-wstring"].createInstance(Components.interfaces.nsISupportsWString);
|
||||
if (!genData) return(false);
|
||||
|
||||
var genDataURL =
|
||||
Components.classes["component://netscape/supports-wstring"].createInstance(Components.interfaces.nsISupportsWString);
|
||||
if (!genDataURL) return(false);
|
||||
|
||||
trans.addDataFlavor("text/unicode");
|
||||
trans.addDataFlavor("moz/rdfitem");
|
||||
|
||||
// id (url) is on the <treeitem> which is two levels above the <treecell> which is
|
||||
// ref/id (url) is on the <treeitem> which is two levels above the <treecell> which is
|
||||
// the target of the event.
|
||||
var id = event.target.parentNode.parentNode.getAttribute("id");
|
||||
genData.data = id;
|
||||
genTextData.data = id;
|
||||
debug("ID: " + id);
|
||||
var id = event.target.parentNode.parentNode.getAttribute("ref");
|
||||
if (!id || id=="")
|
||||
{
|
||||
id = event.target.parentNode.parentNode.getAttribute("id");
|
||||
}
|
||||
dump("\n ID: " + id);
|
||||
|
||||
var parentID = event.target.parentNode.parentNode.parentNode.parentNode.getAttribute("ref");
|
||||
if (!parentID || parentID == "")
|
||||
{
|
||||
parentID = event.target.parentNode.parentNode.parentNode.parentNode.getAttribute("id");
|
||||
}
|
||||
dump(" Parent ID: " + parentID);
|
||||
|
||||
var trueID = id;
|
||||
if (parentID != null)
|
||||
{
|
||||
trueID += "\n" + parentID;
|
||||
}
|
||||
genData.data = trueID;
|
||||
genDataURL.data = id;
|
||||
|
||||
var database = childWithDatabase.database;
|
||||
var rdf =
|
||||
@ -106,15 +128,15 @@ function BeginDragTree ( event )
|
||||
if (target) target = target.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
if (target) target = target.Value;
|
||||
if ((!target) || (target == "")) {dump("BAD\n"); return(false);}
|
||||
debug("Type: '" + target + "'");
|
||||
dump(" Type: '" + target + "'");
|
||||
|
||||
if ((target != "http://home.netscape.com/NC-rdf#BookmarkSeparator") &&
|
||||
(target != "http://home.netscape.com/NC-rdf#Bookmark") &&
|
||||
(target != "http://home.netscape.com/NC-rdf#Folder")) return(false);
|
||||
|
||||
|
||||
// trans.setTransferData ( "moz/toolbaritem", genData, id.length*2 ); // double byte data (len*2)
|
||||
trans.setTransferData ( "text/unicode", genData, id.length * 2); // double byte data
|
||||
dump("genData is " + genData.data + " len is " + genData.data.length + "\n");
|
||||
trans.setTransferData ( "moz/rdfitem", genData, genData.data.length * 2); // double byte data
|
||||
trans.setTransferData ( "text/unicode", genDataURL, genDataURL.data.length * 2); // double byte data
|
||||
|
||||
var transArray =
|
||||
Components.classes["component://netscape/supports-array"].createInstance(Components.interfaces.nsISupportsArray);
|
||||
@ -123,12 +145,17 @@ function BeginDragTree ( event )
|
||||
// put it into the transferable as an |nsISupports|
|
||||
var genTrans = trans.QueryInterface(Components.interfaces.nsISupports);
|
||||
transArray.AppendElement(genTrans);
|
||||
|
||||
var dragService =
|
||||
Components.classes["component://netscape/widget/dragservice"].getService(Components.interfaces.nsIDragService);
|
||||
if ( !dragService ) return(false);
|
||||
|
||||
var nsIDragService = Components.interfaces.nsIDragService;
|
||||
dragService.invokeDragSession ( transArray, null, nsIDragService.DRAGDROP_ACTION_COPY +
|
||||
nsIDragService.DRAGDROP_ACTION_MOVE );
|
||||
dragStarted = true;
|
||||
|
||||
return(!dragStarted); // don't propagate the event if a drag has begun
|
||||
return(!dragStarted);
|
||||
}
|
||||
|
||||
|
||||
@ -136,7 +163,17 @@ function BeginDragTree ( event )
|
||||
function DragOverTree ( event )
|
||||
{
|
||||
if ( !gDragDropEnabled )
|
||||
return;
|
||||
return(false);
|
||||
|
||||
// for beta1, don't allow D&D if sorting is active
|
||||
var tree = document.getElementById("bookmarksTree");
|
||||
if (!tree) return(false);
|
||||
var sortActive = tree.getAttribute("sortActive");
|
||||
if (sortActive == "true")
|
||||
{
|
||||
dump("Sorry, drag&drop is currently disabled when sorting is active.\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
var validFlavor = false;
|
||||
var dragSession = null;
|
||||
@ -149,7 +186,7 @@ function DragOverTree ( event )
|
||||
dragSession = dragService.getCurrentSession();
|
||||
if ( !dragSession ) return(false);
|
||||
|
||||
if ( dragSession.isDataFlavorSupported("moz/toolbaritem") ) validFlavor = true;
|
||||
if ( dragSession.isDataFlavorSupported("moz/rdfitem") ) validFlavor = true;
|
||||
else if ( dragSession.isDataFlavorSupported("text/unicode") ) validFlavor = true;
|
||||
//XXX other flavors here...
|
||||
|
||||
@ -161,7 +198,7 @@ function DragOverTree ( event )
|
||||
rowGroup.setAttribute ( "dd-triggerrepaint", 0 );
|
||||
dragSession.canDrop = true;
|
||||
// necessary??
|
||||
retVal = false; // do not propagate message
|
||||
retVal = false;
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
@ -171,8 +208,21 @@ function DragOverTree ( event )
|
||||
function DropOnTree ( event )
|
||||
{
|
||||
if ( !gDragDropEnabled )
|
||||
return;
|
||||
|
||||
return(false);
|
||||
|
||||
var treeRoot = document.getElementById("bookmarksTree");
|
||||
if (!treeRoot) return(false);
|
||||
var treeDatabase = treeRoot.database;
|
||||
if (!treeDatabase) return(false);
|
||||
|
||||
// for beta1, don't allow D&D if sorting is active
|
||||
var sortActive = treeRoot.getAttribute("sortActive");
|
||||
if (sortActive == "true")
|
||||
{
|
||||
dump("Sorry, drag&drop is currently disabled when sorting is active.\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
var RDF =
|
||||
Components.classes["component://netscape/rdf/rdf-service"].getService(Components.interfaces.nsIRDFService);
|
||||
if (!RDF) return(false);
|
||||
@ -183,12 +233,7 @@ function DropOnTree ( event )
|
||||
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
|
||||
if (!Bookmarks) return(false);
|
||||
|
||||
var treeRoot = document.getElementById("bookmarksTree");
|
||||
if (!treeRoot) return(false);
|
||||
var treeDatabase = treeRoot.database;
|
||||
if (!treeDatabase) return(false);
|
||||
|
||||
// target is the <treecell>, and "id" is on the <treeitem> two levels above
|
||||
// target is the <treecell>, and "ref/id" is on the <treeitem> two levels above
|
||||
var treeItem = event.target.parentNode.parentNode;
|
||||
if (!treeItem) return(false);
|
||||
var targetID = getAbsoluteID(treeRoot, treeItem);
|
||||
@ -226,6 +271,7 @@ function DropOnTree ( event )
|
||||
var trans =
|
||||
Components.classes["component://netscape/widget/transferable"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( !trans ) return(false);
|
||||
trans.addDataFlavor("moz/rdfitem");
|
||||
trans.addDataFlavor("text/unicode");
|
||||
|
||||
var dirty = false;
|
||||
@ -240,17 +286,49 @@ function DropOnTree ( event )
|
||||
if ( dataObj ) dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsWString);
|
||||
if ( !dataObj ) continue;
|
||||
|
||||
// pull the URL out of the data object
|
||||
var sourceID = dataObj.data;
|
||||
if (!sourceID) continue;
|
||||
var sourceID = null;
|
||||
var parentID = null;
|
||||
var checkNameHack = false;
|
||||
|
||||
debug(" Node #" + i + ": drop '" + sourceID + "' " + dropAction + " '" + targetID + "'");
|
||||
if (bestFlavor.value == "moz/rdfitem")
|
||||
{
|
||||
// pull the URL out of the data object
|
||||
var data = dataObj.data.substring(0, len.value / 2);;
|
||||
|
||||
var cr = data.indexOf("\n");
|
||||
if (cr >= 0)
|
||||
{
|
||||
sourceID = data.substr(0, cr);
|
||||
parentID = data.substr(cr+1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceID = dataObj.data;
|
||||
|
||||
// XXX for the moment, if its a text/unicode drop
|
||||
// we may need to synthesize a name (just use the URL)
|
||||
checkNameHack = true;
|
||||
}
|
||||
|
||||
dump(" Node #" + i + ": drop '" + sourceID + "'\n");
|
||||
dump(" from container '" + parentID + "'\n");
|
||||
dump(" action = '" + dropAction + "'\n");
|
||||
dump(" target = '" + targetID + "'\n");
|
||||
|
||||
var sourceNode = RDF.GetResource(sourceID, true);
|
||||
if (!sourceNode) continue;
|
||||
|
||||
var parentNode = null;
|
||||
if (parentID != null)
|
||||
{
|
||||
parentNode = RDF.GetResource(parentID, true);
|
||||
}
|
||||
|
||||
// Prevent dropping of a node before, after, or on itself
|
||||
if (sourceNode == targetNode) continue;
|
||||
// Prevent dropping of a node onto its parent container
|
||||
if ((dropAction == "on") && (containerID) && (containerID == parentID)) continue;
|
||||
|
||||
RDFC.Init(Bookmarks, containerNode);
|
||||
|
||||
@ -260,6 +338,7 @@ function DropOnTree ( event )
|
||||
var nodeIndex;
|
||||
|
||||
nodeIndex = RDFC.IndexOf(sourceNode);
|
||||
|
||||
if (nodeIndex >= 1)
|
||||
{
|
||||
// moving a node around inside of the container
|
||||
@ -268,29 +347,104 @@ function DropOnTree ( event )
|
||||
}
|
||||
|
||||
nodeIndex = RDFC.IndexOf(targetNode);
|
||||
|
||||
if (nodeIndex < 1) return(false);
|
||||
if (dropAction == "after") ++nodeIndex;
|
||||
|
||||
RDFC.InsertElementAt(sourceNode, nodeIndex, true);
|
||||
|
||||
// select the newly added node
|
||||
if (parentID)
|
||||
{
|
||||
selectDroppedItems(treeRoot, containerID, sourceID);
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// drop on
|
||||
RDFC.AppendElement(sourceNode);
|
||||
|
||||
// select the newly added node
|
||||
if (parentID)
|
||||
{
|
||||
selectDroppedItems(treeRoot, containerID, sourceID);
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (checkNameHack == true)
|
||||
{
|
||||
// XXX for the moment, if its a text/unicode drop
|
||||
// we may need to synthesize a name (just use the URL)
|
||||
var srcArc = RDF.GetResource(sourceID, true);
|
||||
var propArc = RDF.GetResource("http://home.netscape.com/NC-rdf#Name", true);
|
||||
if (srcArc && propArc && treeDatabase)
|
||||
{
|
||||
var targetArc = treeDatabase.GetTarget(srcArc, propArc, true);
|
||||
if (!targetArc)
|
||||
{
|
||||
var defaultNameArc = RDF.GetLiteral(sourceID);
|
||||
if (defaultNameArc)
|
||||
{
|
||||
treeDatabase.Assert(srcArc, propArc, defaultNameArc, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// should we move the node? (i.e. take it out of the source container?)
|
||||
if ((parentNode != null) && (containerNode != parentNode))
|
||||
{
|
||||
RDFC.Init(Bookmarks, parentNode);
|
||||
var nodeIndex = RDFC.IndexOf(sourceNode);
|
||||
|
||||
if (nodeIndex >= 1)
|
||||
{
|
||||
RDFC.RemoveElementAt(nodeIndex, true, sourceNode);
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty == true)
|
||||
{
|
||||
var remote = Bookmarks.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
if (remote)
|
||||
{
|
||||
remote.Flush();
|
||||
debug("Wrote out bookmark changes.");
|
||||
dump("Wrote out bookmark changes.");
|
||||
}
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function selectDroppedItems(treeRoot, containerID, targetID)
|
||||
{
|
||||
var select_list = treeRoot.getElementsByAttribute("id", targetID);
|
||||
for (var x=0; x<select_list.length; x++)
|
||||
{
|
||||
var node = select_list[x];
|
||||
if (!node) continue;
|
||||
|
||||
var parent = node.parentNode.parentNode;
|
||||
if (!parent) continue;
|
||||
|
||||
var id = parent.getAttribute("ref");
|
||||
if (!id || id=="")
|
||||
{
|
||||
id = parent.getAttribute("id");
|
||||
}
|
||||
if (!id || id=="") continue;
|
||||
|
||||
if (id == containerID)
|
||||
{
|
||||
node.setAttribute("selected", "true");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user