зеркало из https://github.com/mozilla/gecko-dev.git
1677 строки
76 KiB
XML
1677 строки
76 KiB
XML
<?xml version="1.0" ?>
|
|
<!DOCTYPE window [
|
|
<!ENTITY % bookmarksDTD SYSTEM "chrome://communicator/locale/bookmarks/bookmarks.dtd" >
|
|
%bookmarksDTD;
|
|
]>
|
|
|
|
<bindings id="bookmarksBindings"
|
|
xmlns="http://www.mozilla.org/xbl"
|
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
|
|
<binding id="bookmarksBase">
|
|
<implementation>
|
|
<!-- RDF Namespace URIs -->
|
|
<field name="RDF_NS">"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</field>
|
|
<field name="NC_NS">"http://home.netscape.com/NC-rdf#"</field>
|
|
<field name="NC_NS_CMD">this.NC_NS + "command?cmd=";</field>
|
|
<property name="rdfContainer">
|
|
<getter><![CDATA[
|
|
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
|
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
|
return Components.classes[kRDFCContractID].getService(kRDFCIID);
|
|
]]></getter>
|
|
</property>
|
|
<field name="_rdf">null</field>
|
|
<property name="rdf">
|
|
<getter><![CDATA[
|
|
if (!this._rdf) {
|
|
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
|
|
const kRDFIID = Components.interfaces.nsIRDFService;
|
|
this._rdf = Components.classes[kRDFContractID].getService(kRDFIID);
|
|
}
|
|
return this._rdf;
|
|
]]></getter>
|
|
</property>
|
|
<field name="_bundle">null</field>
|
|
<field name="_bookmarksDS">null</field>
|
|
<property name="bookmarksDS">
|
|
<getter><![CDATA[
|
|
if (!this._bookmarksDS)
|
|
this._bookmarksDS = this.rdf.GetDataSource("rdf:bookmarks");
|
|
return this._bookmarksDS;
|
|
]]></getter>
|
|
</property>
|
|
<method name="resolveType">
|
|
<parameter name="aResource"/>
|
|
<body><![CDATA[
|
|
try {
|
|
aResource.QueryInterface(Components.interfaces.nsIRDFResource);
|
|
}
|
|
catch(ex) {
|
|
// Not actually a resource, assume resource URI
|
|
aResource = this.rdf.GetResource(aResource);
|
|
}
|
|
var res = aResource;
|
|
var typeArc = this.rdf.GetResource(this.RDF_NS + "type");
|
|
var type = this.db.GetTarget(res, typeArc, true);
|
|
try {
|
|
return type.QueryInterface(Components.interfaces.nsIRDFResource).Value;
|
|
}
|
|
catch (e) {
|
|
try {
|
|
return type.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
|
}
|
|
catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
]]></body>
|
|
</method>
|
|
<method name="flushBMDatasource">
|
|
<body><![CDATA[
|
|
var remoteDS = this.bookmarksDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
|
remoteDS.Flush();
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<binding id="bookmarks-outliner"
|
|
extends="chrome://communicator/content/bookmarks/bookmarks.xml#bookmarksBase">
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
// We implement nsIController
|
|
this.outliner.controllers.appendController(this.controller);
|
|
var olb = document.getAnonymousElementByAttribute(this, "anonid", "bookmarks-outlinerbody");
|
|
olb = olb.builder.QueryInterface(Components.interfaces.nsIXULOutlinerBuilder);
|
|
olb.addObserver(this.builderObserver);
|
|
// need to create string bundle manually instead of using <xul:stringbundle/>
|
|
// see bug 63370 for details
|
|
var localeService = Components.classes["@mozilla.org/intl/nslocaleservice;1"]
|
|
.getService(Components.interfaces.nsILocaleService);
|
|
var stringBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
|
|
var bundleURL = "chrome://communicator/locale/bookmarks/bookmark.properties";
|
|
this._bundle = stringBundleService.createBundle(bundleURL, localeService.GetApplicationLocale());
|
|
// setTimeout(this.refreshSort, 0, this);
|
|
]]></constructor>
|
|
<destructor><![CDATA[
|
|
this.outlinerBuilder.removeObserver(this.builderObserver);
|
|
this.outliner.controllers.removeController(this.controller);
|
|
]]></destructor>
|
|
|
|
<property name="outlinerBoxObject">
|
|
<getter><![CDATA[
|
|
return this.outliner.boxObject.QueryInterface(Components.interfaces.nsIOutlinerBoxObject);
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="outlinerBuilder">
|
|
<getter><![CDATA[
|
|
return this.outlinerBoxObject.outlinerBody.builder.QueryInterface(Components.interfaces.nsIXULOutlinerBuilder);
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="outliner">
|
|
<getter><![CDATA[
|
|
return document.getAnonymousElementByAttribute(this, "anonid", "bookmarks-outliner");
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="outlinerBody">
|
|
<getter><![CDATA[
|
|
return document.getAnonymousElementByAttribute(this, "anonid", "bookmarks-outlinerbody");
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="currentIndex">
|
|
<getter><![CDATA[
|
|
return this.outlinerBoxObject.selection.currentIndex;
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="currentRes">
|
|
<getter><![CDATA[
|
|
return this.outlinerBuilder.getResourceAtIndex(this.currentIndex);
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="parentRes">
|
|
<getter><![CDATA[
|
|
const currIndex = this.currentIndex;
|
|
|
|
if (currIndex == -1)
|
|
return this.rdf.GetResource("NC:BookmarksRoot");
|
|
|
|
var parentIndex = this.outlinerBoxObject.view.getParentIndex(currIndex);
|
|
if (parentIndex != -1)
|
|
return this.outlinerBuilder.getResourceAtIndex(parentIndex)
|
|
return this.rdf.GetResource("NC:BookmarksRoot"); // assume its parent is the root
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="firstSelectedIndex">
|
|
<getter><![CDATA[
|
|
var first = { };
|
|
this.outlinerBoxObject.selection.getRangeAt(0, first, { });
|
|
return first.value;
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="lastSelectedIndex">
|
|
<getter><![CDATA[
|
|
var bo = this.outlinerBoxObject;
|
|
var last = { };
|
|
var rangeCount = bo.selection.getRangeCount();
|
|
bo.selection.getRangeAt(rangeCount - 1, { }, last);
|
|
return last.value;
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="_browserURL">
|
|
<getter><![CDATA[
|
|
try {
|
|
var prefs = Components.classes["@mozilla.org/preferences;1"];
|
|
if (prefs) {
|
|
prefs = prefs.getService();
|
|
if (prefs)
|
|
prefs = prefs.QueryInterface(Components.interfaces.nsIPref);
|
|
}
|
|
if (prefs) {
|
|
var url = prefs.CopyCharPref("browser.chromeURL");
|
|
if (url)
|
|
return url;
|
|
}
|
|
} catch(e) {
|
|
}
|
|
return "chrome://navigator/content/navigator.xul";
|
|
]]></getter>
|
|
</property>
|
|
|
|
<!-- Returns the row index of the best row at which to perform an operation
|
|
relative to the current selection, e.g. creating a new bookmark
|
|
adjacent to the current selection. -->
|
|
<method name="getNextRowIndex">
|
|
<body><![CDATA[
|
|
var bo = this.outlinerBoxObject;
|
|
var rangeCount = bo.selection.getRangeCount();
|
|
var currLevel, lastIndex = 0;
|
|
if (!rangeCount)
|
|
currLevel = 0;
|
|
else
|
|
currLevel = bo.view.getLevel(this.firstSelectedIndex);
|
|
|
|
// Walk the selection. If the level for the current item is less than
|
|
// our running minimum, assume it is higher in the hierarchy than any
|
|
// previous. In this case, or in the case with a selected item of same
|
|
// hierarchy, set the lastIndex.
|
|
// XXXben - erk this comment sort of sucks. A diagram might help.
|
|
for (var i = 0; i < rangeCount; ++i) {
|
|
var rangeMin = { };
|
|
var rangeMax = { };
|
|
bo.selection.getRangeAt(i, rangeMin, rangeMax);
|
|
for (var j = rangeMax.value; j >= rangeMin.value; --j) {
|
|
var level = bo.view.getLevel(j);
|
|
if (level <= currLevel) {
|
|
currLevel = level;
|
|
lastIndex = j;
|
|
}
|
|
}
|
|
}
|
|
return lastIndex;
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="getTypeAtIndex">
|
|
<parameter name="aIndex" />
|
|
<body><![CDATA[
|
|
try {
|
|
return this.resolveType(this.outlinerBuilder.getResourceAtIndex(aIndex));
|
|
}
|
|
catch(ex) {
|
|
return null;
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<!-- observer -->
|
|
<field name="newFolderRDFObserver" readonly="true"><![CDATA[
|
|
({
|
|
_newFolderURI: null,
|
|
onAssert: function (aDS, aSource, aProperty, aValue)
|
|
{
|
|
try {
|
|
var value = aValue.QueryInterface(Components.interfaces.nsIRDFResource);
|
|
if (aDS.URI == "rdf:bookmarks" && aProperty.Value == this.RDF_NS + "type" &&
|
|
value.Value == this.NC_NS + "Folder")
|
|
this._newFolderURI = aSource.Value;
|
|
}
|
|
catch (e) {
|
|
// Failures are OK, the value could be a literal instead of a resource.
|
|
}
|
|
},
|
|
onUnassert: function (aDS, aSource, aProperty, aTarget) { },
|
|
onChange: function (aDS, aSource, aProperty, aOldTarget, aNewTarget) { },
|
|
onMove: function (aDS, aOldSource, aNewSource, aProperty, aTarget) { },
|
|
beginUpdateBatch: function (aDS) { },
|
|
endUpdateBatch: function (aDS) { }
|
|
})
|
|
]]></field>
|
|
|
|
<!-- observer -->
|
|
<field name="DNDObserver" readonly="true"><![CDATA[
|
|
({
|
|
mOuter: this,
|
|
onDragStart: function (aEvent, aXferData, aDragAction)
|
|
{
|
|
if (this.mOuter.outlinerBody.getAttribute("sortActive") == "true")
|
|
throw Components.results.NS_OK;
|
|
aXferData.data = new TransferDataSet();
|
|
var rangeCount = this.mOuter.outlinerBoxObject.selection.getRangeCount();
|
|
for (var i = rangeCount - 1; i >= 0; --i) {
|
|
var rangeMin = { };
|
|
var rangeMax = { };
|
|
this.mOuter.outlinerBoxObject.selection.getRangeAt(i, rangeMin, rangeMax);
|
|
for (var j = rangeMax.value; j >= rangeMin.value; --j) {
|
|
var currRes = this.mOuter.outlinerBuilder.getResourceAtIndex(j);
|
|
var parentIndex = this.mOuter.outlinerBoxObject.view.getParentIndex(j);
|
|
var parentRes;
|
|
if (parentIndex == -1)
|
|
parentRes = this.mOuter.rdf.GetResource("NC:BookmarksRoot");
|
|
else
|
|
parentRes = this.mOuter.outlinerBuilder.getResourceAtIndex(parentIndex);
|
|
|
|
var type = this.mOuter.db.GetTarget(currRes, this.mOuter.rdf.GetResource(this.mOuter.RDF_NS + "type"), true);
|
|
type = type.QueryInterface(Components.interfaces.nsIRDFResource).Value;
|
|
if (!type || (type != (this.mOuter.NC_NS + "BookmarkSeparator") &&
|
|
type != (this.mOuter.NC_NS + "Bookmark") &&
|
|
type != (this.mOuter.NC_NS + "Folder")))
|
|
throw Components.results.NS_OK;
|
|
var name = this.mOuter.db.GetTarget(currRes, this.mOuter.rdf.GetResource(this.mOuter.NC_NS + "Name"), true);
|
|
var data = new TransferData();
|
|
if (name) {
|
|
name = name.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
|
data.addDataForFlavour("text/x-moz-url", currRes.Value + "\n" + name);
|
|
}
|
|
else {
|
|
data.addDataForFlavour("text/x-moz-url", currRes.Value);
|
|
}
|
|
data.addDataForFlavour("moz/rdfitem", currRes.Value + "\n" + parentRes.Value);
|
|
data.addDataForFlavour("text/unicode", currRes.Value);
|
|
aXferData.data.push(data);
|
|
}
|
|
|
|
if (aEvent.ctrlKey) {
|
|
const kDSIID = Components.interfaces.nsIDragService;
|
|
aDragAction.action = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK;
|
|
}
|
|
}
|
|
}
|
|
})
|
|
]]></field>
|
|
|
|
<!-- nsIController -->
|
|
<field name="controller" readonly="true"><![CDATA[
|
|
({
|
|
mOuter: this,
|
|
|
|
supportsCommand: function BMOLController_supportsCommand(aCommand)
|
|
{
|
|
switch (aCommand) {
|
|
case "cmd_bm_undo":
|
|
case "cmd_bm_redo":
|
|
return false;
|
|
case "cmd_bm_cut":
|
|
case "cmd_bm_copy":
|
|
case "cmd_bm_paste":
|
|
case "cmd_bm_delete":
|
|
case "cmd_bm_selectAll":
|
|
case "cmd_bm_open":
|
|
case "cmd_bm_openinnewwindow":
|
|
case "cmd_bm_openfolder":
|
|
case "cmd_bm_openfolderinnewwindow":
|
|
case "cmd_bm_newbookmark":
|
|
case "cmd_bm_newfolder":
|
|
case "cmd_bm_newseparator":
|
|
case "cmd_bm_find":
|
|
case "cmd_bm_properties":
|
|
case "cmd_bm_rename":
|
|
case "cmd_bm_setnewbookmarkfolder":
|
|
case "cmd_bm_setpersonaltoolbarfolder":
|
|
case "cmd_bm_setnewsearchfolder":
|
|
case "cmd_bm_import":
|
|
case "cmd_bm_export":
|
|
case "cmd_bm_fileBookmark":
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
},
|
|
|
|
isCommandEnabled: function BMOLController_isCommandEnabled(aCommand)
|
|
{
|
|
var bo = this.mOuter.outlinerBoxObject;
|
|
var type; // The bookmark's RDF:type arc
|
|
|
|
switch (aCommand) {
|
|
case "cmd_bm_undo":
|
|
case "cmd_bm_redo":
|
|
return false;
|
|
case "cmd_bm_openfolder":
|
|
// 'Expand' is only available if one item is selected and that item is a
|
|
// container item.
|
|
return bo.view.rowCount && bo.selection.count == 1 && bo.view.isContainer(this.mOuter.firstSelectedIndex);
|
|
case "cmd_bm_open":
|
|
case "cmd_bm_openinnewwindow":
|
|
if (bo.selection.count != 1)
|
|
return false;
|
|
return this.mOuter.getTypeAtIndex(this.mOuter.firstSelectedIndex) == this.mOuter.NC_NS + "Bookmark";
|
|
case "cmd_bm_rename":
|
|
case "cmd_bm_properties":
|
|
if (bo.selection.count != 1)
|
|
return false;
|
|
type = this.mOuter.getTypeAtIndex(this.mOuter.firstSelectedIndex);
|
|
return type == this.mOuter.NC_NS + "Bookmark" || type == this.mOuter.NC_NS + "Folder";
|
|
case "cmd_bm_cut":
|
|
type = this.mOuter.getTypeAtIndex(this.mOuter.firstSelectedIndex);
|
|
if (type != this.mOuter.NC_NS + "Bookmark" && type != this.mOuter.NC_NS + "BookmarkSeparator" && type != this.mOuter.NC_NS + "Folder")
|
|
return false;
|
|
return bo.selection.count > 0;
|
|
case "cmd_bm_find":
|
|
return true;
|
|
case "cmd_bm_newbookmark":
|
|
case "cmd_bm_newfolder":
|
|
case "cmd_bm_newseparator":
|
|
// This is not really correct because it gives the false impression
|
|
// that it is possible to create an item as a child of some immutable folders
|
|
// like IE Favorites, but it will do for now.
|
|
return true;
|
|
case "cmd_bm_delete":
|
|
// Determining whether or not the selection is mutable is handled by
|
|
// the deletion routine.
|
|
type = this.mOuter.getTypeAtIndex(this.mOuter.firstSelectedIndex);
|
|
if (type != this.mOuter.NC_NS + "Bookmark" && type != this.mOuter.NC_NS + "BookmarkSeparator" && type != this.mOuter.NC_NS + "Folder")
|
|
return false;
|
|
return bo.selection.count >= 1;
|
|
case "cmd_bm_selectAll":
|
|
// "Select All" is disabled when all visible rows are selected.
|
|
// XXXben this could be cleverer.
|
|
return bo.view.rowCount != bo.selection.count;
|
|
case "cmd_bm_copy":
|
|
return bo.selection.count >= 1;
|
|
case "cmd_bm_paste":
|
|
return this.mOuter.canPaste();
|
|
case "cmd_bm_openfolderinnewwindow":
|
|
if (bo.selection.count != 1)
|
|
return false;
|
|
return this.mOuter.getTypeAtIndex(this.mOuter.firstSelectedIndex) == this.mOuter.NC_NS + "Folder";
|
|
case "cmd_bm_setnewbookmarkfolder":
|
|
case "cmd_bm_setpersonaltoolbarfolder":
|
|
case "cmd_bm_setnewsearchfolder":
|
|
if (bo.selection.count != 1)
|
|
return false;
|
|
// XXXbar if a folder has more than one of these special attributes,
|
|
// this won't work
|
|
var folderURI;
|
|
if (aCommand == "cmd_bm_setnewbookmarkfolder")
|
|
folderURI = "NC:NewBookmarkFolder";
|
|
else if (aCommand == "cmd_bm_setpersonaltoolbarfolder")
|
|
folderURI = "NC:PersonalToolbarFolder";
|
|
else
|
|
folderURI = "NC:NewSearchFolder";
|
|
return (this.mOuter.getTypeAtIndex(this.mOuter.firstSelectedIndex) == this.mOuter.NC_NS + "Folder")
|
|
&& (this.mOuter.outlinerBuilder.getResourceAtIndex(this.mOuter.firstSelectedIndex).Value != folderURI);
|
|
case "cmd_bm_import":
|
|
case "cmd_bm_export":
|
|
return true;
|
|
case "cmd_bm_fileBookmark":
|
|
if (bo.selection.count < 1)
|
|
return false;
|
|
type = this.mOuter.getTypeAtIndex(this.mOuter.firstSelectedIndex);
|
|
return type == this.mOuter.NC_NS + "Folder" || type == this.mOuter.NC_NS + "Bookmark";
|
|
default:
|
|
return false;
|
|
}
|
|
},
|
|
|
|
doCommand: function BMOLController_doCommand(aCommand)
|
|
{
|
|
switch (aCommand) {
|
|
case "cmd_bm_cut":
|
|
this.mOuter.copySelection();
|
|
this.mOuter.deleteSelection();
|
|
break;
|
|
case "cmd_bm_copy":
|
|
this.mOuter.copySelection();
|
|
break;
|
|
case "cmd_bm_paste":
|
|
this.mOuter.paste();
|
|
break;
|
|
case "cmd_bm_delete":
|
|
this.mOuter.deleteSelection();
|
|
break;
|
|
case "cmd_bm_selectAll":
|
|
this.mOuter.selectAll();
|
|
break;
|
|
case "cmd_bm_open":
|
|
this.mOuter.openItem();
|
|
break;
|
|
case "cmd_bm_openfolder":
|
|
this.mOuter.outlinerBoxObject.view.toggleOpenState(this.mOuter.currentIndex);
|
|
break;
|
|
case "cmd_bm_openfolderinnewwindow":
|
|
this.mOuter.openFolderInNewWindow();
|
|
break;
|
|
case "cmd_bm_newbookmark":
|
|
this.mOuter.addBookmark();
|
|
break;
|
|
case "cmd_bm_newfolder":
|
|
this.mOuter.createNewFolder();
|
|
break;
|
|
case "cmd_bm_newseparator":
|
|
this.mOuter.createNewSeparator();
|
|
break;
|
|
case "cmd_bm_find":
|
|
this.mOuter.openFindDialog();
|
|
break;
|
|
case "cmd_bm_properties":
|
|
case "cmd_bm_rename":
|
|
this.mOuter.openPropertiesForItem();
|
|
break;
|
|
case "cmd_bm_setnewbookmarkfolder":
|
|
this.mOuter.setAsNewBookmarkFolder();
|
|
break;
|
|
case "cmd_bm_setpersonaltoolbarfolder":
|
|
this.mOuter.setAsPersonalToolbarFolder();
|
|
break;
|
|
case "cmd_bm_setnewsearchfolder":
|
|
this.mOuter.setAsNewSearchFolder();
|
|
break;
|
|
case "cmd_bm_import":
|
|
this.mOuter.importBookmarks();
|
|
break;
|
|
case "cmd_bm_export":
|
|
this.mOuter.exportBookmarks();
|
|
break;
|
|
case "cmd_bm_fileBookmark":
|
|
this.mOuter.fileBookmark();
|
|
break;
|
|
default:
|
|
}
|
|
}
|
|
})
|
|
]]></field>
|
|
|
|
<method name="onCommandUpdate">
|
|
<body><![CDATA[
|
|
var commands = ["cmd_bm_properties", "cmd_bm_rename", "cmd_bm_copy",
|
|
"cmd_bm_paste", "cmd_bm_cut", "cmd_bm_delete",
|
|
"cmd_bm_setpersonaltoolbarfolder",
|
|
"cmd_bm_setnewbookmarkfolder",
|
|
"cmd_bm_setnewsearchfolder", "cmd_bm_fileBookmark",
|
|
"cmd_bm_openfolderinnewwindow", "cmd_bm_openfolder"];
|
|
for (var i = 0; i < commands.length; ++i) {
|
|
var enabled = this.controller.isCommandEnabled(commands[i]);
|
|
var commandNode = document.getElementById(commands[i]);
|
|
if (commandNode) {
|
|
if (enabled)
|
|
commandNode.removeAttribute("disabled");
|
|
else
|
|
commandNode.setAttribute("disabled", "true");
|
|
}
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="selectionChanged">
|
|
<parameter name="aEvent" />
|
|
<body><![CDATA[
|
|
]]></body>
|
|
</method>
|
|
|
|
<!-- nsIXULOutlinerBuilderObserver -->
|
|
<field name="builderObserver"><![CDATA[
|
|
({
|
|
mOuter: this,
|
|
inDropBefore: 1,
|
|
inDropOn: 2,
|
|
inDropAfter: 3,
|
|
canDropOn: function(index)
|
|
{
|
|
return true;
|
|
},
|
|
canDropBeforeAfter: function(index, before)
|
|
{
|
|
return true;
|
|
},
|
|
onDrop: function(row, orientation)
|
|
{
|
|
var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService().QueryInterface(Components.interfaces.nsIDragService);
|
|
var dragSession = dragService.getCurrentSession();
|
|
if (!dragSession)
|
|
return false;
|
|
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
|
const kRDFIID = Components.interfaces.nsIRDFContainer;
|
|
var RDFC = Components.classes[kRDFCContractID].getService(kRDFIID);
|
|
var rTarget = this.mOuter.outlinerBuilder.getResourceAtIndex(row);
|
|
var parentIndex = this.mOuter.outlinerBoxObject.view.getParentIndex(row);
|
|
var rContainer;
|
|
if (parentIndex == -1)
|
|
rContainer = this.mOuter.rdf.GetResource("NC:BookmarksRoot");
|
|
else
|
|
rContainer = this.mOuter.outlinerBuilder.getResourceAtIndex(parentIndex);
|
|
|
|
var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
|
|
var rBookmark = this.mOuter.rdf.GetResource(this.mOuter.NC_NS + "Bookmark");
|
|
trans.addDataFlavor("moz/rdfitem");
|
|
trans.addDataFlavor("text/x-moz-url");
|
|
trans.addDataFlavor("text/unicode");
|
|
|
|
var list = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
|
|
|
|
var sourceUri;
|
|
var sourceResource;
|
|
var dirty = false;
|
|
var additiveFlag = false;
|
|
for (var i = 0; i < dragSession.numDropItems; ++i) {
|
|
dragSession.getData(trans, i);
|
|
var dataObj = {};
|
|
var bestFlavor = {};
|
|
var len = {};
|
|
trans.getAnyTransferData(bestFlavor, dataObj, len);
|
|
if (dataObj)
|
|
dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsWString);
|
|
if (!dataObj)
|
|
continue;
|
|
sourceUri = dataObj.data.substring(0, len.value);
|
|
if (!sourceUri)
|
|
continue;
|
|
|
|
var sourceID = [], parentID = [], nameRequired = [], name = [];
|
|
nameRequired[i] = false;
|
|
name[i] = null;
|
|
switch (bestFlavor.value) {
|
|
case "moz/rdfitem":
|
|
var ix = sourceUri.indexOf("\n");
|
|
sourceID[i] = ix >= 0 ? (parentID[i] = sourceUri.substr(ix+1), sourceUri.substr(0, ix)) : sourceUri;
|
|
break;
|
|
case "text/x-moz-url":
|
|
ix = sourceUri.indexOf("\n");
|
|
sourceID[i] = ix >= 0 ? (name[i] = sourceUri.substr(ix+1), sourceUri.substr(0, ix)) : sourceUri;
|
|
break;
|
|
case "text/unicode":
|
|
sourceID[i] = sourceUri;
|
|
nameRequired[i] = true;
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
var rSource = this.mOuter.rdf.GetResource(sourceID[i]);
|
|
var rParent = parentID[i] ? this.mOuter.rdf.GetResource(parentID[i]) : null;
|
|
const kBMDS = this.mOuter.bookmarksDS;
|
|
RDFC.Init(kBMDS, rContainer);
|
|
var dropIx = RDFC.IndexOf(rTarget);
|
|
// XXX if any of the following fails, the nodes are gone for good!
|
|
const kDSIID = Components.interfaces.nsIDragService;
|
|
const kCopyAction = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK;
|
|
if (rParent) {
|
|
if (!(dragSession.dragAction & kCopyAction)) {
|
|
try {
|
|
RDFC.Init(kBMDS, rParent);
|
|
ix = RDFC.IndexOf(rSource);
|
|
if (ix >= 1)
|
|
RDFC.RemoveElementAt(ix, true);
|
|
}
|
|
catch (ex) { }
|
|
}
|
|
}
|
|
|
|
var bmType = kBMDS.GetTarget(this.mOuter.rdf.GetResource(sourceID[i]), this.mOuter.rdf.GetResource(this.mOuter.RDF_NS + "type"), true);
|
|
var rType = this.mOuter.rdf.GetResource(this.mOuter.RDF_NS + "type");
|
|
if (!bmType)
|
|
kBMDS.Assert(rSource, rType, rBookmark, true);
|
|
|
|
if (bmType == this.mOuter.NC_NS + "Folder") {
|
|
// If we're going to copy a folder type, we need to clone the folder
|
|
// rather than just asserting the new node as a child of the drop folder.
|
|
if (dragSession.dragAction & kCopyAction)
|
|
rSource = BookmarksUtils.cloneFolder(rSource, rContainer, rTarget);
|
|
}
|
|
if (orientation == this.inDropBefore || orientation == this.inDropAfter) {
|
|
if (dropIx == -1) break;
|
|
RDFC.Init(kBMDS, rContainer);
|
|
RDFC.InsertElementAt(rSource, rParent ? dropIx : (orientation == this.inDropAfter ? ++dropIx : dropIx), true);
|
|
}
|
|
else {
|
|
rContainer = this.mOuter.outlinerBuilder.getResourceAtIndex(row);
|
|
RDFC.Init(kBMDS, rContainer);
|
|
RDFC.AppendElement(rSource); // drop on
|
|
}
|
|
dirty = true;
|
|
|
|
//if (rParent) {
|
|
// gBookmarksShell.selectFolderItem(rContainer.Value, sourceID[i], additiveFlag);
|
|
// if (!additiveFlag) additiveFlag = true;
|
|
//}
|
|
// If a name is supplied, we want to assert this information into the
|
|
// graph. E.g. user drags an internet shortcut to the app, we want to
|
|
// preserve not only the URL but the name of the shortcut. The other case
|
|
// where we need to assert a name is when the node does not already exist
|
|
// in the graph, in this case we'll just use the URL as the name.
|
|
if (name[i] || nameRequired[i]) {
|
|
var currentName = kBMDS.GetTarget(this.mOuter.rdf.GetResource(sourceID[i]), this.mOuter.rdf.GetResource(this.mOuter.NC_NS + "Name"), true);
|
|
if (!currentName) {
|
|
var rDefaultName = this.mOuter.rdf.GetLiteral(name[i] || sourceID[i]);
|
|
if (rDefaultName) {
|
|
var rName = this.mOuter.rdf.GetResource(this.mOuter.NC_NS + "Name");
|
|
kBMDS.Assert(rSource, rName, rDefaultName, true);
|
|
}
|
|
}
|
|
}
|
|
if (dirty)
|
|
this.mOuter.flushBMDatasource();
|
|
}
|
|
},
|
|
onToggleOpenState: function BMOLBuilderObserver_onToggleOpenState(aItemIndex)
|
|
{
|
|
},
|
|
|
|
onCycleHeader: function BMOLBuilderObserver_onCycleHeader(aColumnID, aHeaderElement)
|
|
{
|
|
},
|
|
|
|
onCycleCell: function BMOLBuilderObserver_onCycleCell(aItemIndex, aColumnID)
|
|
{
|
|
},
|
|
|
|
onSelectionChanged: function BMOLBuilderObserver_onSelectionChanged()
|
|
{
|
|
this.mOuter.onCommandUpdate();
|
|
const kStatusBar = document.getAnonymousElementByAttribute(this.mOuter, "anonid", "statusbar-text");
|
|
const currentIndex = this.mOuter.currentIndex;
|
|
var displayValue = "";
|
|
if (kStatusBar && this.mOuter.outlinerBoxObject.selection.count == 1) {
|
|
if (this.mOuter.outlinerBoxObject.view.isContainer(currentIndex)) {
|
|
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
|
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
|
const kRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
|
|
const krSrc = this.mOuter.outlinerBuilder.getResourceAtIndex(currentIndex);
|
|
try {
|
|
kRDFC.Init(this.mOuter.db, krSrc);
|
|
var count = kRDFC.GetCount();
|
|
displayValue = this.mOuter._bundle.GetStringFromName("status_foldercount");
|
|
displayValue = displayValue.replace(/%num_items%/, count);
|
|
}
|
|
catch (e) {
|
|
}
|
|
}
|
|
else {
|
|
try {
|
|
displayValue = this.mOuter.db.GetTarget(this.mOuter.outlinerBuilder.getResourceAtIndex(currentIndex), this.mOuter.rdf.GetResource(this.mOuter.NC_NS + "URL"), true);
|
|
displayValue = displayValue.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
|
}
|
|
catch (e) {
|
|
displayValue = "";
|
|
}
|
|
}
|
|
if (displayValue.substring(0, 3) == "NC:")
|
|
displayValue = "";
|
|
kStatusBar.label = displayValue;
|
|
}
|
|
},
|
|
|
|
isEditable: function BMOLBuilderObserver_isEditable(aItemIndex, aColumnID)
|
|
{
|
|
},
|
|
|
|
onSetCellText: function BMOLBuilderObserver_onSetCellText(aItemIndex, aColumnID, aValue)
|
|
{
|
|
},
|
|
|
|
onPerformAction: function BMOLBuilderObserver_onPerformAction(aAction)
|
|
{
|
|
},
|
|
|
|
onPerformActionOnRow: function BMOLBuilderObserver_onPerformActionOnRow(aAction, aItemIndex)
|
|
{
|
|
},
|
|
|
|
onPerformActionOnCell: function BMOLBuilderObserver_onPerformActionOnCell(aAction, aItemIndex, aColumnID)
|
|
{
|
|
}
|
|
})
|
|
]]></field>
|
|
|
|
<!-- RDF utility functions required by base binding -->
|
|
<property name="db">
|
|
<getter><![CDATA[
|
|
return this.outlinerBody.database;
|
|
]]></getter>
|
|
</property>
|
|
|
|
<method name="doBookmarksCommand">
|
|
<parameter name="aSourceURI"/>
|
|
<parameter name="aCommand"/>
|
|
<parameter name="aArgumentsArray"/>
|
|
<body><![CDATA[
|
|
var rCommand = this.rdf.GetResource(aCommand);
|
|
|
|
var kSuppArrayContractID = "@mozilla.org/supports-array;1";
|
|
var kSuppArrayIID = Components.interfaces.nsISupportsArray;
|
|
var sourcesArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
|
|
if (aSourceURI) {
|
|
var rSource = this.rdf.GetResource(aSourceURI);
|
|
sourcesArray.AppendElement (rSource);
|
|
}
|
|
|
|
var argsArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
|
|
for (var i = 0; i < aArgumentsArray.length; ++i) {
|
|
var rArc = this.rdf.GetResource(aArgumentsArray[i].property);
|
|
argsArray.AppendElement(rArc);
|
|
var rValue = null;
|
|
if ("resource" in aArgumentsArray[i])
|
|
rValue = this.rdf.GetResource(aArgumentsArray[i].resource);
|
|
else
|
|
rValue = this.rdf.GetLiteral(aArgumentsArray[i].literal);
|
|
argsArray.AppendElement(rValue);
|
|
}
|
|
|
|
// Exec the command in the Bookmarks datasource.
|
|
this.bookmarksDS.DoCommand(sourcesArray, rCommand, argsArray);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="refreshSort">
|
|
<parameter name="aContext"/>
|
|
<body><![CDATA[
|
|
var column = document.getAnonymousElementByAttribute(aContext, "sortDirection", "*");
|
|
if (column)
|
|
aContext.outlinerBoxObject.view.cycleHeader(column.id, column);
|
|
aContext = null;
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="selectAll">
|
|
<body><![CDATA[
|
|
this.outlinerBoxObject.selection.selectAll();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="paste">
|
|
<body><![CDATA[
|
|
const kXferableContractID = "@mozilla.org/widget/transferable;1";
|
|
const kXferableIID = Components.interfaces.nsITransferable;
|
|
var xferable = Components.classes[kXferableContractID].createInstance(kXferableIID);
|
|
xferable.addDataFlavor("moz/bookmarkclipboarditem");
|
|
xferable.addDataFlavor("text/x-moz-url");
|
|
xferable.addDataFlavor("text/unicode");
|
|
|
|
const kClipboardContractID = "@mozilla.org/widget/clipboard;1";
|
|
const kClipboardIID = Components.interfaces.nsIClipboard;
|
|
var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID);
|
|
clipboard.getData(xferable, kClipboardIID.kGlobalClipboard);
|
|
|
|
var flavour = { };
|
|
var data = { };
|
|
var length = { };
|
|
xferable.getAnyTransferData(flavour, data, length);
|
|
var nodes = []; var names = [];
|
|
data = data.value.QueryInterface(Components.interfaces.nsISupportsWString).data;
|
|
switch (flavour.value) {
|
|
case "moz/bookmarkclipboarditem":
|
|
nodes = data.split("\n");
|
|
break;
|
|
case "text/x-moz-url":
|
|
var ix = data.indexOf("\n");
|
|
nodes.push(data.substring(0, ix != -1 ? ix : data.length));
|
|
names.push(data.substring(ix));
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
|
|
const kRDFIID = Components.interfaces.nsIRDFService;
|
|
const ksRDF = Components.classes[kRDFContractID].getService(kRDFIID);
|
|
var parentRes;
|
|
const currentIndex = this.currentIndex;
|
|
if (!this.outlinerBoxObject.view.isContainer(currentIndex))
|
|
parentRes = this.parentRes;
|
|
else
|
|
parentRes = this.outlinerBuilder.getResourceAtIndex(currentIndex);
|
|
|
|
const currentRes = this.currentRes;
|
|
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
|
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
|
const ksRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
|
|
var additiveFlag = false;
|
|
for (var i = 0; i < nodes.length; ++i) {
|
|
if (!nodes[i]) continue;
|
|
var rCurrent = ksRDF.GetResource(nodes[i]);
|
|
const krTypeProperty = ksRDF.GetResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
|
var rType = this.db.GetTarget(rCurrent, krTypeProperty, true);
|
|
try {
|
|
rType = rType.QueryInterface(Components.interfaces.nsIRDFResource);
|
|
}
|
|
catch (e) {
|
|
try {
|
|
rType = rType.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
|
}
|
|
catch (e) {
|
|
// OK, no type exists, so node does not exist in the graph.
|
|
// (e.g. user pastes url as text)
|
|
// Do some housekeeping.
|
|
const krName = ksRDF.GetResource(names[i]);
|
|
const krNameProperty = ksRDF.GetResource("http://home.netscape.com/NC-rdf#Name");
|
|
const krBookmark = ksRDF.GetResource("http://home.netscape.com/NC-rdf#Bookmark");
|
|
kBMDS.Assert(rCurrent, krNameProperty, krName, true);
|
|
kBMDS.Assert(rCurrent, krTypeProperty, krBookmark, true);
|
|
}
|
|
}
|
|
// If the node is a folder, then we need to create a new anonymous
|
|
// resource and copy all the arcs over.
|
|
if (rType && rType.Value == "http://home.netscape.com/NC-rdf#Folder")
|
|
rCurrent = BookmarksUtils.cloneFolder(rCurrent, parentRes, currentRes);
|
|
|
|
// If this item already exists in this container, don't paste, as
|
|
// this will result in the creation of multiple copies in the datasource
|
|
// but will not result in an update of the UI. (In Short: we don't
|
|
// handle multiple bookmarks well)
|
|
ksRDFC.Init(this.bookmarksDS, parentRes);
|
|
ix = ksRDFC.IndexOf(rCurrent);
|
|
if (ix != -1)
|
|
continue;
|
|
|
|
ix = ksRDFC.IndexOf(currentRes);
|
|
if (ix != -1)
|
|
ksRDFC.InsertElementAt(rCurrent, ix+1, true);
|
|
else
|
|
ksRDFC.AppendElement(rCurrent);
|
|
|
|
this.flushBMDatasource();
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="copySelection">
|
|
<body><![CDATA[
|
|
const kSuppArrayContractID = "@mozilla.org/supports-array;1";
|
|
const kSuppArrayIID = Components.interfaces.nsISupportsArray;
|
|
var itemArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
|
|
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
|
|
const kRDFIID = Components.interfaces.nsIRDFService;
|
|
const ksRDF = Components.classes[kRDFContractID].getService(kRDFIID);
|
|
const kSuppWStringContractID = "@mozilla.org/supports-wstring;1";
|
|
const kSuppWStringIID = Components.interfaces.nsISupportsWString;
|
|
var bmstring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID);
|
|
var unicodestring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID);
|
|
var htmlstring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID);
|
|
|
|
var sBookmarkItem = ""; var sTextUnicode = ""; var sTextHTML = "";
|
|
var rangeCount = this.outlinerBoxObject.selection.getRangeCount();
|
|
for (var i = rangeCount - 1; i >= 0; --i) {
|
|
var rangeMin = {};
|
|
var rangeMax = {};
|
|
this.outlinerBoxObject.selection.getRangeAt(i, rangeMin, rangeMax);
|
|
for (var j = rangeMax.value; j >= rangeMin.value; --j) {
|
|
var res = this.outlinerBuilder.getResourceAtIndex(j);
|
|
var urlRes = ksRDF.GetResource("http://home.netscape.com/NC-rdf#URL");
|
|
var nameRes = ksRDF.GetResource("http://home.netscape.com/NC-rdf#Name");
|
|
var url = this.db.GetTarget(res, urlRes, true);
|
|
if (url)
|
|
url = url.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
|
var name = this.db.GetTarget(res, nameRes, true);
|
|
name = name.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
|
// XXXben is "\n" the best delimiter here? I think not.
|
|
sBookmarkItem += res.Value + "\n";
|
|
sTextUnicode += url + "\n";
|
|
sTextHTML += "<A HREF=\"" + url + "\">" + name + "</A>";
|
|
}
|
|
}
|
|
|
|
const kXferableContractID = "@mozilla.org/widget/transferable;1";
|
|
const kXferableIID = Components.interfaces.nsITransferable;
|
|
var xferable = Components.classes[kXferableContractID].createInstance(kXferableIID);
|
|
|
|
xferable.addDataFlavor("moz/bookmarkclipboarditem");
|
|
bmstring.data = sBookmarkItem;
|
|
xferable.setTransferData("moz/bookmarkclipboarditem", bmstring, sBookmarkItem.length*2)
|
|
|
|
xferable.addDataFlavor("text/html");
|
|
htmlstring.data = sTextHTML;
|
|
xferable.setTransferData("text/html", htmlstring, sTextHTML.length*2)
|
|
|
|
xferable.addDataFlavor("text/unicode");
|
|
unicodestring.data = sTextUnicode;
|
|
xferable.setTransferData("text/unicode", unicodestring, sTextUnicode.length*2)
|
|
|
|
const kClipboardContractID = "@mozilla.org/widget/clipboard;1";
|
|
const kClipboardIID = Components.interfaces.nsIClipboard;
|
|
var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID);
|
|
clipboard.setData(xferable, null, kClipboardIID.kGlobalClipboard);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="deleteSelection">
|
|
<body><![CDATA[
|
|
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
|
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
|
|
const kRDFIID = Components.interfaces.nsIRDFService;
|
|
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
|
const ksRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
|
|
const ksRDF = Components.classes[kRDFContractID].getService(kRDFIID);
|
|
|
|
var nextIndex = 0; // Used to determine which item to select after the deletion
|
|
// is performed.
|
|
|
|
// Whether or not the selection contains items which cannot be deleted.
|
|
// var selectionContainsImmutableItems = false;
|
|
|
|
var boxObject = this.outlinerBoxObject;
|
|
var outlinerBuilder = this.outlinerBuilder;
|
|
var rangeCount = this.outlinerBoxObject.selection.getRangeCount();
|
|
|
|
var rangeMax = { };
|
|
var rangeMin = { };
|
|
|
|
// First, walk the selection and see if there's anything we /can't/
|
|
// delete. If so, present a warning dialog listing the items that
|
|
// we can't remove.
|
|
const kIMDSContractID = "@mozilla.org/rdf/datasource;1?name=in-memory-datasource";
|
|
const kIMDSIID = Components.interfaces.nsIRDFDataSource;
|
|
var imDS = Components.classes[kIMDSContractID].getService(kIMDSIID);
|
|
|
|
const kRDFCUContractID = "@mozilla.org/rdf/container-utils;1";
|
|
const kRDFCUIID = Components.interfaces.nsIRDFContainerUtils;
|
|
const kRDFCU = Components.classes[kRDFCUContractID].getService(kRDFCUIID);
|
|
|
|
/*
|
|
var immutableList = this.rdf.GetResource("NC:ImmutableBookmarkList");
|
|
var container = kRDFCU.MakeSeq(imDS, immutableList);
|
|
|
|
for (var i = rangeCount - 1; i >= 0; --i) {
|
|
boxObject.selection.getRangeAt(i, rangeMin, rangeMax);
|
|
for (var j = rangeMax.value; j >= rangeMin.value; --j) {
|
|
var resource = outlinerBuilder.getResourceAtIndex(j);
|
|
var type = this.getTypeAtIndex(j);
|
|
if (resource.Value == "NC:BookmarksRoot" || type == this.NC_NS + "IEFavoriteFolder")
|
|
continue;
|
|
if (type != this.NC_NS + "Bookmark" && type != this.NC_NS + "BookmarkSeparator" && type != this.NC_NS + "Folder") {
|
|
// This delete operation contains items which cannot be deleted
|
|
// for one reason or another. Make a list of the items which
|
|
// we can't delete, and show a dialog.
|
|
container.AppendElement(resource);
|
|
selectionContainsImmutableItems = true;
|
|
|
|
// Now we need to ensure that this item's parent chain is not
|
|
// part of the current selection so that we don't delete that. We
|
|
// preserve selection on any deletable items in the folder chain
|
|
// however, and these are removed.
|
|
for (var parentIndex = boxObject.view.getParentIndex(j);
|
|
parentIndex != -1;
|
|
parentIndex = boxObject.view.getParentIndex(parentIndex)) {
|
|
// Note that we don't combine this with the check in the
|
|
// |while| above, as this would mean that if you had a folder
|
|
// hierarchy consisting of:
|
|
//
|
|
// Folder -> [ selected ]
|
|
// Folder -> [ not selected ]
|
|
// Immutable item [ selected ]
|
|
//
|
|
// This code would not work and the containing folder would be
|
|
// deleted.
|
|
if (boxObject.selection.isSelected(parentIndex))
|
|
boxObject.selection.toggleSelect(parentIndex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Present a dialog showing any items that we can't delete.
|
|
// if (selectionContainsImmutableItems) {
|
|
// openDialog("chrome://communicator/content/bookmarks/deleteBookmark.xul", "", "modal=yes,resizable=no", imDS);
|
|
|
|
// Now clear the list of immutable items.
|
|
ksRDFC.Init(imDS, immutableList);
|
|
var count = ksRDFC.GetCount();
|
|
for (var i = 0; i < count; ++i)
|
|
ksRDFC.RemoveElementAt(i, false);
|
|
}
|
|
*/
|
|
for (i = rangeCount - 1; i >= 0; --i) {
|
|
rangeMax = { };
|
|
rangeMin = { };
|
|
boxObject.selection.getRangeAt(i, rangeMin, rangeMax);
|
|
for (var j = rangeMax.value; j >= rangeMin.value; --j) {
|
|
var resource = outlinerBuilder.getResourceAtIndex(j);
|
|
if (resource.Value == "NC:BookmarksRoot")
|
|
continue;
|
|
var currType = this.getTypeAtIndex(j);
|
|
if (currType == this.NC_NS + "IEFavoriteFolder") {
|
|
const kPrefSvcContractID = "@mozilla.org/preferences;1";
|
|
const kPrefSvcIID = Components.interfaces.nsIPref;
|
|
const kPrefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
|
|
kPrefSvc.SetBoolPref("browser.bookmarks.import_system_favorites", false);
|
|
}
|
|
else if (currType != this.NC_NS + "Bookmark" &&
|
|
currType != this.NC_NS + "BookmarkSeparator" &&
|
|
currType != this.NC_NS + "Folder")
|
|
continue;
|
|
var parentIndex = boxObject.view.getParentIndex(j);
|
|
var parent;
|
|
if (parentIndex != -1)
|
|
parent = outlinerBuilder.getResourceAtIndex(parentIndex);
|
|
else {
|
|
// assume its parent is the root
|
|
parent = ksRDF.GetResource("NC:BookmarksRoot");
|
|
}
|
|
ksRDFC.Init(this.bookmarksDS, parent);
|
|
ksRDFC.RemoveElement(resource, true);
|
|
nextIndex = j;
|
|
}
|
|
}
|
|
|
|
// Select the next row
|
|
boxObject.selection.select(nextIndex);
|
|
]]></body>
|
|
</method>
|
|
<method name="openFindDialog">
|
|
<body><![CDATA[
|
|
openDialog("chrome://communicator/content/bookmarks/findBookmark.xul",
|
|
"FindBookmarksWindow",
|
|
"dialog=no,centerscreen,resizable=no,chrome,dependent");
|
|
]]></body>
|
|
</method>
|
|
<method name="canSendLink">
|
|
<body><![CDATA[
|
|
var selectedIndex = this.outlinerBoxObject.selection.currentIndex;
|
|
return (this.outlinerBoxObject.selection.count == 1 &&
|
|
!this.outlinerBoxObject.view.isContainer(selectedIndex) &&
|
|
this.getTypeAtIndex(selectedIndex) != this.NC_NS + "BookmarkSeparator");
|
|
]]></body>
|
|
</method>
|
|
<method name="sendLink">
|
|
<body><![CDATA[
|
|
const currentRes = this.currentRes;
|
|
var urlLiteral = this.db.GetTarget(currentRes, this.rdf.GetResource(this.NC_NS + "URL"), true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
|
var nameLiteral = this.db.GetTarget(currentRes, this.rdf.GetResource(this.NC_NS + "Name"), true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
|
sendLink(urlLiteral, nameLiteral);
|
|
]]></body>
|
|
</method>
|
|
<method name="getAllCmds">
|
|
<parameter name="aNodeID"/>
|
|
<body><![CDATA[
|
|
var type = this.resolveType(aNodeID);
|
|
if (!type) {
|
|
if (aNodeID == "NC:PersonalToolbarFolder" || aNodeID == "NC:BookmarksRoot")
|
|
type = "http://home.netscape.com/NC-rdf#Folder";
|
|
else
|
|
return null;
|
|
}
|
|
var commands = [];
|
|
switch (type) {
|
|
case "http://home.netscape.com/NC-rdf#BookmarkSeparator":
|
|
commands = ["bm_find", "bm_separator", "bm_cut", "bm_copy", "bm_paste",
|
|
"bm_delete", "bm_separator", "bm_fileBookmark", "bm_separator",
|
|
"bm_newfolder"];
|
|
break;
|
|
case "http://home.netscape.com/NC-rdf#Bookmark":
|
|
commands = ["bm_open", "bm_separator", "bm_cut",
|
|
"bm_copy", "bm_paste", "bm_delete", "bm_separator", "bm_rename",
|
|
"bm_separator", "bm_fileBookmark", "bm_separator", "bm_newfolder",
|
|
"bm_separator", "bm_properties"];
|
|
break;
|
|
case "http://home.netscape.com/NC-rdf#Folder":
|
|
commands = ["bm_openfolder", "bm_openfolderinnewwindow", "bm_separator",
|
|
"bm_cut", "bm_copy", "bm_paste", "bm_delete", "bm_separator", "bm_rename",
|
|
"bm_separator", "bm_fileBookmark", "bm_separator",
|
|
"bm_newfolder", "bm_separator", "bm_properties"];
|
|
break;
|
|
case "http://home.netscape.com/NC-rdf#IEFavoriteFolder":
|
|
commands = ["bm_open", "bm_find", "bm_separator", "bm_copy", "bm_delete", "bm_separator", "bm_rename", "bm_separator",
|
|
"bm_fileBookmark", "bm_separator", "bm_separator", "bm_properties"];
|
|
break;
|
|
case "http://home.netscape.com/NC-rdf#IEFavorite":
|
|
commands = ["bm_open", "bm_find", "bm_separator", "bm_copy"];
|
|
break;
|
|
case "http://home.netscape.com/NC-rdf#FileSystemObject":
|
|
commands = ["bm_open", "bm_find", "bm_separator", "bm_copy"];
|
|
break;
|
|
default:
|
|
var source = this.rdf.GetResource(aNodeID);
|
|
return this.db.GetAllCmds(source);
|
|
}
|
|
return new CommandArrayEnumerator(commands);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="flattenEnumerator">
|
|
<parameter name="aEnumerator"/>
|
|
<body><![CDATA[
|
|
if ("_index" in aEnumerator)
|
|
return aEnumerator._inner;
|
|
|
|
var temp = [];
|
|
while (aEnumerator.hasMoreElements())
|
|
temp.push(aEnumerator.getNext());
|
|
return temp;
|
|
]]></body>
|
|
</method>
|
|
<method name="findCommonNodes">
|
|
<parameter name="aNewArray"/>
|
|
<parameter name="aOldArray"/>
|
|
<body><![CDATA[
|
|
var common = [];
|
|
for (var i = 0; i < aNewArray.length; ++i) {
|
|
for (var j = 0; j < aOldArray.length; ++j) {
|
|
if (common.length > 0 && common[common.length-1] == aNewArray[i])
|
|
continue;
|
|
if (aNewArray[i] == aOldArray[j])
|
|
common.push(aNewArray[i]);
|
|
}
|
|
}
|
|
return common;
|
|
]]></body>
|
|
</method>
|
|
<method name="createMenuItem">
|
|
<parameter name="aDisplayName"/>
|
|
<parameter name="aCommandName"/>
|
|
<parameter name="aSelectedIndex"/>
|
|
<body><![CDATA[
|
|
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
var xulElement = document.createElementNS(kXULNS, "menuitem");
|
|
xulElement.setAttribute("cmd", aCommandName);
|
|
xulElement.setAttribute("command", "cmd_" + aCommandName.substring(this.NC_NS_CMD.length));
|
|
switch (aCommandName) {
|
|
case this.NC_NS_CMD + "bm_open":
|
|
xulElement.setAttribute("label", aDisplayName);
|
|
xulElement.setAttribute("default", "true");
|
|
break;
|
|
case this.NC_NS_CMD + "bm_openfolder":
|
|
aDisplayName = this.outlinerBoxObject.view.isContainerOpen(aSelectedIndex) ? this._bundle.GetStringFromName("cmd_bm_openfolder2") : aDisplayName;
|
|
xulElement.setAttribute("label", aDisplayName);
|
|
xulElement.setAttribute("default", "true");
|
|
break;
|
|
case this.NC_NS_CMD + "bm_renamebookmark":
|
|
if (!document.popupNode.hasAttribute("type")) {
|
|
xulElement.setAttribute("label", this._bundle.GetStringFromName("cmd_bm_renamebookmark2"));
|
|
xulElement.setAttribute("cmd", (this.NC_NS_CMD + "bm_editurl"));
|
|
}
|
|
else
|
|
xulElement.setAttribute("label", aDisplayName);
|
|
break;
|
|
default:
|
|
xulElement.setAttribute("label", aDisplayName);
|
|
break;
|
|
}
|
|
return xulElement;
|
|
]]></body>
|
|
</method>
|
|
<method name="getCommandName">
|
|
<parameter name="aCommand"/>
|
|
<body><![CDATA[
|
|
var cmdName = aCommand.substring(this.NC_NS_CMD.length);
|
|
try {
|
|
// Note: this will succeed only if there's a string in the bookmarks
|
|
// string bundle for this command name. Otherwise, <xul:stringbundle/>
|
|
// will throw, we'll catch & stifle the error, and look up the command
|
|
// name in the datasource.
|
|
return this._bundle.GetStringFromName("cmd_" + cmdName);
|
|
}
|
|
catch (e) {
|
|
// XXX - WORK TO DO HERE! (rjc will cry if we don't fix this)
|
|
// need to ask the ds for the commands for this node, however we don't
|
|
// have the right params. This is kind of a problem.
|
|
dump("*** BAD! EVIL! WICKED! NO! ACK! ARGH! ORGH!\n");
|
|
const rName = this.rdf.GetResource(this.NC_NS + "Name");
|
|
const rSource = this.rdf.GetResource(aCommand);
|
|
return this.db.GetTarget(rSource, rName, true).Value;
|
|
}
|
|
]]></body>
|
|
</method>
|
|
<method name="createContextMenu">
|
|
<parameter name="aEvent"/>
|
|
<body><![CDATA[
|
|
var popup = aEvent.target;
|
|
// clear out the old context menu contents (if any)
|
|
while (popup.hasChildNodes())
|
|
popup.removeChild(popup.firstChild);
|
|
|
|
var popupNode = document.popupNode;
|
|
var commonCommands = [];
|
|
var rangeCount = this.outlinerBoxObject.selection.getRangeCount();
|
|
for (var i = rangeCount - 1; i >= 0; --i) {
|
|
var minRange = {};
|
|
var maxRange = {};
|
|
this.outlinerBoxObject.selection.getRangeAt(i, minRange, maxRange);
|
|
for (var j = maxRange.value; j >= minRange.value; --j) {
|
|
var nodeURI = this.outlinerBuilder.getResourceAtIndex(j).Value;
|
|
var commands = this.getAllCmds(nodeURI);
|
|
if (!commands) {
|
|
aEvent.preventDefault();
|
|
return;
|
|
}
|
|
commands = this.flattenEnumerator(commands);
|
|
if (!commonCommands.length) commonCommands = commands;
|
|
commonCommands = this.findCommonNodes(commands, commonCommands);
|
|
}
|
|
}
|
|
if (!commonCommands.length) {
|
|
aEvent.preventDefault();
|
|
return;
|
|
}
|
|
|
|
// Now that we should have generated a list of commands that is valid
|
|
// for the entire selection, build a context menu.
|
|
for (i = 0; i < commonCommands.length; ++i) {
|
|
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
var currCommand = commonCommands[i].QueryInterface(Components.interfaces.nsIRDFResource).Value;
|
|
var element = null;
|
|
if (currCommand != this.NC_NS_CMD + "bm_separator") {
|
|
var commandName = this.getCommandName(currCommand);
|
|
var selectedIndex = this.outlinerBoxObject.selection.currentIndex;
|
|
element = this.createMenuItem(commandName, currCommand, selectedIndex);
|
|
}
|
|
else if (i != 0 && i < commonCommands.length-1) {
|
|
// Never append a separator as the first or last element in a context
|
|
// menu.
|
|
element = document.createElementNS(kXULNS, "menuseparator");
|
|
}
|
|
|
|
if (element)
|
|
popup.appendChild(element);
|
|
}
|
|
]]></body>
|
|
</method>
|
|
<method name="openPropertiesForItem">
|
|
<body><![CDATA[
|
|
// XXX if not bookmarks separator
|
|
var itemURI = this.outlinerBuilder.getResourceAtIndex(this.outlinerBoxObject.selection.currentIndex).Value;
|
|
openDialog("chrome://communicator/content/bookmarks/bm-props.xul",
|
|
"", "centerscreen,chrome,dialog=no,resizable=no,dependent",
|
|
itemURI);
|
|
]]></body>
|
|
</method>
|
|
<method name="setAsPersonalToolbarFolder">
|
|
<body><![CDATA[
|
|
var selectedURI = this.outlinerBuilder.getResourceAtIndex(this.outlinerBoxObject.selection.currentIndex).Value;
|
|
var args = [];
|
|
this.doBookmarksCommand(selectedURI,
|
|
this.NC_NS_CMD + "setpersonaltoolbarfolder", args);
|
|
|
|
]]></body>
|
|
</method>
|
|
<method name="setAsNewSearchFolder">
|
|
<body><![CDATA[
|
|
var selectedURI = this.outlinerBuilder.getResourceAtIndex(this.outlinerBoxObject.selection.currentIndex).Value;
|
|
var args = [];
|
|
this.doBookmarksCommand(selectedURI,
|
|
this.NC_NS_CMD + "setnewsearchfolder", args);
|
|
]]></body>
|
|
</method>
|
|
<method name="setAsNewBookmarkFolder">
|
|
<body><![CDATA[
|
|
var selectedURI = this.outlinerBuilder.getResourceAtIndex(this.outlinerBoxObject.selection.currentIndex).Value;
|
|
var args = [];
|
|
this.doBookmarksCommand(selectedURI,
|
|
this.NC_NS_CMD + "setnewbookmarkfolder", args);
|
|
]]></body>
|
|
</method>
|
|
<method name="addBookmark">
|
|
<body><![CDATA[
|
|
const currentIndex = this.currentIndex;
|
|
var parentIndex;
|
|
if (this.outlinerBoxObject.view.rowCount) {
|
|
if (this.outlinerBoxObject.view.isContainer(currentIndex))
|
|
parentIndex = currentIndex;
|
|
else
|
|
parentIndex = this.outlinerBoxObject.view.getParentIndex(currentIndex);
|
|
}
|
|
else
|
|
parentIndex = -1;
|
|
var parentURI;
|
|
if (parentIndex == -1)
|
|
parentURI = this.rdf.GetResource("NC:BookmarksRoot").Value;
|
|
else
|
|
parentURI = this.outlinerBuilder.getResourceAtIndex(parentIndex).Value;
|
|
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
|
|
"centerscreen,chrome,modal=yes,dialog=yes,resizable=no", null, null, parentURI, null, "newBookmark");
|
|
]]></body>
|
|
</method>
|
|
<method name="fileBookmark">
|
|
<body><![CDATA[
|
|
// XXX folder arg
|
|
var rv = { selectedFolder: null };
|
|
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
|
|
"centerscreen,chrome,modal=yes,dialog=yes,resizable=yes", null, null, null, null, "selectFolder", rv);
|
|
if (rv.selectedFolder) {
|
|
var rangeCount = this.outlinerBoxObject.selection.getRangeCount();
|
|
for (var k = rangeCount - 1; k >= 0; --k) {
|
|
var rangeMin = {};
|
|
var rangeMax = {};
|
|
this.outlinerBoxObject.selection.getRangeAt(k, rangeMin, rangeMax);
|
|
for (var i = rangeMax.value; i >= rangeMin.value; --i) {
|
|
var selected = this.outlinerBuilder.getResourceAtIndex(i);
|
|
if (selected.Value == rv.selectedFolder)
|
|
return; // Selection contains the target folder. Just fail silently.
|
|
var additiveFlag = false;
|
|
var parentIndex = this.outlinerBoxObject.view.getParentIndex(i);
|
|
var parentURI;
|
|
if (parentIndex == -1)
|
|
parentURI = this.rdf.GetResource("NC:BookmarksRoot").Value;
|
|
else
|
|
parentURI = this.outlinerBuilder.getResourceAtIndex(parentIndex).Value;
|
|
this.moveBookmark(selected.Value, parentURI, rv.selectedFolder);
|
|
// gBookmarksShell.selectFolderItem(rv.selectedFolder, selected.Value, additiveFlag);
|
|
if (!additiveFlag) additiveFlag = true;
|
|
}
|
|
}
|
|
this.flushBMDatasource();
|
|
}
|
|
]]></body>
|
|
</method>
|
|
<method name="moveBookmark">
|
|
<parameter name="aBookmarkURI"/>
|
|
<parameter name="aFromFolderURI"/>
|
|
<parameter name="aToFolderURI"/>
|
|
<body><![CDATA[
|
|
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
|
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
|
const kRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
|
|
const krSrc = this.rdf.GetResource(aBookmarkURI);
|
|
const krOldParent = this.rdf.GetResource(aFromFolderURI);
|
|
const krNewParent = this.rdf.GetResource(aToFolderURI);
|
|
kRDFC.Init(this.bookmarksDS, krNewParent);
|
|
kRDFC.AppendElement(krSrc);
|
|
kRDFC.Init(this.bookmarksDS, krOldParent);
|
|
kRDFC.RemoveElement(krSrc, true);
|
|
]]></body>
|
|
</method>
|
|
<method name="importBookmarks">
|
|
<body><![CDATA[
|
|
try {
|
|
const kFilePickerContractID = "@mozilla.org/filepicker;1";
|
|
const kFilePickerIID = Components.interfaces.nsIFilePicker;
|
|
const kFilePicker = Components.classes[kFilePickerContractID].createInstance(kFilePickerIID);
|
|
|
|
const kTitle = this._bundle.GetStringFromName("SelectImport");
|
|
kFilePicker.init(window, kTitle, kFilePickerIID["modeOpen"]);
|
|
kFilePicker.appendFilters(kFilePickerIID.filterHTML | kFilePickerIID.filterAll);
|
|
var fileName;
|
|
if (kFilePicker.show() != kFilePickerIID.returnCancel) {
|
|
fileName = kFilePicker.fileURL.spec;
|
|
if (!fileName) return;
|
|
}
|
|
else return;
|
|
}
|
|
catch (e) {
|
|
return;
|
|
}
|
|
var seln = null;
|
|
try {
|
|
seln = this.outlinerBuilder.getResourceAtIndex(this.outlinerBoxObject.selection.currentIndex).Value;
|
|
}
|
|
catch(ex) {
|
|
seln = this.rdf.GetResource("NC:BookmarksRoot").Value;
|
|
}
|
|
var args = [{ property: this.NC_NS + "URL", literal: fileName}];
|
|
this.doBookmarksCommand(seln, this.NC_NS_CMD + "import", args);
|
|
]]></body>
|
|
</method>
|
|
<method name="exportBookmarks">
|
|
<body><![CDATA[
|
|
try {
|
|
const kFilePickerContractID = "@mozilla.org/filepicker;1";
|
|
const kFilePickerIID = Components.interfaces.nsIFilePicker;
|
|
const kFilePicker = Components.classes[kFilePickerContractID].createInstance(kFilePickerIID);
|
|
|
|
const kTitle = this._bundle.GetStringFromName("EnterExport");
|
|
kFilePicker.init(window, kTitle, kFilePickerIID["modeSave"]);
|
|
kFilePicker.appendFilters(kFilePickerIID.filterHTML | kFilePickerIID.filterAll);
|
|
kFilePicker.defaultString = "bookmarks.html";
|
|
var fileName;
|
|
if (kFilePicker.show() != kFilePickerIID.returnCancel) {
|
|
fileName = kFilePicker.fileURL.spec;
|
|
if (!fileName) return;
|
|
}
|
|
else return;
|
|
}
|
|
catch (e) {
|
|
return;
|
|
}
|
|
var seln = null;
|
|
try {
|
|
seln = this.outlinerBuilder.getResourceAtIndex(this.outlinerBoxObject.selection.currentIndex).Value;
|
|
}
|
|
catch(ex) {
|
|
seln = this.rdf.GetResource("NC:BookmarksRoot").Value;
|
|
}
|
|
var args = [{ property: this.NC_NS + "URL", literal: fileName}];
|
|
this.doBookmarksCommand(seln, this.NC_NS_CMD + "export", args);
|
|
]]></body>
|
|
</method>
|
|
<method name="openFolderInNewWindow">
|
|
<body><![CDATA[
|
|
var selectedIndex = this.outlinerBoxObject.selection.currentIndex;
|
|
var selectedURI = this.outlinerBuilder.getResourceAtIndex(selectedIndex).Value;
|
|
openDialog("chrome://communicator/content/bookmarks/bookmarks.xul",
|
|
"", "chrome,all,dialog=no", selectedURI);
|
|
]]>
|
|
</body>
|
|
</method>
|
|
<method name="createNewSeparator">
|
|
<body><![CDATA[
|
|
var currIndex = this.outlinerBoxObject.selection.currentIndex;
|
|
if (currIndex == -1)
|
|
currIndex = this.outlinerBoxObject.view.rowCount - 1;
|
|
var parentIndex = this.outlinerBoxObject.view.getParentIndex(currIndex);
|
|
var parentValue;
|
|
if (parentIndex == -1)
|
|
parentValue = this.rdf.GetResource("NC:BookmarksRoot").Value;
|
|
else
|
|
parentValue = this.outlinerBuilder.getResourceAtIndex(parentIndex).Value;
|
|
args = [{ property: this.NC_NS + "parent",
|
|
resource: parentValue }];
|
|
this.doBookmarksCommand(this.outlinerBuilder.getResourceAtIndex(currIndex).Value,
|
|
this.NC_NS_CMD + "newseparator", args);
|
|
]]></body>
|
|
</method>
|
|
<method name="createNewFolder">
|
|
<body><![CDATA[
|
|
const kPromptSvcContractID = "@mozilla.org/embedcomp/prompt-service;1";
|
|
const kPromptSvcIID = Components.interfaces.nsIPromptService;
|
|
const kPromptSvc = Components.classes[kPromptSvcContractID].getService(kPromptSvcIID);
|
|
var defaultValue = this._bundle.GetStringFromName("ile_newfolder");
|
|
var dialogTitle = this._bundle.GetStringFromName("newfolder_dialog_title");
|
|
var dialogMsg = this._bundle.GetStringFromName("newfolder_dialog_msg");
|
|
var stringValue = { value: defaultValue };
|
|
var relativeIndex = this.currentIndex;
|
|
const currentIndex = this.currentIndex;
|
|
var parentRes;
|
|
var isParent = false;
|
|
if (kPromptSvc.prompt(window, dialogTitle, dialogMsg, stringValue, null, { value: 0 })) {
|
|
if (currentIndex < this.outlinerBoxObject.view.rowCount) {
|
|
// If it's an open container, the relative index should be that of the last child.
|
|
if (this.outlinerBoxObject.view.isContainerOpen(currentIndex)) {
|
|
isParent = true;
|
|
var index = currentIndex + 1;
|
|
while (index < this.outlinerBoxObject.view.rowCount
|
|
&& this.outlinerBoxObject.view.getParentIndex(index) == currentIndex)
|
|
++index;
|
|
relativeIndex = index - 1;
|
|
}
|
|
if (isParent) {
|
|
parentRes = this.outlinerBuilder.getResourceAtIndex(this.outlinerBoxObject.view.getParentIndex(relativeIndex));
|
|
} else {
|
|
parentRes = this.parentRes;
|
|
}
|
|
}
|
|
else {
|
|
parentRes = this.rdf.GetResource("NC:BookmarksRoot");
|
|
relativeIndex = -1;
|
|
}
|
|
var args = [{ property: this.NC_NS + "parent",
|
|
resource: parentRes.Value },
|
|
{ property: this.NC_NS + "Name",
|
|
literal: stringValue.value }];
|
|
this.bookmarksDS.AddObserver(this.newFolderRDFObserver);
|
|
var relativeRes;
|
|
if (relativeIndex != -1)
|
|
relativeRes = this.outlinerBuilder.getResourceAtIndex(relativeIndex).Value;
|
|
else
|
|
relativeRes = this.rdf.GetResource("NC:BookmarksRoot");;
|
|
|
|
this.doBookmarksCommand(relativeRes, this.NC_NS_CMD + "newfolder", args);
|
|
this.bookmarksDS.RemoveObserver(this.newFolderRDFObserver);
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="openItem">
|
|
<parameter name="aEvent"/>
|
|
<body><![CDATA[
|
|
if (this.outlinerBoxObject.view.isContainer(this.outlinerBoxObject.selection.currentIndex))
|
|
return;
|
|
var urlRes = this.rdf.GetResource(this.NC_NS + "URL");
|
|
var urlValue = this.db.GetTarget(this.currentRes, urlRes, true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
|
|
|
// Ignore "NC:" and empty urls.
|
|
if (urlValue.substring(0,3) == "NC:" || !urlValue) return;
|
|
if (aEvent && aEvent.altKey)
|
|
this.openPropertiesForItem();
|
|
else
|
|
openDialog (this._browserURL, "_blank", "chrome,all,dialog=no", urlValue);
|
|
|
|
if (aEvent)
|
|
aEvent.preventBubble();
|
|
]]></body>
|
|
</method>
|
|
<method name="canPaste">
|
|
<body><![CDATA[
|
|
// XXXben
|
|
return true;
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="newBookmark">
|
|
<body><![CDATA[
|
|
var insertAt = this.getNextRowIndex();
|
|
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
|
|
"centerscreen,chrome,modal=yes,dialog=yes,resizable=no", null, null, folder, null, "newBookmark");
|
|
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
<!-- Full Bookmarks Outliner, multi-columned -->
|
|
<!-- Localize column labels! -->
|
|
<binding id="bookmarks-outliner-full" extends="chrome://communicator/content/bookmarks/bookmarks.xml#bookmarks-outliner">
|
|
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl"
|
|
contextmenu="_child">
|
|
<!-- XXXben need focus event handler for cmd update -->
|
|
<menupopup id="bmContext"
|
|
onpopupshowing="this.parentNode.createContextMenu(event);"/>
|
|
<vbox flex="1">
|
|
<outliner flex="1" flags="dont-test-empty" anonid="bookmarks-outliner" enableColumnDrag="true">
|
|
<outlinerbody anonid="bookmarks-outlinerbody" datasources="rdf:bookmarks rdf:internetsearch rdf:files rdf:localsearch" flex="1" ref="NC:BookmarksRoot"
|
|
ondblclick="this.parentNode.parentNode.parentNode.openItem(event);"
|
|
ondraggesture="nsDragAndDrop.startDrag(event, this.parentNode.parentNode.parentNode.DNDObserver);"
|
|
onselect="this.parentNode.parentNode.parentNode.outlinerBoxObject.view.selectionChanged();">
|
|
<template>
|
|
<rule rdf:type="http://home.netscape.com/NC-rdf#BookmarkSeparator">
|
|
<outlinerrow uri="rdf:*" properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type separator" />
|
|
</rule>
|
|
<rule>
|
|
<outlinerrow uri="rdf:*" properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type rdf:http://home.netscape.com/NC-rdf#loading rdf:http://home.netscape.com/WEB-rdf#status">
|
|
<outlinercell ref="Name" label="rdf:http://home.netscape.com/NC-rdf#Name" />
|
|
<outlinercell ref="URL" label="rdf:http://home.netscape.com/NC-rdf#URL" />
|
|
<outlinercell ref="ShortcutURL" label="rdf:http://home.netscape.com/NC-rdf#ShortcutURL" />
|
|
<outlinercell ref="Description" label="rdf:http://home.netscape.com/NC-rdf#Description" />
|
|
<outlinercell ref="LastVisitDate" label="rdf:http://home.netscape.com/WEB-rdf#LastVisitDate"/>
|
|
<outlinercell ref="AddDate" label="rdf:http://home.netscape.com/NC-rdf#BookmarkAddDate" />
|
|
<outlinercell ref="LastModDate" label="rdf:http://home.netscape.com/NC-rdf#LastModifiedDate" />
|
|
</outlinerrow>
|
|
</rule>
|
|
</template>
|
|
</outlinerbody>
|
|
<outlinercol id="Name" label="&outlinercol.name.label;" flex="1" primary="true" class="outlinercol-inset-header sortDirectionIndicator" persist="width hidden sortActive sortDirection ordinal" sort="rdf:http://home.netscape.com/NC-rdf#Name"
|
|
sortActive="true" sortDirection="descending"/>
|
|
<splitter class="tree-splitter" />
|
|
<outlinercol id="URL" label="&outlinercol.url.label;" flex="1" class="outlinercol-inset-header sortDirectionIndicator" sort="rdf:http://home.netscape.com/NC-rdf#URL" persist="width hidden sortActive sortDirection ordinal" />
|
|
<splitter class="tree-splitter" />
|
|
<outlinercol id="ShortcutURL" label="&outlinercol.shortcut.label;" hidden="true" flex="1" class="outlinercol-inset-header sortDirectionIndicator" persist="hidden width sortActive sortDirection ordinal" sort="rdf:http://home.netscape.com/NC-rdf#ShortcutURL"/>
|
|
<splitter class="tree-splitter"/>
|
|
<outlinercol id="Description" label="&outlinercol.description.label;" hidden="true" flex="1" class="outlinercol-inset-header sortDirectionIndicator" persist="hidden width sortActive sortDirection ordinal" sort="rdf:http://home.netscape.com/NC-rdf#Description"/>
|
|
<splitter class="tree-splitter"/>
|
|
<outlinercol id="AddDate" label="&outlinercol.addedon.label;" hidden="true" flex="1" class="outlinercol-inset-header sortDirectionIndicator" sort="rdf:http://home.netscape.com/NC-rdf#BookmarkAddDate" persist="width hidden sortActive sortDirection ordinal" />
|
|
<splitter class="tree-splitter" />
|
|
<outlinercol id="LastModDate" label="&outlinercol.lastmod.label;" hidden="true" flex="1" class="outlinercol-inset-header sortDirectionIndicator" sort="rdf:http://home.netscape.com/NC-rdf#LastModifiedDate" persist="width hidden sortActive sortDirection ordinal" />
|
|
<splitter class="tree-splitter" />
|
|
<outlinercol id="LastVisitDate" label="&outlinercol.lastvisit.label;" hidden="true" flex="1" class="outlinercol-inset-header sortDirectionIndicator" sort="rdf:http://home.netscape.com/NC-rdf#LastVisitDate" persist="width hidden sortActive sortDirection ordinal" />
|
|
</outliner>
|
|
<statusbar class="chromeclass-status" inherits="hidden=hidestatusbar" hidden="false">
|
|
<statusbarpanel anonid="statusbar-text" flex="1"/>
|
|
</statusbar>
|
|
</vbox>
|
|
</xbl:content>
|
|
</binding>
|
|
<!-- Single column outliner -->
|
|
<binding id="bookmarks-outliner-name" extends="chrome://communicator/content/bookmarks/bookmarks.xml#bookmarks-outliner">
|
|
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl"
|
|
contextmenu="_child">
|
|
<menupopup id="bmContext"
|
|
onpopupshowing="this.parentNode.createContextMenu(event);"/>
|
|
<outliner flex="1" flags="dont-test-empty" anonid="bookmarks-outliner" inherits="class=outlinerclass" enableColumnDrag="true">
|
|
<outlinerbody anonid="bookmarks-outlinerbody" datasources="rdf:bookmarks rdf:internetsearch rdf:files rdf:localsearch" flex="1" ref="NC:BookmarksRoot"
|
|
ondblclick="this.parentNode.parentNode.openItem(event);"
|
|
ondraggesture="nsDragAndDrop.startDrag(event, this.parentNode.parentNode.DNDObserver);"
|
|
onselect="this.parentNode.parentNode.outlinerBoxObject.view.selectionChanged();">
|
|
<template>
|
|
<rule rdf:type="http://home.netscape.com/NC-rdf#BookmarkSeparator">
|
|
<outlinerrow uri="rdf:*" properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type separator" />
|
|
</rule>
|
|
<rule>
|
|
<outlinerrow uri="rdf:*" properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type rdf:http://home.netscape.com/NC-rdf#loading rdf:http://home.netscape.com/WEB-rdf#status">
|
|
<outlinercell ref="Name" label="rdf:http://home.netscape.com/NC-rdf#Name" />
|
|
</outlinerrow>
|
|
</rule>
|
|
</template>
|
|
</outlinerbody>
|
|
<outlinercol id="Name" label="&outlinercol.name.label;" flex="1" primary="true" class="outlinercol-header outlinercol-inset-header sortDirectionIndicator" persist="width hidden sortActive sortDirection" sort="rdf:http://home.netscape.com/NC-rdf#Name"
|
|
sortActive="true" sortDirection="descending"/>
|
|
</outliner>
|
|
</xbl:content>
|
|
</binding>
|
|
</bindings>
|
|
<!--
|
|
|
|
API:
|
|
- root ref
|
|
- datasources
|
|
- columns
|
|
- click count
|
|
- sort
|
|
- selection
|
|
- default action oncommand
|
|
- context menu
|
|
- insert, remove bookmarks
|
|
-
|
|
|
|
//-->
|
|
<!--
|
|
ILE:
|
|
- impl ILE on outliner.xml
|
|
//-->
|
|
<!--
|
|
Command handling:
|
|
- impl |nsIController|
|
|
- actual controller implemented by client which intercepts commands and provides
|
|
special handling for things like open in new browser etc.
|
|
- client can alternatively use the built in controller for default functionality.
|
|
- decisions:
|
|
Implementation pattern:
|
|
client:
|
|
(A) bookmarksUIElement.prototype.doCommand = function () { .. }
|
|
OR
|
|
(B) var ctrlr = { doCommand: function () { bookmarksUIElement.doCommand(); }
|
|
Tend to prefer (B) as it supports delegation
|
|
//--> |