chanial%noos.fr da5050dd4a bookmarks rewrite landing
git-svn-id: svn://10.0.0.236/trunk@129478 18797224-902f-48f8-a5cc-f745e15eee43
2002-09-13 03:12:27 +00:00

925 lines
40 KiB
XML

<?xml version="1.0"?>
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
<!--
The contents of this file are subject to the Netscape 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/NPL/
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) 1998 Netscape Communications Corporation. All
Rights Reserved.
Contributor(s):
Ben Goodger <ben@netscape.com> (Original Author)
Blake Ross <blakeross@telocity.com>
Pierre Chanial <chanial@noos.fr>
-->
<!DOCTYPE window [
<!ENTITY % bookmarksDTD SYSTEM "chrome://browser/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#"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="bookmarks-tree">
<implementation>
<constructor><![CDATA[
// This function only reads in the bookmarks from disk if they have not already been read.
BMSVC.ReadBookmarks();
// We implement nsIController
this.tree.controllers.appendController(this.controller);
var olb = document.getAnonymousElementByAttribute(this, "anonid", "bookmarks-tree");
olb = olb.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
olb.addObserver(this.builderObserver);
// Load column settings from persisted attribute
var colinfostr = this.getAttribute("colinfo");
var colinfo = colinfostr.split(" ");
for (var i = 0; i < colinfo.length; ++i) {
if (colinfo[i] == "") continue;
var querymarker = colinfo[i].indexOf("?");
var anonid = colinfo[i].substring(4, querymarker);
var col = document.getAnonymousElementByAttribute(this, "id", anonid);
if (!anonid || !col) break;
var attrstring = colinfo[i].substr(querymarker + 1);
var attrpairs = attrstring.split("&");
for (var j = 0; j < attrpairs.length; ++j) {
var pair = attrpairs[j].split("=");
col.setAttribute(pair[0], pair[1]);
}
}
// Load sort data from preferences
this.refreshSort();
// Observe for changes in sort from other concurrent UI
const kPrefSvcContractID = "@mozilla.org/preferences;1";
const kPrefSvcIID = Components.interfaces.nsIPrefService;
var prefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
var prefs = prefSvc.getBranch(null);
const kPrefBranchInternalIID = Components.interfaces.nsIPrefBranchInternal;
var bookmarksPrefsInternal = prefs.QueryInterface(kPrefBranchInternalIID);
bookmarksPrefsInternal.addObserver(this.sortChangedObserver.domain,
this.sortChangedObserver, false);
]]></constructor>
<destructor><![CDATA[
this.treeBuilder.removeObserver(this.builderObserver);
this.tree.controllers.removeController(this.controller);
// Save column settings and sort info to persisted attribute
var persistString = "";
var sortResource = NC_NS + "Name";
var sortDirection = "none";
var treecols = document.getAnonymousElementByAttribute(this, "anonid", "treecols");
var child = treecols.firstChild;
while (child) {
if (child.localName != "splitter") {
var formatString = " col:%1%?width=%2%&hidden=%3%&ordinal=%6%";
formatString = formatString.replace(/%1%/, child.getAttribute("id"));
formatString = formatString.replace(/%2%/, child.getAttribute("width"));
formatString = formatString.replace(/%3%/, child.getAttribute("hidden"));
// While we're walking the columns, if we discover the column that represents the
// field sorted by, save the resource associated with that column so that we
// can save that in prefs (see below)
if (child.getAttribute("sortActive") == "true") {
sortResource = child.getAttribute("sort");
sortDirection = child.getAttribute("sortDirection");
}
formatString = formatString.replace(/%6%/, child.getAttribute("ordinal"));
persistString += formatString;
}
child = child.nextSibling;
}
this.setAttribute("colinfo", persistString);
document.persist(this.id, "colinfo");
// Unhook the sort change observer for this tree
const kPrefSvcContractID = "@mozilla.org/preferences;1";
const kPrefSvcIID = Components.interfaces.nsIPrefService;
var prefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
var prefs = prefSvc.getBranch(null);
const kPrefBranchInternalIID = Components.interfaces.nsIPrefBranchInternal;
var bookmarksPrefsInternal = prefs.QueryInterface(kPrefBranchInternalIID);
bookmarksPrefsInternal.removeObserver(this.sortChangedObserver.domain,
this.sortChangedObserver);
]]></destructor>
<property name="db">
<getter><![CDATA[
return this.tree.database;
]]></getter>
</property>
<field name="sortChangedObserver">
<![CDATA[
({
outer: this,
domain: "browser.bookmarks.sort",
observe: function BMOL_sortChangedObserver(aSubject, aTopic, aPrefName)
{
if (aTopic != "nsPref:changed") return;
if (aPrefName.substr(0, this.domain.length) != this.domain) return;
this.outer.refreshSort();
}
})
]]>
</field>
<field name="sorted">false</field>
<method name="refreshSort">
<body>
<![CDATA[
const kPrefSvcContractID = "@mozilla.org/preferences;1";
const kPrefSvcIID = Components.interfaces.nsIPrefService;
var prefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
var bookmarksSortPrefs = prefSvc.getBranch("browser.bookmarks.sort.");
// This ensures that we don't sort twice in the tree that is clicked on
// as a result of 1) the click and 2) the pref listener.
if (!this.sorted) {
try {
var sortResource = bookmarksSortPrefs.getCharPref("resource");
var sortDirection = bookmarksSortPrefs.getCharPref("direction");
// Walk the columns, when we find a column with a sort resource that matches the supplied
// data, stop and make sure it's sort active.
var treecols = document.getAnonymousElementByAttribute(this, "anonid", "treecols");
var child = treecols.firstChild;
while (child) {
if (child.localName != "splitter") {
if (child.getAttribute("sort") == sortResource) {
child.setAttribute("sortActive", "true");
child.setAttribute("sortDirection", sortDirection);
this.treeBuilder.sort(child, false);
break;
}
}
child = child.nextSibling;
}
}
catch (e) {
}
}
this.sorted = false;
]]>
</body>
</method>
<property name="columns">
<getter>
<![CDATA[
var cols = [];
var treecols = document.getAnonymousElementByAttribute(this, "anonid", "treecols");
var child = treecols.firstChild;
while (child) {
if (child.localName != "splitter") {
var obj = {
label: child.getAttribute("label"),
accesskey: child.getAttribute("accesskey"),
resource: child.getAttribute("sort"),
sortActive: child.getAttribute("sortActive") == "true",
hidden: child.getAttribute("hidden")
}
cols.push(obj);
}
child = child.nextSibling;
}
return cols;
]]>
</getter>
</property>
<method name="toggleColumnVisibility">
<parameter name="aColumnResource"/>
<body>
<![CDATA[
var elt = document.getAnonymousElementByAttribute(this, "sort", aColumnResource);
if (elt)
elt.setAttribute("hidden", elt.getAttribute("hidden") != "true");
]]>
</body>
</method>
<property name="treeBoxObject">
<getter><![CDATA[
return this.tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
]]></getter>
</property>
<property name="treeBuilder">
<getter><![CDATA[
return this.tree.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
]]></getter>
</property>
<property name="tree">
<getter><![CDATA[
return document.getAnonymousElementByAttribute(this, "anonid", "bookmarks-tree");
]]></getter>
</property>
<property name="currentIndex">
<getter><![CDATA[
return this.treeBoxObject.selection.currentIndex;
]]></getter>
</property>
<property name="currentRes">
<getter><![CDATA[
return this.treeBuilder.getResourceAtIndex(this.currentIndex);
]]></getter>
</property>
<property name="parentRes">
<getter><![CDATA[
const currIndex = this.currentIndex;
if (currIndex == -1)
return RDF.GetResource("NC:BookmarksRoot");
var parentIndex = this.treeBoxObject.view.getParentIndex(currIndex);
if (parentIndex != -1)
return this.treeBuilder.getResourceAtIndex(parentIndex)
return RDF.GetResource("NC:BookmarksRoot"); // assume its parent is the root
]]></getter>
</property>
<property name="type">
<getter><![CDATA[
if (!this._type) {
var type = this.getAttribute("type");
if (!type)
type = "multi-column";
this._type = type;
}
return this._type;
]]></getter>
</property>
<method name="getRowResource">
<parameter name="aRow"/>
<body><![CDATA[
if (aRow != -1)
return this.treeBuilder.getResourceAtIndex(aRow);
else
return this.getRootResource();
]]></body>
</method>
<method name="getParentResource">
<parameter name="aRow"/>
<body><![CDATA[
if (aRow != -1) {
var parentIndex = this.treeBoxObject.view.getParentIndex(aRow);
return this.getRowResource(parentIndex);
}
return this.getRootResource(); // assume its parent is the root
]]></body>
</method>
<method name="getRootResource">
<body><![CDATA[
var tree = document.getAnonymousElementByAttribute(this, "anonid", "bookmarks-tree");
var rootURI = tree.ref;
if (rootURI == "NC:BookmarksTopRoot")
rootURI = "NC:BookmarksRoot";
return RDF.GetResource(rootURI);
]]></body>
</method>
<method name="getIndexOfResourceInContainer">
<parameter name="aItem"/>
<parameter name="aParent"/>
<body><![CDATA[
if (!aParent)
return -1;
var index = this.treeBuilder.getIndexOfResource(aParent)
if (index == -1)
return -1;
if (!this.treeBoxObject.view.isContainerOpen(index))
return -1;
while (++index < this.treeBuilder.rowCount) {
if (this.treeBuilder.getResourceAtIndex(index) == aItem &&
this.getParentResource(index) == aParent)
return index;
}
return -1;
]]></body>
</method>
<field name="_selection">null</field>
<field name="_target"> null</field>
<method name="getTreeSelection">
<body><![CDATA[
var selection = {};
selection.item = [];
selection.parent = [];
selection.isExpanded = [];
selection.treeIndex = [];
var rangeCount = this.treeBoxObject.selection.getRangeCount();
for (var k = 0; k < rangeCount; ++k) {
var rangeMin = {};
var rangeMax = {};
this.treeBoxObject.selection.getRangeAt(k, rangeMin, rangeMax);
for (var i = rangeMin.value; i <= rangeMax.value; ++i) {
var selectedItem = this.getRowResource(i);
var selectedParent = this.getParentResource(i);
var isExpanded = this.treeBoxObject.view.isContainerOpen(i)
selection.item .push(selectedItem);
selection.parent.push(selectedParent);
selection.isExpanded.push(isExpanded);
}
}
if (selection.item.length == 0) {
selection = { item : [RDF.GetResource("NC:BookmarksRoot")],
parent : [null],
isExpanded: [true]
}
}
selection.length = selection.item.length;
BookmarksUtils.checkSelection(selection);
return selection;
]]></body>
</method>
<field name="_itemToBeToggled"> null</field>
<field name="_parentToBeToggled">null</field>
<method name="preUpdateTreeSelection">
<parameter name="aTxn"/>
<body><![CDATA[
aTxn = aTxn.wrappedJSObject;
var type = aTxn.type;
if (type != "remove" && type != "insert")
return;
for (var i=0; i<aTxn.item.length; ++i) {
this._itemToBeToggled .push(aTxn.item [i]);
this._parentToBeToggled.push(aTxn.parent[i]);
}
]]></body>
</method>
<method name="updateTreeSelection">
<body><![CDATA[
this.treeBoxObject.selection.clearSelection();
for (var i=0; i<this._itemToBeToggled.length; ++i) {
// getIndexOfResource does not handle duplicate resource!!!
// it only picks up the first occurence in the tree -->
index = this.getIndexOfResourceInContainer(this._itemToBeToggled[i], this._parentToBeToggled[i]);
if (index != -1 && !this.treeBoxObject.selection.isSelected(index))
this.treeBoxObject.selection.toggleSelect(index);
}
]]></body>
</method>
<method name="createTreeContextMenu">
<parameter name="aEvent"/>
<body><![CDATA[
var selection = this._selection;
var target = this._target;
BookmarksCommand.createContextMenu(aEvent, selection);
this.onCommandUpdate();
]]></body>
</method>
<method name="openItem">
<parameter name="aEvent"/>
<parameter name="aClickCount"/>
<body><![CDATA[
if (aEvent.button == 2 || aEvent.originalTarget.localName != "treechildren")
return;
if (aClickCount == 1 && this.clickCount == 2 && aEvent.button != 1)
return;
var row = {};
var col = {};
var obj = {};
this.treeBoxObject.getCellAt(aEvent.clientX, aEvent.clientY, row, col, obj);
row = row.value;
if (row == -1 || obj.value == "twisty")
return;
var browserTarget = BookmarksUtils.getBrowserTargetFromEvent(aEvent);
if (browserTarget != "current" && this.clickCount == aClickCount) {
if (!this.treeBoxObject.selection.isSelected(row)) {
this.treeBoxObject.selection.select(row)
}
}
var selection = this.getTreeSelection();
this._selection = selection;
var isFolderGroup = selection.type[0] == "FolderGroup";
if (!isFolderGroup && selection.isContainer[0]) {
if (this.clickCount == 1) {
if (row.value >= 0) {
this.treeBoxObject.view.toggleOpenState(row.value);
}
}
if (selection.protocol[0] == "file")
BookmarksCommand.openBookmark(selection, browserTarget, this.db);
return;
}
if (aEvent.altKey) {
BookmarksCommand.showProperties(selection);
return
}
BookmarksCommand.openBookmark(selection, browserTarget, this.db);
]]></body>
</method>
<!-- observer -->
<field name="DNDObserver" readonly="true"><![CDATA[(
{
mOuter: this,
onDragStart: function (aEvent, aXferData, aDragAction)
{
if (this.mOuter.tree.getAttribute("sortActive") == "true")
throw Components.results.NS_OK;
var selection = this.mOuter._selection;
aXferData.data = BookmarksUtils.getXferDataFromSelection(selection);
const kDSIID = Components.interfaces.nsIDragService;
if (aEvent.ctrlKey || !selection.containsMutable)
aDragAction.action = kDSIID.DRAGDROP_ACTION_COPY;
}
}
)]]></field>
<!-- nsIController -->
<field name="controller" readonly="true"><![CDATA[
({
mOuter: this,
supportsCommand: BookmarksController.supportsCommand,
isCommandEnabled: function (aCommand)
{
// warning: this is not the called function in BookmarksController.onCommandUpdate
var selection = this.mOuter._selection;
var target = this.mOuter._target;
return BookmarksController.isCommandEnabled(aCommand, selection, target)
},
doCommand: function (aCommand)
{
var selection = this.mOuter._selection;
var target = this.mOuter._target;
this.mOuter.treeBoxObject.selection.selectEventsSuppressed = true;
switch (aCommand) {
case "cmd_bm_selectAll":
this.mOuter.treeBoxObject.selection.selectAll();
break;
case "cmd_bm_expandfolder":
this.mOuter.treeBoxObject.view.toggleOpenState(this.mOuter.currentIndex);
break;
default:
// Notify the datasource that we're about to begin a batch operation
var observer = this.mOuter.tree.builder.QueryInterface(Components.interfaces.nsIRDFObserver);
observer.beginUpdateBatch(this.db);
this.mOuter._itemToBeToggled = [];
this.mOuter._parentToBeToggled = [];
BookmarksController.doCommand(aCommand, selection, target);
observer.endUpdateBatch(this.db);
this.mOuter.tree.builder.rebuild();
this.mOuter.updateTreeSelection();
}
this.mOuter.treeBoxObject.selection.selectEventsSuppressed = false;
}
})
]]></field>
<method name="onCommandUpdate">
<body><![CDATA[
var selection = this._selection;
var target = this._target;
BookmarksController.onCommandUpdate(selection, target);
]]></body>
</method>
<method name="selectionChanged">
<parameter name="aEvent"/>
<body><![CDATA[
]]></body>
</method>
<!-- nsIXULTreeBuilderObserver -->
<field name="builderObserver"><![CDATA[
({
mOuter: this,
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;
var date = Date.now();
var selection = BookmarksUtils.getSelectionFromXferData(dragSession);
var rItem = this.mOuter.getRowResource(row);
var rParent = this.mOuter.getParentResource(row);
var target;
if (orientation == BookmarksUtils.DROP_AFTER &&
this.mOuter.treeBoxObject.view.isContainer(row) &&
this.mOuter.treeBoxObject.view.isContainerOpen(row) &&
!this.mOuter.treeBoxObject.view.isContainerEmpty(row))
target = { parent: rItem, index: 1 };
else {
target = BookmarksUtils.getSelectionFromResource(rItem, rParent);
target = BookmarksUtils.getTargetFromSelection(target, orientation);
}
var firstVisibleRow = this.mOuter.treeBoxObject.getFirstVisibleRow()
this.mOuter.treeBoxObject.selection.selectEventsSuppressed = true;
// Notify the datasource that we're about to begin a batch operation
var observer = this.mOuter.tree.builder.QueryInterface(Components.interfaces.nsIRDFObserver);
observer.beginUpdateBatch(this.db);
this.mOuter._itemToBeToggled = [];
this.mOuter._parentToBeToggled = [];
const kDSIID = Components.interfaces.nsIDragService;
const kCopyAction = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK;
if (dragSession.dragAction & kCopyAction)
BookmarksUtils.insertSelection("drag", selection, target, true);
else
BookmarksUtils.moveSelection ("drag", selection, target);
observer.endUpdateBatch(this.db);
this.mOuter.treeBuilder.rebuild();
// temporary hack: for an unknown reason, rebuilding cause a scroll to the bottom
// if the first visible row is not 0
this.mOuter.treeBoxObject.scrollToRow(firstVisibleRow);
this.mOuter.updateTreeSelection();
// use of a timer to speedup
var This = this.mOuter;
setTimeout( function (){This.treeBoxObject.selection.selectEventsSuppressed = false}, 100)
dump("6:"+(Date.now()-date)+"\n")
},
onToggleOpenState: function (aRow)
{
// update the open attribute of the selection
var resource = this.mOuter.getRowResource(aRow);
var selection = this.mOuter._selection;
for (var i=0; i<selection.length; ++i) {
if (selection.item[i] == resource) {
selection.isExpanded[i] = !selection.isExpanded[i];
break;
}
}
},
onCycleHeader: function (aColumnID, aHeaderElement)
{
const kPrefSvcContractID = "@mozilla.org/preferences;1";
const kPrefSvcIID = Components.interfaces.nsIPrefService;
var prefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
var bookmarksSortPrefs = prefSvc.getBranch("browser.bookmarks.sort.");
// Sorted! http://www.sorted.org.nz/
this.mOuter.sorted = true;
bookmarksSortPrefs.setCharPref("resource", aHeaderElement.getAttribute("sort"));
bookmarksSortPrefs.setCharPref("direction", aHeaderElement.getAttribute("sortDirection"));
},
onSelectionChanged: function ()
{
dump("ONSELECTION CHANGED\n")
var selection = this.mOuter.getTreeSelection();
this.mOuter._selection = selection;
this.mOuter._target = BookmarksUtils.getTargetFromSelection(selection);
this.mOuter.onCommandUpdate();
const kStatusBar = document.getAnonymousElementByAttribute(this.mOuter, "anonid", "statusbar-text");
var displayValue;
if (kStatusBar && selection.length == 1) {
var protocol = selection.protocol[0];
if (selection.isContainer[0] && protocol != "find" && protocol != "file") {
RDFC.Init(this.mOuter.db, selection.item[0]);
var count = RDFC.GetCount();
displayValue = BookmarksUtils.getLocaleString("status_foldercount", String(count));
}
else if (selection.type[0] == "Bookmark")
displayValue = BookmarksUtils.getProperty(selection.item[0], NC_NS+"URL", this.mOuter.db)
else
displayValue = "";
kStatusBar.label = displayValue;
}
},
onCycleCell : function (aItemIndex, aColumnID) {},
isEditable : function (aItemIndex, aColumnID) {},
onSetCellText : function (aItemIndex, aColumnID, aValue) {},
onPerformAction : function (aAction) {},
onPerformActionOnRow : function (aAction, aItemIndex) {},
onPerformActionOnCell: function (aAction, aItemIndex, aColumnID) {}
})
]]></field>
<!-- nsITransactionManager listener -->
<field name="bookmarkTreeTransactionListener"><![CDATA[
({
mOuter: this,
didDo: function (aTxmgr, aTxn) {
this.mOuter.preUpdateTreeSelection(aTxn);
},
didUndo: function (aTxmgr, aTxn) {
this.mOuter.preUpdateTreeSelection(aTxn);
},
didRedo: function (aTxmgr, aTxn) {
this.mOuter.preUpdateTreeSelection(aTxn);
},
didMerge : function (aTxmgr, aTransaction) {},
didBeginBatch : function (aTxmgr, aTransaction) {},
didEndBatch : function (aTxmgr, aTransaction) {},
willDo : function (aTxmgr, aTransaction) {},
willUndo : function (aTxmgr, aTransaction) {},
willRedo : function (aTxmgr, aTransaction) {},
willMerge : function (aTxmgr, aTransaction) {},
willBeginBatch : function (aTxmgr, aTransaction) {},
willEndBatch : function (aTxmgr, aTransaction) {}
})
]]></field>
</implementation>
</binding>
<!-- Full Bookmarks Tree, multi-columned -->
<!-- Localize column labels! -->
<binding id="bookmarks-tree-full" extends="chrome://browser/content/bookmarks/bookmarksTree.xml#bookmarks-tree">
<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 -->
<!-- context menu -->
<menupopup onpopupshowing="this.parentNode.createTreeContextMenu(event);"
onpopuphidden="if (content) content.focus()"/>
<vbox flex="1">
<tree anonid="bookmarks-tree" flex="1" class="plain" enableColumnDrag="true"
datasources="rdf:bookmarks rdf:internetsearch rdf:files rdf:localsearch" ref="NC:BookmarksRoot" flags="dont-build-content"
onkeypress="if (event.keyCode == 13) this.parentNode.parentNode.openItem(event);"
onclick="this.parentNode.parentNode.openItem(event, 1);"
ondblclick="this.parentNode.parentNode.openItem(event, 2);"
ondraggesture="if (event.originalTarget.localName == 'treechildren') nsDragAndDrop.startDrag(event, this.parentNode.parentNode.DNDObserver);"
onselect="this.treeBoxObject.view.selectionChanged();">
<template xmlns:nc="http://home.netscape.com/NC-rdf#">
<rule rdf:type="http://home.netscape.com/NC-rdf#BookmarkSeparator">
<treechildren>
<treeitem uri="rdf:*">
<treerow properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type separator"/>
</treeitem>
</treechildren>
</rule>
<rule nc:FolderGroup="true">
<treechildren>
<treeitem uri="rdf:*">
<treerow 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">
<treecell properties="group" label="rdf:http://home.netscape.com/NC-rdf#Name" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#URL" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#ShortcutURL" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#Description" />
<treecell label="rdf:http://home.netscape.com/WEB-rdf#LastVisitDate"/>
<treecell label="rdf:http://home.netscape.com/NC-rdf#BookmarkAddDate" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#LastModifiedDate" />
</treerow>
</treeitem>
</treechildren>
</rule>
<rule>
<treechildren>
<treeitem uri="rdf:*">
<treerow 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">
<treecell label="rdf:http://home.netscape.com/NC-rdf#Name" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#URL" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#ShortcutURL" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#Description" />
<treecell label="rdf:http://home.netscape.com/WEB-rdf#LastVisitDate"/>
<treecell label="rdf:http://home.netscape.com/NC-rdf#BookmarkAddDate" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#LastModifiedDate" />
</treerow>
</treeitem>
</treechildren>
</rule>
</template>
<treecols anonid="treecols">
<treecol id="Name" label="&treecol.name.label;" flex="1" primary="true"
class="sortDirectionIndicator"
persist="width hidden sortActive sortDirection ordinal"
sort="rdf:http://home.netscape.com/NC-rdf#Name"
sortActive="true" sortDirection="none"/>
<splitter class="tree-splitter" />
<treecol id="URL" label="&treecol.url.label;"
flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#URL"
persist="width hidden sortActive sortDirection ordinal" />
<splitter class="tree-splitter" />
<treecol id="ShortcutURL" label="&treecol.shortcut.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
persist="hidden width sortActive sortDirection ordinal"
sort="rdf:http://home.netscape.com/NC-rdf#ShortcutURL"/>
<splitter class="tree-splitter"/>
<treecol id="Description" label="&treecol.description.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
persist="hidden width sortActive sortDirection ordinal"
sort="rdf:http://home.netscape.com/NC-rdf#Description"/>
<splitter class="tree-splitter"/>
<treecol id="AddDate" label="&treecol.addedon.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#BookmarkAddDate"
persist="width hidden sortActive sortDirection ordinal" />
<splitter class="tree-splitter" />
<treecol id="LastModDate" label="&treecol.lastmod.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#LastModifiedDate"
persist="width hidden sortActive sortDirection ordinal" />
<splitter class="tree-splitter" />
<treecol id="LastVisitDate" label="&treecol.lastvisit.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#LastVisitDate"
persist="width hidden sortActive sortDirection ordinal" />
</treecols>
</tree>
<statusbar class="chromeclass-status" xbl:inherits="hidden=hidestatusbar" hidden="false">
<statusbarpanel anonid="statusbar-text" flex="1"/>
</statusbar>
</vbox>
</xbl:content>
<implementation>
<constructor>
// Adding the transaction listener
gBMtxmgr = BookmarksUtils.getTransactionManager();
gBMtxmgr.AddListener(this.bookmarkTreeTransactionListener)
</constructor>
<destructor>
gBMtxmgr.RemoveListener(this.bookmarkTreeTransactionListener)
</destructor>
<field name="clickCount">2</field>
</implementation>
</binding>
<!-- Single column tree -->
<binding id="bookmarks-tree-name" extends="chrome://browser/content/bookmarks/bookmarksTree.xml#bookmarks-tree">
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl" contextmenu="_child">
<!-- context menu -->
<menupopup onpopupshowing="this.parentNode.createTreeContextMenu(event);"
onpopuphidden ="if (content) content.focus()"/>
<tree anonid="bookmarks-tree" flex="1" hidecolumnpicker="true" class="plain"
datasources="rdf:bookmarks rdf:internetsearch rdf:files rdf:localsearch" ref="NC:BookmarksRoot" flags="dont-build-content"
onkeypress="if (event.keyCode == 13) this.parentNode.openItem(event); event.preventBubble();"
ondraggesture="if (event.originalTarget.localName == 'treechildren') nsDragAndDrop.startDrag(event, this.parentNode.DNDObserver);"
onclick="this.parentNode.openItem(event);"
onselect="this.parentNode.treeBoxObject.view.selectionChanged();">
<template xmlns:nc="http://home.netscape.com/NC-rdf#">
<rule rdf:type="http://home.netscape.com/NC-rdf#BookmarkSeparator">
<treechildren>
<treeitem uri="rdf:*">
<treerow properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type separator" />
</treeitem>
</treechildren>
</rule>
<rule nc:FolderGroup="true">
<treechildren>
<treeitem uri="rdf:*">
<treerow 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">
<treecell properties="group hidetwisty" label="rdf:http://home.netscape.com/NC-rdf#Name" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#URL" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#ShortcutURL" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#Description" />
<treecell label="rdf:http://home.netscape.com/WEB-rdf#LastVisitDate"/>
<treecell label="rdf:http://home.netscape.com/NC-rdf#BookmarkAddDate" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#LastModifiedDate" />
</treerow>
</treeitem>
</treechildren>
</rule>
<rule>
<treechildren>
<treeitem uri="rdf:*">
<treerow 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">
<treecell label="rdf:http://home.netscape.com/NC-rdf#Name" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#URL" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#ShortcutURL" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#Description" />
<treecell label="rdf:http://home.netscape.com/WEB-rdf#LastVisitDate"/>
<treecell label="rdf:http://home.netscape.com/NC-rdf#BookmarkAddDate" />
<treecell label="rdf:http://home.netscape.com/NC-rdf#LastModifiedDate" />
</treerow>
</treeitem>
</treechildren>
</rule>
</template>
<treecols anonid="treecols">
<treecol id="Name" label="&treecol.name.label;" flex="1" primary="true"
class="sortDirectionIndicator"
persist="width hidden sortActive sortDirection ordinal"
sort="rdf:http://home.netscape.com/NC-rdf#Name"
sortActive="true" sortDirection="none"/>
<splitter class="tree-splitter" />
<treecol id="URL" label="&treecol.url.label;"
flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#URL"
hidden="true"/>
<splitter class="tree-splitter" />
<treecol id="ShortcutURL" label="&treecol.shortcut.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#ShortcutURL"/>
<splitter class="tree-splitter" />
<treecol id="Description" label="&treecol.description.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#Description"/>
<splitter class="tree-splitter" />
<treecol id="AddDate" label="&treecol.addedon.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#BookmarkAddDate" />
<splitter class="tree-splitter" />
<treecol id="LastModDate" label="&treecol.lastmod.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#LastModifiedDate" />
<splitter class="tree-splitter" />
<treecol id="LastVisitDate" label="&treecol.lastvisit.label;"
hidden="true" flex="1" class="sortDirectionIndicator"
sort="rdf:http://home.netscape.com/NC-rdf#LastVisitDate" />
</treecols>
</tree>
</xbl:content>
<implementation>
<constructor>
gBMtxmgr = BookmarksUtils.getTransactionManager();
</constructor>
<field name="clickCount">1</field>
</implementation>
</binding>
<!-- Tree with folders only -->
<binding id="bookmarks-tree-folders" extends="chrome://browser/content/bookmarks/bookmarksTree.xml#bookmarks-tree">
<xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:xbl="http://www.mozilla.org/xbl">
<tree anonid="bookmarks-tree" flex="1" hidecolumnpicker="true"
datasources="rdf:bookmarks rdf:internetsearch rdf:files rdf:localsearch" ref="NC:BookmarksRoot" flags="dont-build-content"
onselect="this.parentNode.treeBoxObject.view.selectionChanged();">
<template>
<rule iscontainer="true">
<treechildren>
<treeitem uri="rdf:*">
<treerow 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">
<treecell label="rdf:http://home.netscape.com/NC-rdf#Name" />
</treerow>
</treeitem>
</treechildren>
</rule>
</template>
<treecols>
<treecol id="Name" label="&treecol.name.label;" flex="1" primary="true"
class="sortDirectionIndicator" persist="width hidden sortActive sortDirection"
sort="rdf:http://home.netscape.com/NC-rdf#Name"
sortActive="true" sortDirection="none"/>
</treecols>
</tree>
</xbl:content>
<implementation>
<constructor>
gBMtxmgr = BookmarksUtils.getTransactionManager();
</constructor>
<field name="clickCount">1</field>
</implementation>
</binding>
</bindings>