941 строка
37 KiB
XML
941 строка
37 KiB
XML
<?xml version="1.0"?>
|
|
|
|
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
|
|
<!--
|
|
|
|
***** BEGIN LICENSE BLOCK *****
|
|
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
The contents of this file are subject to the Mozilla Public License Version
|
|
1.1 (the "License"); you may not use this file except in compliance with
|
|
the License. You may obtain a copy of the License at
|
|
http://www.mozilla.org/MPL/
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
for the specific language governing rights and limitations under the
|
|
License.
|
|
|
|
The Original Code is mozilla.org code.
|
|
|
|
The Initial Developer of the Original Code is
|
|
Netscape Communications Corporation.
|
|
Portions created by the Initial Developer are Copyright (C) 1998
|
|
the Initial Developer. All Rights Reserved.
|
|
|
|
Contributor(s):
|
|
Ben Goodger <ben@netscape.com> (Original Author)
|
|
Blake Ross <blakeross@telocity.com>
|
|
Pierre Chanial <chanial@noos.fr> (v2.0)
|
|
Dan Cannon <dc2@myrealbox.com>
|
|
|
|
Alternatively, the contents of this file may be used under the terms of
|
|
either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
in which case the provisions of the GPL or the LGPL are applicable instead
|
|
of those above. If you wish to allow use of your version of this file only
|
|
under the terms of either the GPL or the LGPL, and not to allow others to
|
|
use your version of this file under the terms of the MPL, indicate your
|
|
decision by deleting the provisions above and replace them with the notice
|
|
and other provisions required by the GPL or the LGPL. If you do not delete
|
|
the provisions above, a recipient may use your version of this file under
|
|
the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
***** END LICENSE BLOCK ***** -->
|
|
|
|
<!-- bookmarksTree.xml depends on global variables defined in bookmarks.js.
|
|
Before use, these must be initialized by calling initServices() and
|
|
initBMService() -->
|
|
|
|
<!DOCTYPE bindings [
|
|
<!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#"
|
|
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.
|
|
initServices();
|
|
initBMService();
|
|
|
|
BMSVC.readBookmarks();
|
|
|
|
// Add controllers and listeners.
|
|
this.tree.controllers.appendController(this.controller);
|
|
|
|
// XXXvarga this observer should go away once bug 120071 is fixed.
|
|
this.treeBuilder.addObserver(this.builderObserver);
|
|
|
|
this.tree.builder.addListener(this.builderListener);
|
|
|
|
BMSVC.transactionManager.AddListener(this.transactionListener);
|
|
|
|
// 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]);
|
|
}
|
|
}
|
|
]]></constructor>
|
|
<destructor><![CDATA[
|
|
// Remove controllers and listeners.
|
|
BMSVC.transactionManager.RemoveListener(this.transactionListener);
|
|
|
|
this.tree.builder.removeListener(this.builderListener);
|
|
|
|
this.treeBuilder.removeObserver(this.builderObserver);
|
|
|
|
this.tree.controllers.removeController(this.controller);
|
|
|
|
// Save column settings and sort info to persisted attribute
|
|
var persistString = "";
|
|
|
|
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"));
|
|
formatString = formatString.replace(/%6%/, child.getAttribute("ordinal"));
|
|
persistString += formatString;
|
|
}
|
|
child = child.nextSibling;
|
|
}
|
|
this.setAttribute("colinfo", persistString);
|
|
|
|
document.persist(this.id, "colinfo");
|
|
]]></destructor>
|
|
|
|
<property name="db">
|
|
<getter><![CDATA[
|
|
return this.tree.database;
|
|
]]></getter>
|
|
</property>
|
|
|
|
<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 = {
|
|
id: child.getAttribute("id"),
|
|
label: child.getAttribute("label"),
|
|
accesskey: child.getAttribute("accesskey"),
|
|
hidden: child.getAttribute("hidden")
|
|
}
|
|
cols.push(obj);
|
|
}
|
|
child = child.nextSibling;
|
|
}
|
|
|
|
return cols;
|
|
]]>
|
|
</getter>
|
|
</property>
|
|
|
|
<method name="toggleColumnVisibility">
|
|
<parameter name="aColumnId"/>
|
|
<body>
|
|
<![CDATA[
|
|
var elt = document.getAnonymousElementByAttribute(this, "id", aColumnId);
|
|
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.tree.view.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;
|
|
return RDF.GetResource(rootURI);
|
|
]]></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 = [];
|
|
var rangeCount = this.treeBoxObject.view.selection.getRangeCount();
|
|
// workaround for bug 171547: if rowCount==0, rangeCount==1
|
|
if (this.treeBuilder.rowCount > 0)
|
|
for (var k = 0; k < rangeCount; ++k) {
|
|
var rangeMin = {};
|
|
var rangeMax = {};
|
|
this.treeBoxObject.view.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);
|
|
}
|
|
}
|
|
selection.length = selection.item.length;
|
|
BookmarksUtils.checkSelection(selection);
|
|
return selection;
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="getTreeTarget">
|
|
<parameter name="aItem"/>
|
|
<parameter name="aParent"/>
|
|
<parameter name="aOrientation"/>
|
|
<body><![CDATA[
|
|
|
|
if (!aParent || aParent.Value == "NC:BookmarksTopRoot")
|
|
return BookmarksUtils.getTargetFromFolder(RDF.GetResource("NC:BookmarksRoot"))
|
|
|
|
if (aOrientation == BookmarksUtils.DROP_ON)
|
|
return BookmarksUtils.getTargetFromFolder(aItem);
|
|
|
|
RDFC.Init(this.db, aParent);
|
|
var index = RDFC.IndexOf(aItem);
|
|
if (aOrientation == BookmarksUtils.DROP_AFTER)
|
|
++index;
|
|
return { parent: aParent, index: index };
|
|
]]></body>
|
|
</method>
|
|
|
|
<!--
|
|
This function saves the current selection state before the tree is
|
|
rebuilt.
|
|
-->
|
|
<field name="_savedSelection">[]</field>
|
|
<method name="saveSelection">
|
|
<body><![CDATA[
|
|
this._savedSelection = [];
|
|
var selection = this.treeBoxObject.view.selection;
|
|
if (selection) {
|
|
var rangeCount = selection.getRangeCount();
|
|
var min = {}; var max = {};
|
|
for (var i = 0; i < rangeCount; ++i) {
|
|
selection.getRangeAt(i, min, max);
|
|
for (var j = min.value; j <= max.value; ++j) {
|
|
var resource = this.treeBuilder.getResourceAtIndex(j);
|
|
this._savedSelection.push(resource);
|
|
}
|
|
}
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<!--
|
|
This function restores the selection appropriately after the tree has
|
|
been rebuilt.
|
|
-->
|
|
<method name="restoreSelection">
|
|
<body><![CDATA[
|
|
var selection = this.treeBoxObject.view.selection;
|
|
if (selection) {
|
|
selection.selectEventsSuppressed = true;
|
|
|
|
selection.clearSelection();
|
|
for (var i = 0; i < this._savedSelection.length; ++i) {
|
|
var index = this.treeBuilder.getIndexOfResource(this._savedSelection[i]);
|
|
if (index >= 0) {
|
|
selection.toggleSelect(index);
|
|
}
|
|
}
|
|
|
|
selection.selectEventsSuppressed = false;
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<field name="_itemToBeToggled"> []</field>
|
|
<field name="_parentToBeToggled">[]</field>
|
|
<method name="preUpdateTreeSelection">
|
|
<parameter name="aTxn"/>
|
|
<body><![CDATA[
|
|
aTxn = aTxn.wrappedJSObject;
|
|
var type = aTxn.type;
|
|
// Skip transactions that aggregates nested "insert" or "remove" transactions.
|
|
if (type != "insert" && type != "remove")
|
|
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.view.selection.selectEventsSuppressed = true;
|
|
this.treeBoxObject.view.selection.clearSelection();
|
|
for (var i=0; i<this._itemToBeToggled.length; ++i) {
|
|
index = this.treeBuilder.getIndexOfResource(this._itemToBeToggled[i]);
|
|
if (index >=0)
|
|
this.treeBoxObject.view.selection.toggleSelect(index);
|
|
}
|
|
this.treeBoxObject.view.selection.selectEventsSuppressed = false;
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="createTreeContextMenu">
|
|
<parameter name="aEvent"/>
|
|
<body><![CDATA[
|
|
BookmarksCommand.createContextMenu(aEvent, this._selection);
|
|
this.onCommandUpdate();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="openItemClick">
|
|
<parameter name="aEvent"/>
|
|
<parameter name="aClickCount"/>
|
|
<body><![CDATA[
|
|
if (aEvent.button == 2 || aEvent.originalTarget.localName != "treechildren")
|
|
return;
|
|
if (aClickCount != this.clickCount && 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 modifKey = aEvent.shiftKey || aEvent.ctrlKey || aEvent.altKey ||
|
|
aEvent.metaKey || aEvent.button == 1;
|
|
if (this.clickCount == 2 && !modifKey &&
|
|
this.treeBoxObject.view.isContainer(row))
|
|
return;
|
|
|
|
if (this.clickCount == 2 && modifKey) {
|
|
this.treeBoxObject.view.selection.select(row);
|
|
this._selection = this.getTreeSelection();
|
|
}
|
|
var selection = this._selection;
|
|
|
|
if (selection.type[0] != "FolderGroup" && selection.isContainer[0]) {
|
|
if (this.clickCount == 1 && !modifKey) {
|
|
this.treeBoxObject.view.toggleOpenState(row);
|
|
if (selection.protocol[0] != "file")
|
|
return;
|
|
}
|
|
}
|
|
|
|
var target = BookmarksUtils.getBrowserTargetFromEvent(aEvent);
|
|
if (target)
|
|
BookmarksCommand.openBookmark(selection, target, this.db, aEvent);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="openItemKey">
|
|
<parameter name="aEvent"/>
|
|
<body><![CDATA[
|
|
if (this._selection.length != 1)
|
|
return;
|
|
if (!this._selection.isContainer[0]) {
|
|
var target = BookmarksUtils.getBrowserTargetFromEvent(aEvent);
|
|
if (target)
|
|
BookmarksCommand.openBookmark(this._selection, target, this.db, aEvent)
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="searchBookmarks">
|
|
<parameter name="aInput"/>
|
|
<body><![CDATA[
|
|
this.treeBoxObject.view.selection.currentIndex=-1;
|
|
if (!aInput) {
|
|
this.tree.setAttribute("ref", this.originalRef);
|
|
}
|
|
else {
|
|
if (!this.originalRef) {
|
|
this.originalRef = this.tree.getAttribute("ref");
|
|
}
|
|
this.tree.setAttribute("ref",
|
|
"find:datasource=rdf:bookmarks&match=http://home.netscape.com/NC-rdf#Name&method=contains&text=" + encodeURIComponent(aInput));
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<!-- observer -->
|
|
<field name="DNDObserver" readonly="true"><![CDATA[
|
|
({
|
|
mOuter: this,
|
|
onDragStart: function (aEvent, aXferData, aDragAction)
|
|
{
|
|
var selection = this.mOuter._selection;
|
|
aXferData.data = BookmarksUtils.getXferDataFromSelection(selection);
|
|
const kDSIID = Components.interfaces.nsIDragService;
|
|
if (aEvent.ctrlKey)
|
|
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
|
|
return BookmarksController.isCommandEnabled(aCommand,
|
|
this.mOuter._selection,
|
|
this.mOuter._target);
|
|
},
|
|
|
|
doCommand: function (aCommand)
|
|
{
|
|
var selection = this.mOuter._selection;
|
|
var target = this.mOuter._target;
|
|
switch (aCommand) {
|
|
// Commands that insert rows
|
|
case "cmd_bm_newfolder":
|
|
case "cmd_bm_newbookmark":
|
|
case "cmd_bm_newseparator":
|
|
case "cmd_bm_import":
|
|
case "cmd_bm_movebookmark":
|
|
case "cmd_bm_paste":
|
|
// XXXvarga undo/redo can insert or remove rows.
|
|
case "cmd_undo":
|
|
case "cmd_redo":
|
|
// All items inserted will be selected. The implementation of
|
|
// this model is left to |preUpdateTreeSelection|, called when
|
|
// an insert transaction is executed, and |updateTreeSelection|
|
|
// called here.
|
|
BookmarksController.doCommand(aCommand, selection, target);
|
|
this.mOuter.updateTreeSelection();
|
|
break;
|
|
// Commands that remove rows
|
|
case "cmd_bm_cut":
|
|
case "cmd_bm_delete":
|
|
// Since rows have been removed, the row immediately after the
|
|
// first range in the original selection now has the index of
|
|
// the first item in the first range.
|
|
var s = this.mOuter.treeBoxObject.view.selection;
|
|
rangeMin = {};
|
|
rangeMax = {};
|
|
s.getRangeAt(0, rangeMin, rangeMax);
|
|
BookmarksController.doCommand(aCommand, selection, target);
|
|
// Select the next remaining row if there is one,
|
|
// or the previous row, even "Bookmarks for <profile name>"(= 0)
|
|
// if no other row remains.
|
|
s.select((rangeMin.value >= this.mOuter.treeBuilder.rowCount)
|
|
? this.mOuter.treeBuilder.rowCount - 1
|
|
: rangeMin.value);
|
|
break;
|
|
case "cmd_bm_expandfolder":
|
|
this.mOuter.treeBoxObject.view.toggleOpenState(this.mOuter.currentIndex);
|
|
break;
|
|
case "cmd_bm_selectAll":
|
|
this.mOuter.treeBoxObject.view.selection.selectAll();
|
|
break;
|
|
default:
|
|
BookmarksController.doCommand(aCommand, selection, target);
|
|
}
|
|
}
|
|
})
|
|
]]></field>
|
|
|
|
<method name="onCommandUpdate">
|
|
<body><![CDATA[
|
|
BookmarksController.onCommandUpdate(this._selection, this._target);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="selectionChanged">
|
|
<parameter name="aEvent"/>
|
|
<body><![CDATA[
|
|
]]></body>
|
|
</method>
|
|
|
|
<!-- nsIXULTreeBuilderObserver -->
|
|
<field name="builderObserver"><![CDATA[
|
|
({
|
|
mOuter: this,
|
|
canDrop: function(index, orientation)
|
|
{
|
|
var dragSession = DS && DS.getCurrentSession();
|
|
if (!dragSession)
|
|
return false;
|
|
var selection = BookmarksUtils.getSelectionFromXferData(dragSession);
|
|
if (selection.containsRF)
|
|
return false;
|
|
if (orientation == BookmarksUtils.DROP_ON)
|
|
return true;
|
|
|
|
if (index != 0)
|
|
return true;
|
|
if (this.mOuter.getRowResource(index).Value != "NC:BookmarksRoot")
|
|
return true;
|
|
return orientation == BookmarksUtils.DROP_BEFORE ? false : this.mOuter.treeBoxObject.view.isContainerOpen(0)
|
|
},
|
|
onDrop: function(row, orientation)
|
|
{
|
|
var dragSession = DS && DS.getCurrentSession();
|
|
if (!dragSession)
|
|
return;
|
|
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 = this.mOuter.getTreeTarget(rItem, rParent, orientation);
|
|
}
|
|
const kDSIID = Components.interfaces.nsIDragService;
|
|
const kCopyAction = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK;
|
|
if (dragSession.dragAction & kCopyAction)
|
|
BookmarksUtils.insertSelection("drag", selection, target);
|
|
else
|
|
BookmarksUtils.moveSelection ("drag", selection, target);
|
|
},
|
|
|
|
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) {},
|
|
|
|
onSelectionChanged: function ()
|
|
{
|
|
var selection = this.mOuter.getTreeSelection();
|
|
this.mOuter._selection = selection;
|
|
var selectionLength = selection.length;
|
|
if (!selectionLength)
|
|
this.mOuter._target = null;
|
|
else {
|
|
// Paste or create items into an expanded folder, otherwise after the selected item.
|
|
var orient = selection.isExpanded[0] ? BookmarksUtils.DROP_ON : BookmarksUtils.DROP_AFTER;
|
|
this.mOuter._target = this.mOuter.getTreeTarget(selection.item[0], selection.parent[0], orient);
|
|
}
|
|
this.mOuter.onCommandUpdate();
|
|
const kStatusBar = document.getAnonymousElementByAttribute(this.mOuter, "anonid", "statusbar-text");
|
|
var displayValue;
|
|
if (kStatusBar && selectionLength == 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) {},
|
|
onPerformAction : function (aAction) {},
|
|
onPerformActionOnRow : function (aAction, aItemIndex) {},
|
|
onPerformActionOnCell: function (aAction, aItemIndex, aColumnID) {}
|
|
|
|
})
|
|
]]></field>
|
|
|
|
<!-- nsIXULBuilderListener -->
|
|
<field name="builderListener"><![CDATA[
|
|
({
|
|
mOuter: this,
|
|
|
|
willRebuild: function(aBuilder) {
|
|
this.mOuter.saveSelection();
|
|
},
|
|
|
|
didRebuild: function(aBuilder) {
|
|
this.mOuter.restoreSelection();
|
|
}
|
|
})
|
|
]]></field>
|
|
|
|
<!-- nsITransactionManager listener -->
|
|
<field name="transactionListener"><![CDATA[
|
|
({
|
|
|
|
mOuter: this,
|
|
|
|
willDo: function (aTxmgr, aTxn) {
|
|
this.mOuter._itemToBeToggled = [];
|
|
this.mOuter._parentToBeToggled = [];
|
|
},
|
|
|
|
didDo: function (aTxmgr, aTxn) {
|
|
this.mOuter.preUpdateTreeSelection(aTxn);
|
|
},
|
|
|
|
willUndo: function (aTxmgr, aTxn) {
|
|
this.mOuter._itemToBeToggled = [];
|
|
this.mOuter._parentToBeToggled = [];
|
|
},
|
|
|
|
didUndo: function (aTxmgr, aTxn) {
|
|
this.mOuter.preUpdateTreeSelection(aTxn);
|
|
},
|
|
|
|
willRedo: function (aTxmgr, aTxn) {
|
|
this.mOuter._itemToBeToggled = [];
|
|
this.mOuter._parentToBeToggled = [];
|
|
},
|
|
|
|
didRedo: function (aTxmgr, aTxn) {
|
|
this.mOuter.preUpdateTreeSelection(aTxn);
|
|
},
|
|
|
|
didMerge : function (aTxmgr, aTxn) {},
|
|
didBeginBatch : function (aTxmgr, aTxn) {},
|
|
didEndBatch : function (aTxmgr, aTxn) {},
|
|
willMerge : function (aTxmgr, aTxn) {},
|
|
willBeginBatch : function (aTxmgr, aTxn) {},
|
|
willEndBatch : function (aTxmgr, aTxn) {}
|
|
})
|
|
]]></field>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- Full Bookmarks Tree, multi-columned -->
|
|
<!-- Localize column labels! -->
|
|
<binding id="bookmarks-tree-full" extends="chrome://communicator/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()"
|
|
onclick="event.stopPropagation();"
|
|
onkeypress="event.stopPropagation();"/>
|
|
<vbox flex="1">
|
|
<tree anonid="bookmarks-tree"
|
|
treelines="true"
|
|
flex="1"
|
|
class="plain"
|
|
enableColumnDrag="true"
|
|
datasources="rdf:bookmarks rdf:internetsearch rdf:localsearch"
|
|
ref="NC:BookmarksTopRoot"
|
|
flags="dont-build-content"
|
|
onkeypress="if (event.keyCode == 13) this.parentNode.parentNode.openItemKey(event);"
|
|
onclick="this.parentNode.parentNode.openItemClick(event, 1);"
|
|
ondblclick="this.parentNode.parentNode.openItemClick(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">
|
|
<treecell properties="separator" label="rdf:http://home.netscape.com/NC-rdf#Name"/>
|
|
</treerow>
|
|
</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/NC-rdf#BookmarkAddDate" />
|
|
<treecell label="rdf:http://home.netscape.com/WEB-rdf#LastModifiedDate" />
|
|
<treecell label="rdf:http://home.netscape.com/WEB-rdf#LastVisitDate"/>
|
|
</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 src="rdf:http://home.netscape.com/NC-rdf#Icon"
|
|
properties="rdf:http://home.netscape.com/WEB-rdf#status"
|
|
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/NC-rdf#BookmarkAddDate" />
|
|
<treecell label="rdf:http://home.netscape.com/WEB-rdf#LastModifiedDate" />
|
|
<treecell label="rdf:http://home.netscape.com/WEB-rdf#LastVisitDate"/>
|
|
</treerow>
|
|
</treeitem>
|
|
</treechildren>
|
|
</rule>
|
|
</template>
|
|
<treecols anonid="treecols">
|
|
<treecol id="Name" flex="1" primary="true"
|
|
label="&treecol.name.label;"
|
|
tooltiptext="&treecol.name.tooltip;"
|
|
sort="rdf:http://home.netscape.com/NC-rdf#Name"
|
|
sortActive="true"
|
|
persist="width hidden ordinal"/>
|
|
<splitter class="tree-splitter" />
|
|
<treecol id="URL" flex="1"
|
|
label="&treecol.url.label;"
|
|
tooltiptext="&treecol.url.tooltip;"
|
|
sort="rdf:http://home.netscape.com/NC-rdf#URL"
|
|
persist="width hidden ordinal"/>
|
|
<splitter class="tree-splitter" />
|
|
<treecol id="ShortcutURL" flex="1" hidden="true"
|
|
label="&treecol.shortcut.label;"
|
|
tooltiptext="&treecol.shortcut.tooltip;"
|
|
sort="rdf:http://home.netscape.com/NC-rdf#ShortcutURL"
|
|
persist="hidden width ordinal"/>
|
|
<splitter class="tree-splitter"/>
|
|
<treecol id="Description" flex="1"
|
|
label="&treecol.description.label;"
|
|
tooltiptext="&treecol.description.tooltip;"
|
|
sort="rdf:http://home.netscape.com/NC-rdf#Description"
|
|
persist="hidden width ordinal"/>
|
|
<splitter class="tree-splitter"/>
|
|
<treecol id="BookmarkAddDate" flex="1" hidden="true"
|
|
label="&treecol.addedon.label;"
|
|
tooltiptext="&treecol.addedon.tooltip;"
|
|
sort="rdf:http://home.netscape.com/NC-rdf#BookmarkAddDate"
|
|
persist="width hidden ordinal"/>
|
|
<splitter class="tree-splitter" />
|
|
<treecol id="LastModifiedDate" flex="1" hidden="true"
|
|
label="&treecol.lastmod.label;"
|
|
tooltiptext="&treecol.lastmod.tooltip;"
|
|
sort="rdf:http://home.netscape.com/WEB-rdf#LastModifiedDate"
|
|
persist="width hidden ordinal"/>
|
|
<splitter class="tree-splitter" />
|
|
<treecol id="LastVisitDate" flex="1" hidden="true"
|
|
label="&treecol.lastvisit.label;"
|
|
tooltiptext="&treecol.lastvisit.tooltip;"
|
|
sort="rdf:http://home.netscape.com/WEB-rdf#LastVisitDate"
|
|
persist="width hidden ordinal"/>
|
|
</treecols>
|
|
</tree>
|
|
<statusbar class="chromeclass-status" xbl:inherits="hidden=hidestatusbar" hidden="false">
|
|
<statusbarpanel anonid="statusbar-text" flex="1"/>
|
|
</statusbar>
|
|
</vbox>
|
|
</xbl:content>
|
|
<implementation>
|
|
<field name="clickCount">2</field>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- Single column tree -->
|
|
<binding id="bookmarks-tree-name" extends="chrome://communicator/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 xbl:inherits="onpopupshowing"
|
|
onpopupshowing="this.parentNode.createTreeContextMenu(event);"
|
|
onpopuphidden="if (content) content.focus()"
|
|
onclick="event.stopPropagation();"
|
|
onkeypress="event.stopPropagation();"/>
|
|
<tree anonid="bookmarks-tree"
|
|
treelines="true"
|
|
flex="1"
|
|
class="plain"
|
|
hidecolumnpicker="true"
|
|
datasources="rdf:bookmarks rdf:internetsearch rdf:localsearch"
|
|
ref="NC:BookmarksRoot"
|
|
flags="dont-build-content"
|
|
seltype="single"
|
|
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">
|
|
<treecell properties="separator" label="rdf:http://home.netscape.com/NC-rdf#Name"/>
|
|
</treerow>
|
|
</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" />
|
|
</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 src="rdf:http://home.netscape.com/NC-rdf#Icon"
|
|
properties="rdf:http://home.netscape.com/WEB-rdf#status"
|
|
label="rdf:http://home.netscape.com/NC-rdf#Name"/>
|
|
</treerow>
|
|
</treeitem>
|
|
</treechildren>
|
|
</rule>
|
|
</template>
|
|
<treecols anonid="treecols">
|
|
<treecol id="Name" flex="1" primary="true" hideheader="true"
|
|
sort="rdf:http://home.netscape.com/NC-rdf#Name"
|
|
sortActive="true" sortLocked="true"/>
|
|
</treecols>
|
|
</tree>
|
|
</xbl:content>
|
|
<implementation>
|
|
<field name="clickCount">1</field>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<!-- Tree with folders only -->
|
|
<binding id="bookmarks-tree-folders" extends="chrome://communicator/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"
|
|
treelines="true"
|
|
flex="1"
|
|
hidecolumnpicker="true"
|
|
xbl:inherits="rows,seltype"
|
|
datasources="rdf:bookmarks rdf:internetsearch rdf:localsearch"
|
|
ref="NC:BookmarksTopRoot"
|
|
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 anonid="treecols">
|
|
<treecol id="Name" flex="1" primary="true" hideheader="true"
|
|
sort="rdf:http://home.netscape.com/NC-rdf#Name"
|
|
sortActive="true" sortLocked="true"/>
|
|
</treecols>
|
|
</tree>
|
|
</xbl:content>
|
|
<implementation>
|
|
<field name="clickCount">2</field>
|
|
</implementation>
|
|
</binding>
|
|
</bindings>
|