mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 00:55:37 +00:00
0ceb02438e
NOT PART OF BUILD.
374 lines
14 KiB
JavaScript
374 lines
14 KiB
JavaScript
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 2000 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Ben Goodger <ben@netscape.com> (Original Author)
|
|
*/
|
|
|
|
var gR_NC_child = null;
|
|
|
|
const kNC_NS = "http://home.netscape.com/NC-rdf#";
|
|
|
|
const kToolboxID = "navigator-toolbox";
|
|
|
|
var ToolbarShell = {
|
|
|
|
RDFSvc : Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService),
|
|
RDFC : Components.classes["@mozilla.org/rdf/container;1"].getService(Components.interfaces.nsIRDFContainer),
|
|
|
|
initToolbars: function ()
|
|
{
|
|
var toolbox = document.getElementById(kToolboxID);
|
|
|
|
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService();
|
|
rdfService = rdfService.QueryInterface(Components.interfaces.nsIRDFService);
|
|
|
|
// Add Datasources to toolbox
|
|
// NOTE: This is for navigator toolbar datasource hookup ONLY. Datasources
|
|
// from other components must add themselves separately.
|
|
|
|
var toolbars = rdfService.GetDataSource("chrome://navigator/content/navigator-toolbars.rdf");
|
|
toolbox.database.AddDataSource(toolbars);
|
|
|
|
var commands = rdfService.GetDataSource("chrome://navigator/content/navigator-commands.rdf");
|
|
toolbox.database.AddDataSource(commands);
|
|
|
|
// XXX - shift to applicable component overlays
|
|
var bmds = rdfService.GetDataSource("rdf:bookmarks");
|
|
toolbox.database.AddDataSource(bmds);
|
|
|
|
var sidebarDS = rdfService.GetDataSource(get_sidebar_datasource_uri());
|
|
toolbox.database.AddDataSource(sidebarDS);
|
|
|
|
toolbox.builder.rebuild();
|
|
|
|
// globals
|
|
gR_NC_child = rdfService.GetResource(kNC_NS + "child", true);
|
|
|
|
},
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// @param aNode wstring Node URI being inserted
|
|
// @param aRelativeNode wstring Node URI being inserted into/adjacent to
|
|
// @param aParentNode wstring Node URI of parent
|
|
// @param aPosition boolean true = before, false = after
|
|
insertNode: function (aNode, aRelativeNode, aParentNode, aPosition)
|
|
{
|
|
var toolbox = document.getElementById(kToolboxID);
|
|
var db = toolbox.database;
|
|
|
|
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService();
|
|
rdfService = rdfService.QueryInterface(Components.interfaces.nsIRDFService);
|
|
|
|
// Obtain RDF Resources for the node URIs
|
|
var rNode = rdfService.GetResource(aNode, true);
|
|
var rRelNode = rdfService.GetResource(aRelativeNode, true);
|
|
|
|
const cUtilsContractID = "@mozilla.org/rdf/container-utils;1";
|
|
const cUtilsIID = Components.interfaces.nsIRDFContainerUtils;
|
|
var cUtils = Components.classes[cUtilsContractID].getService();
|
|
cUtils = cUtils.QueryInterface(cUtilsIID);
|
|
|
|
const cContractID = "@mozilla.org/rdf/container;1";
|
|
const cIID = Components.interfaces.nsIRDFContainer;
|
|
var container = Components.classes[cContractID].getService();
|
|
container = container.QueryInterface(cIID);
|
|
|
|
// If the relative and parent nodes are the same, the node is a container
|
|
// and we want to append to it.
|
|
if (aRelativeNode == aParentNode) {
|
|
try {
|
|
// Relative Node is a bona fide container, init container and append.
|
|
container.Init(db, rRelNode);
|
|
container.AppendElement(rNode);
|
|
}
|
|
catch (e) {
|
|
// No container, just assert a child relationship
|
|
this.conditionalAssert(rRelNode, gR_NC_child, rNode, true);
|
|
}
|
|
}
|
|
else {
|
|
// Insert relative to a given node and its parent.
|
|
try {
|
|
var rParentNode = rdfService.GetResource(aParentNode, true);
|
|
|
|
// See if our parent is a container, if it is, we can just append directly
|
|
// to it.
|
|
if (cUtils.IsContainer(db, rParentNode)) {
|
|
container.Init(db, rParentNode);
|
|
var ix = container.IndexOf(rRelNode);
|
|
container.InsertElementAt(rNode, ix + (aPosition ? 0 : 1), true);
|
|
}
|
|
else {
|
|
// Otherwise, we're higher up in the graph and need to navigate down
|
|
// into our children looking for sequences...
|
|
var childSeqs = db.GetTargets(rParentNode, gR_NC_child, true);
|
|
while (childSeqs.hasMoreElements()) {
|
|
var currSeq = childSeqs.getNext();
|
|
currSeq = currSeq.QueryInterface(Components.interfaces.nsIRDFResource);
|
|
|
|
if (cUtils.IsContainer(db, currSeq)) {
|
|
container.Init(db, currSeq);
|
|
var ix = container.IndexOf(rRelNode);
|
|
dump("*** index of relative node is " + ix + "\n");
|
|
DUMP_seq(rdfService, container, db, currSeq, rRelNode);
|
|
if (ix >= 1) {
|
|
// This is the right container. It has the node we care about.
|
|
// Append to it.
|
|
container.InsertElementAt(rNode, ix + (aPosition ? 0 : 1), true);
|
|
DUMP_seq(rdfService, container, db, currSeq, rRelNode);
|
|
return;
|
|
}
|
|
// Otherwise, continue to inspect child containers.
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (e) { throw e }
|
|
}
|
|
},
|
|
|
|
removeNode: function (aNode, aParent)
|
|
{
|
|
var toolbox = document.getElementById(kToolboxID);
|
|
var db = toolbox.database;
|
|
|
|
// If we want to append aNode to aRelativeNode, a shortcut is to assert a
|
|
// child property
|
|
const cUtilsContractID = "@mozilla.org/rdf/container-utils;1";
|
|
const cUtilsIID = Components.interfaces.nsIRDFContainerUtils;
|
|
var containerUtils = Components.classes[cUtilsContractID].getService();
|
|
containerUtils = containerUtils.QueryInterface(cUtilsIID);
|
|
|
|
const cContractID = "@mozilla.org/rdf/container;1";
|
|
const cIID = Components.interfaces.nsIRDFContainer;
|
|
var container = Components.classes[cContractID].getService();
|
|
container = container.QueryInterface(cIID);
|
|
|
|
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService();
|
|
rdfService = rdfService.QueryInterface(Components.interfaces.nsIRDFService);
|
|
|
|
var rParent = rdfService.GetResource(aParent, true);
|
|
var rNode = rdfService.GetResource(aNode, true);
|
|
|
|
if (containerUtils.IsContainer(db, rParent)) {
|
|
// If the parent is a container, remove aNode from it.
|
|
container.Init(db, rParent);
|
|
container.RemoveElement(rNode, true);
|
|
}
|
|
else {
|
|
// Otherwise (the likely case) the parent is not itself a container, but
|
|
// a resource with a series of child arcs out to containers. Iterate over
|
|
// these child arcs, and compare their URIs with the aParentURI. When we
|
|
// find that, we can remove aNodeURI from it safely.
|
|
var childSeqs = db.GetTargets(rParent, gR_NC_child, true);
|
|
while (childSeqs.hasMoreElements()) {
|
|
var currSeq = childSeqs.getNext();
|
|
currSeq = currSeq.QueryInterface(Components.interfaces.nsIRDFResource);
|
|
|
|
if (containerUtils.IsContainer(db, currSeq)) {
|
|
container.Init(db, currSeq);
|
|
var ix = container.IndexOf(rNode);
|
|
if (ix >= 0) {
|
|
container.RemoveElement(rNode, true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
|
|
copy: function (aNode, aIID)
|
|
{
|
|
this._copy(aNode, aIID);
|
|
},
|
|
|
|
conditionalAssert: function (aSource, aProperty, aTarget, aTruthValue)
|
|
{
|
|
var toolbox = document.getElementById(kToolboxID);
|
|
var db = toolbox.database;
|
|
if (!db) return;
|
|
|
|
if (db.HasAssertion(aSource, aProperty, aTarget, aTruthValue)) {
|
|
var currValue = db.GetTarget(aSource, aProperty, true);
|
|
db.Change(aSource, aProperty, currValue, aTarget);
|
|
}
|
|
else
|
|
db.Assert(aSource, aProperty, aTarget, aTruthValue);
|
|
},
|
|
|
|
getProperty: function (aSourceURI, aPropertyURI)
|
|
{
|
|
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService();
|
|
rdfService = rdfService.QueryInterface(Components.interfaces.nsIRDFService);
|
|
|
|
var toolbox = document.getElementById(kToolboxID);
|
|
var db = toolbox.database;
|
|
|
|
var rSource = rdfService.GetResource(aSourceURI, true);
|
|
var rURL = rdfService.GetResource(aPropertyURI, true);
|
|
|
|
var URL = db.GetTarget(rSource, rURL, true);
|
|
if (!URL) return null;
|
|
try {
|
|
URL = URL.QueryInterface(Components.interfaces.nsIRDFResource);
|
|
}
|
|
catch (e) {
|
|
URL = URL.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
|
}
|
|
return URL.Value;
|
|
},
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Drag And Drop Observer Implementation
|
|
onDragStart: function (aEvent)
|
|
{
|
|
// targetURI is the unique identifier of this node in the RDF graph.
|
|
// targetURL is its URL property, which we will want for creation of HTML
|
|
// links, etc.
|
|
// targetName is the short descriptive label.
|
|
// targetDesc is the longer descriptive label
|
|
var targetURI = aEvent.target.id;
|
|
var targetURL = this.getProperty(targetURI, kNC_NS + "URL");
|
|
var targetDesc = this.getProperty(targetURI, kNC_NS + "Description");
|
|
var targetName = this.getProperty(targetURI, kNC_NS + "Name");
|
|
|
|
var flavourList = { };
|
|
|
|
if (targetURI) {
|
|
// For moz/toolbaritem, transferring the URI is enough as we always remain
|
|
// in the context of the graph, and we can always figure out what we need.
|
|
flavourList["moz/toolbaritem"] = { width: 2, data: targetURI };
|
|
// For simple URLs, transport the Name and the Location
|
|
flavourList["text/x-moz-url"] = { width: 2, data: targetURL + "\n" + targetName };
|
|
// For HTML Links, take the Name, Location and descriptive text for
|
|
// the TITLE tooltip.
|
|
var htmlString = "";
|
|
if (targetDesc)
|
|
htmlString = "<a href=\"" + targetURL + "\" title=\"" + targetDesc + "\">" + targetName + "</a>";
|
|
else
|
|
htmlString = "<a href=\"" + targetURL + "\">" + targetName + "</a>";
|
|
flavourList["text/html"] = { width: 2, data: htmlString };
|
|
// For the most basic case, simply take the URL.
|
|
flavourList["text/unicode"] = { width: 2, data: targetURL };
|
|
}
|
|
|
|
DUMP_flavours(flavourList);
|
|
|
|
return flavourList;
|
|
},
|
|
|
|
onDragOver: function (aEvent, aFlavourList, aDragSession)
|
|
{
|
|
// Handle Drag & Drop Feedback
|
|
},
|
|
|
|
onDragExit: function (aEvent, aDragSession)
|
|
{
|
|
// Handle Drag & Drop Feedback
|
|
},
|
|
|
|
onDrop: function (aEvent, aDragData, aDragSession)
|
|
{
|
|
// Find the node dropped on
|
|
var dropNode = aEvent.target;
|
|
|
|
// Get Client Coords and Widget Bounds
|
|
var cX = aEvent.clientX;
|
|
var wX = dropNode.boxObject.x;
|
|
var wW = dropNode.boxObject.width;
|
|
|
|
var relNodeURI = dropNode.id;
|
|
var parentNodeURI = aEvent.target.parentNode.id;
|
|
|
|
// bounds check
|
|
if (cX > wX && cX < (wX + wW)) {
|
|
// XXX - need to handle containers here, which will mean creating three
|
|
// dropzones rather than 2.
|
|
if (cX > wX && cX < (wX + (wW/2))) {
|
|
// Drop to the left
|
|
if (aDragData.flavour == "moz/toolbaritem") {
|
|
try {
|
|
this.insertNode(aDragData.data.data, relNodeURI, parentNodeURI, true);
|
|
// if insertNode fails, it will throw, and we won't remove the node
|
|
// from the destination
|
|
this.removeNode(aDragData.data.data, parentNodeURI);
|
|
}
|
|
catch (e) {
|
|
dump("*** ToolbarShell::insertNode failed for some reason\n");
|
|
dump("*** Reason: " + e + "\n");
|
|
}
|
|
}
|
|
}
|
|
else if (cX > (wX + (wW/2)) && cX < (wX + wW)) {
|
|
// Drop to the right
|
|
if (aDragData.flavour == "moz/toolbaritem") {
|
|
try {
|
|
this.insertNode(aDragData.data.data, relNodeURI, parentNodeURI, false);
|
|
// if insertNode fails, it will throw, and we won't remove the node
|
|
// from the destination
|
|
this.removeNode(aDragData.data.data, parentNodeURI);
|
|
}
|
|
catch (e) {
|
|
dump("*** ToolbarShell::insertNode failed for some reason\n");
|
|
dump("*** Reason: " + e + "\n");
|
|
}
|
|
}
|
|
}
|
|
else if (0) {
|
|
// Drop On
|
|
}
|
|
}
|
|
},
|
|
|
|
getSupportedFlavours: function ()
|
|
{
|
|
var flavourList = { };
|
|
flavourList["moz/toolbaritem"] = { width: 2, iid: "nsISupportsWString" };
|
|
flavourList["text/x-moz-url"] = { width: 2, iid: "nsISupportsWString" };
|
|
flavourList["text/html"] = { width: 2, iid: "nsISupportsWString" };
|
|
flavourList["text/unicode"] = { width: 2, iid: "nsISupportsWString" };
|
|
return flavourList;
|
|
}
|
|
|
|
|
|
};
|
|
|
|
function DUMP_flavours(aFlavourList)
|
|
{
|
|
for (var flavour in aFlavourList)
|
|
dump("*** Flavour " + flavour + " has data : " + aFlavourList[flavour].data + "\n");
|
|
}
|
|
|
|
function DUMP_seq(aRDFS, aContainer, aDB, aSequence, aRelNode)
|
|
{
|
|
var res = aContainer.GetElements();
|
|
var count = 1;
|
|
while (res.hasMoreElements()) {
|
|
var currRes = res.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
|
|
if (currRes.Value == aRelNode.Value)
|
|
dump("[[ #" + count++ + " * " + currRes.Value + "\n");
|
|
else
|
|
dump("[[ #" + count++ + " " + currRes.Value + "\n");
|
|
}
|
|
}
|
|
|
|
addEventListener("load", ToolbarShell.initToolbars, false);
|
|
|