- adding bookmark/separator in the bookmark manager now calls the property dialog for consistency with the folders.

- fix the use of the immutable bookmarks.
- remove unused methods: GetLastCharset and AddBookmarkImmediately
- porting several small fixes mainly from Jan's work
- more prototyping for BookmarkTransaction


git-svn-id: svn://10.0.0.236/trunk@147445 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
chanial%noos.fr 2003-09-29 21:43:11 +00:00
parent 6fd647ae4a
commit 2c309d455c
8 changed files with 257 additions and 377 deletions

View File

@ -1,30 +0,0 @@
#
# 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):
#
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk

View File

@ -36,7 +36,7 @@
#
# ***** END LICENSE BLOCK *****
var NC_NS, RDF_NS, XUL_NS, NC_NS_CMD;
var NC_NS, WEB_NS, RDF_NS, XUL_NS, NC_NS_CMD;
// definition of the services frequently used for bookmarks
var kRDFContractID;
@ -69,10 +69,15 @@ var kWINDOWContractID;
var kWINDOWIID;
var WINDOWSVC;
var kDSContractID;
var kDSIID;
var DS;
// should be moved in a separate file
function initServices()
{
NC_NS = "http://home.netscape.com/NC-rdf#";
WEB_NS = "http://home.netscape.com/WEB-rdf#";
RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
NC_NS_CMD = NC_NS + "command?cmd=";
@ -85,7 +90,7 @@ function initServices()
kRDFCContractID = "@mozilla.org/rdf/container;1";
kRDFCIID = Components.interfaces.nsIRDFContainer;
RDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
RDFC = Components.classes[kRDFCContractID].createInstance(kRDFCIID);
kRDFCUContractID = "@mozilla.org/rdf/container-utils;1";
kRDFCUIID = Components.interfaces.nsIRDFContainerUtils;
@ -104,6 +109,10 @@ function initServices()
kWINDOWIID = Components.interfaces.nsIWindowMediator;
WINDOWSVC = Components.classes[kWINDOWContractID].getService(kWINDOWIID);
kDSContractID = "@mozilla.org/widget/dragservice;1";
kDSIID = Components.interfaces.nsIDragService;
DS = Components.classes[kDSContractID].getService(kDSIID);
}
function initBMService()
@ -111,12 +120,8 @@ function initBMService()
kBMSVCIID = Components.interfaces.nsIBookmarksService;
BMDS = RDF.GetDataSource("rdf:bookmarks");
BMSVC = BMDS.QueryInterface(kBMSVCIID);
BookmarkInsertTransaction.prototype.RDFC = RDFC;
BookmarkInsertTransaction.prototype.BMDS = BMDS;
BookmarkRemoveTransaction.prototype.RDFC = RDFC;
BookmarkRemoveTransaction.prototype.BMDS = BMDS;
BookmarkImportTransaction.prototype.RDFC = RDFC;
BookmarkImportTransaction.prototype.BMDS = BMDS;
BookmarkTransaction.prototype.RDFC = RDFC;
BookmarkTransaction.prototype.BMDS = BMDS;
}
/**
@ -634,38 +639,55 @@ var BookmarksCommand = {
}
},
createNewBookmark: function (aTarget)
{
var name = BookmarksUtils.getLocaleString("ile_newbookmark");
var resource = BMSVC.createBookmark(name, "", "", "", "");
this.createNewResource(resource, aTarget, "newbookmark");
},
createNewFolder: function (aTarget)
{
var name = BookmarksUtils.getLocaleString("ile_newfolder");
var rFolder = BMSVC.createFolder(name);
var selection = BookmarksUtils.getSelectionFromResource(rFolder, aTarget.parent);
var ok = BookmarksUtils.insertSelection("newfolder", selection, aTarget);
var name = BookmarksUtils.getLocaleString("ile_newfolder");
var resource = BMSVC.createFolder(name);
this.createNewResource(resource, aTarget, "newfolder");
},
createNewSeparator: function (aTarget)
{
var resource = BMSVC.createSeparator();
this.createNewResource(resource, aTarget, "newseparator");
},
createNewResource: function(aResource, aTarget, aTxnType)
{
var selection = BookmarksUtils.getSelectionFromResource(aResource, aTarget.parent);
// XXXpch: ugly ugly ugly temporary hack, getsynthesizeType says a bookmark
// is not a bookmark when it's not a child of sth.
if (aTxnType == "newbookmark") {
selection.type[0] = "Bookmark";
selection.isImmutable[0] = false;
selection.containsImmutable = false;
}
var ok = BookmarksUtils.insertSelection(aTxnType, selection, aTarget);
if (ok) {
var propWin = this.openBookmarkProperties(selection);
function canceledNewFolder()
function canceledNewResource()
{
BookmarksCommand.deleteBookmark(selection);
propWin.document.documentElement.removeEventListener("dialogcancel", canceledNewFolder, false);
propWin.document.documentElement.removeEventListener("dialogcancel", canceledNewResource, false);
propWin.removeEventListener("load", propertiesWindowLoad, false);
}
function propertiesWindowLoad()
{
propWin.document.documentElement.addEventListener("dialogcancel", canceledNewFolder, false);
propWin.document.documentElement.addEventListener("dialogcancel", canceledNewResource, false);
}
propWin.addEventListener("load", propertiesWindowLoad, false);
}
},
createNewSeparator: function (aTarget)
{
var rSeparator = BMSVC.createSeparator();
var selection = BookmarksUtils.getSelectionFromResource(rSeparator);
BookmarksUtils.insertSelection("newseparator", selection, aTarget);
},
importBookmarks: function ()
{
///transaction...
@ -784,9 +806,6 @@ var BookmarksController = {
isCommandEnabled: function (aCommand, aSelection, aTarget)
{
if (aTarget.parent.Value == "NC:BookmarksTopRoot")
return false;
var item0, type0;
var length = aSelection.length;
if (length != 0) {
@ -797,10 +816,11 @@ var BookmarksController = {
switch(aCommand) {
case "cmd_undo":
case "cmd_redo":
case "cmd_bm_undo":
return BMSVC.transactionManager.numberOfUndoItems > 0;
case "cmd_redo":
case "cmd_bm_redo":
return true;
return BMSVC.transactionManager.numberOfRedoItems > 0;
case "cmd_bm_paste":
if (!BookmarksUtils.isValidTargetContainer(aTarget.parent))
return false;
@ -824,9 +844,8 @@ var BookmarksController = {
case "cmd_bm_copy":
return length > 0;
case "cmd_bm_cut":
return true;
case "cmd_bm_delete":
return length > 0 && aSelection.containsMutable && !aSelection.containsPTF;
return length > 0 && !aSelection.containsImmutable && !aSelection.containsPTF;
case "cmd_bm_selectAll":
return true;
case "cmd_bm_open":
@ -868,14 +887,15 @@ var BookmarksController = {
case "cmd_bm_setpersonaltoolbarfolder":
if (length != 1)
return false;
return item0 != "NC:PersonalToolbarFolder" && type0 == "Folder";
return item0 != "NC:PersonalToolbarFolder" &&
item0 != "NC:BookmarksRoot" && type0 == "Folder";
case "cmd_bm_setnewsearchfolder":
if (length != 1)
return false;
return item0 != "NC:NewSearchFolder" &&
(type0 == "Folder" || type0 == "PersonalToolbarFolder");
case "cmd_bm_movebookmark":
return length > 0;
return length > 0 && !aSelection.containsImmutable;
default:
return false;
}
@ -931,15 +951,12 @@ var BookmarksController = {
case "cmd_bm_movebookmark":
BookmarksCommand.moveBookmark(aSelection);
break;
case "cmd_bm_newbookmark":
BookmarksCommand.createNewBookmark(aTarget);
break;
case "cmd_bm_newfolder":
BookmarksCommand.createNewFolder(aTarget);
break;
case "cmd_bm_newbookmark":
var folder = aTarget.parent.Value;
var rv = { newBookmark: null };
openDialog("chrome://browser/content/bookmarks/addBookmark.xul", "",
"centerscreen,chrome,modal=yes,dialog=yes,resizable=no", null, null, folder, null, "newBookmark", rv);
break;
case "cmd_bm_newseparator":
BookmarksCommand.createNewSeparator(aTarget);
break;
@ -957,12 +974,10 @@ var BookmarksController = {
onCommandUpdate: function (aSelection, aTarget)
{
var commands = ["cmd_bm_newbookmark", "cmd_bm_newfolder", "cmd_bm_newseparator",
"cmd_bm_properties", "cmd_bm_rename",
var commands = ["cmd_bm_newbookmark", "cmd_bm_newfolder", "cmd_bm_newseparator",
"cmd_undo", "cmd_redo", "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_movebookmark",
"cmd_bm_setpersonaltoolbarfolder", "cmd_bm_movebookmark",
"cmd_bm_openfolder", "cmd_bm_managefolder"];
for (var i = 0; i < commands.length; ++i) {
var enabled = this.isCommandEnabled(commands[i], aSelection, aTarget);
@ -1076,6 +1091,17 @@ var BookmarksUtils = {
}
},
getResource: function (aName)
{
if (aName == "LastModifiedDate" ||
aName == "LastVisitDate") {
return RDF.GetResource(WEB_NS + aName);
}
else {
return RDF.GetResource(NC_NS + aName);
}
},
/////////////////////////////////////////////////////////////////////////////
// Determine the rdf:type property for the given resource.
resolveType: function (aResource)
@ -1147,13 +1173,13 @@ var BookmarksUtils = {
if (aSelection.length == 0)
return;
aSelection.type = new Array(aSelection.length);
aSelection.protocol = new Array(aSelection.length);
aSelection.isContainer = new Array(aSelection.length);
aSelection.isImmutable = new Array(aSelection.length);
aSelection.isValid = new Array(aSelection.length);
aSelection.containsMutable = false;
aSelection.containsPTF = false;
aSelection.type = new Array(aSelection.length);
aSelection.protocol = new Array(aSelection.length);
aSelection.isContainer = new Array(aSelection.length);
aSelection.isImmutable = new Array(aSelection.length);
aSelection.isValid = new Array(aSelection.length);
aSelection.containsPTF = false;
aSelection.containsImmutable = false;
var index, item, parent, type, protocol, isContainer, isImmutable, isValid;
for (var i=0; i<aSelection.length; ++i) {
item = aSelection.item[i];
@ -1164,8 +1190,9 @@ var BookmarksUtils = {
protocol == "find" || protocol == "file";
isValid = true;
isImmutable = false;
if (item == "NC:BookmarksRoot")
if (item.Value == "NC:BookmarksRoot") {
isImmutable = true;
}
else if (type != "Bookmark" && type != "BookmarkSeparator" &&
type != "Folder" && type != "PersonalToolbarFolder")
isImmutable = true;
@ -1174,8 +1201,8 @@ var BookmarksUtils = {
if (parentProtocol == "find" || parentProtocol == "file")
aSelection.parent[i] = null;
}
if (!isImmutable && aSelection.parent[i])
aSelection.containsMutable = true;
if (isImmutable)
aSelection.containsImmutable = true;
aSelection.type [i] = type;
aSelection.protocol [i] = protocol;
@ -1234,6 +1261,8 @@ var BookmarksUtils = {
{
if (!aFolder)
return false;
if (aFolder.Value == "NC:BookmarksTopRoot")
return false;
if (aFolder.Value == "NC:BookmarksRoot")
return true;
@ -1318,7 +1347,7 @@ var BookmarksUtils = {
var rSource = aSelection.item[i];
if (transaction.isValid[i]) {
if (BMSVC.isBookmarkedInternal(rSource))
if (BMSVC.isBookmarkedResource(rSource))
rSource = BMSVC.cloneResource(rSource);
transaction.item [i] = rSource;
transaction.parent[i] = aTarget.parent;
@ -1491,6 +1520,35 @@ var BookmarksUtils = {
}
}
function BookmarkTransaction()
{
}
BookmarkTransaction.prototype = {
BATCH_LIMIT : 8,
RDFC : null,
BMDS : null,
beginUpdateBatch: function()
{
if (this.item.length > this.BATCH_LIMIT) {
this.BMDS.beginUpdateBatch();
}
},
endUpdateBatch: function()
{
if (this.item.length > this.BATCH_LIMIT) {
this.BMDS.endUpdateBatch();
}
},
merge : function (aTxn) {return false},
QueryInterface : function (aUID) {return this},
getHelperForLanguage: function (aCount) {return null},
getInterfaces : function (aCount) {return null},
canCreateWrapper : function (aIID) {return "AllAccess"}
}
function BookmarkInsertTransaction (aAction)
{
this.wrappedJSObject = this;
@ -1504,42 +1562,40 @@ function BookmarkInsertTransaction (aAction)
BookmarkInsertTransaction.prototype =
{
__proto__: BookmarkTransaction.prototype,
isTransient: false,
RDFC : RDFC,
BMDS : BMDS,
doTransaction: function ()
{
this.beginUpdateBatch();
for (var i=0; i<this.item.length; ++i) {
if (this.isValid[i]) {
this.RDFC.Init(this.BMDS, this.parent[i]);
this.RDFC.InsertElementAt(this.item[i], this.index[i], true);
}
}
this.endUpdateBatch();
},
undoTransaction: function ()
{
this.beginUpdateBatch();
// XXXvarga Can't use |RDFC| here because it's being "reused" elsewhere.
var container = Components.classes[kRDFCContractID].createInstance(kRDFCIID);
for (var i=this.item.length-1; i>=0; i--) {
if (this.isValid[i]) {
this.RDFC.Init(this.BMDS, this.parent[i]);
this.RDFC.RemoveElementAt(this.index[i], true);
container.Init(this.BMDS, this.parent[i]);
container.RemoveElementAt(this.index[i], true);
}
}
this.endUpdateBatch();
},
redoTransaction: function ()
{
this.doTransaction();
},
merge : function (aTransaction) {return false},
QueryInterface : function (aUID) {return this},
getHelperForLanguage: function (aCount) {return null},
getInterfaces : function (aCount) {return null},
canCreateWrapper : function (aIID) {return "AllAccess"}
}
}
function BookmarkRemoveTransaction (aAction)
@ -1555,42 +1611,38 @@ function BookmarkRemoveTransaction (aAction)
BookmarkRemoveTransaction.prototype =
{
__proto__: BookmarkTransaction.prototype,
isTransient: false,
RDFC : RDFC,
BMDS : BMDS,
doTransaction: function ()
{
this.beginUpdateBatch();
for (var i=0; i<this.item.length; ++i) {
if (this.isValid[i]) {
this.RDFC.Init(this.BMDS, this.parent[i]);
this.RDFC.RemoveElementAt(this.index[i], false);
}
}
this.endUpdateBatch();
},
undoTransaction: function ()
{
this.beginUpdateBatch();
for (var i=this.item.length-1; i>=0; i--) {
if (this.isValid[i]) {
this.RDFC.Init(this.BMDS, this.parent[i]);
this.RDFC.InsertElementAt(this.item[i], this.index[i], false);
}
}
this.endUpdateBatch();
},
redoTransaction: function ()
{
this.doTransaction();
},
merge : function (aTransaction) {return false},
QueryInterface : function (aUID) {return this},
getHelperForLanguage: function (aCount) {return null},
getInterfaces : function (aCount) {return null},
canCreateWrapper : function (aIID) {return "AllAccess"}
}
}
function BookmarkMoveTransaction (aAction, aSelection, aTarget)
@ -1605,23 +1657,34 @@ function BookmarkMoveTransaction (aAction, aSelection, aTarget)
BookmarkMoveTransaction.prototype =
{
__proto__: BookmarkTransaction.prototype,
isTransient: false,
doTransaction: function ()
beginUpdateBatch: function()
{
BookmarksUtils.removeSelection("move", this.selection);
BookmarksUtils.insertSelection("move", this.selection, this.target);
if (this.selection.length > this.BATCH_LIMIT) {
this.BMDS.beginUpdateBatch();
}
},
undoTransaction : function () {},
redoTransaction : function () {},
merge : function (aTransaction) {return false},
QueryInterface : function (aUID) {return this},
getHelperForLanguage: function (aCount) {return null},
getInterfaces : function (aCount) {return null},
canCreateWrapper : function (aIID) {return "AllAccess"}
endUpdateBatch: function()
{
if (this.selection.length > this.BATCH_LIMIT) {
this.BMDS.endUpdateBatch();
}
},
doTransaction: function ()
{
this.beginUpdateBatch();
BookmarksUtils.removeSelection("move", this.selection);
BookmarksUtils.insertSelection("move", this.selection, this.target);
this.endUpdateBatch();
},
undoTransaction: function () {},
redoTransaction: function () {}
}
function BookmarkImportTransaction (aAction)
@ -1637,10 +1700,9 @@ function BookmarkImportTransaction (aAction)
BookmarkImportTransaction.prototype =
{
__proto__: BookmarkTransaction.prototype,
isTransient: false,
RDFC : RDFC,
BMDS : BMDS,
doTransaction: function ()
{
@ -1648,30 +1710,27 @@ BookmarkImportTransaction.prototype =
undoTransaction: function ()
{
this.beginUpdateBatch();
for (var i=this.item.length-1; i>=0; i--) {
if (this.isValid[i]) {
this.RDFC.Init(this.BMDS, this.parent[i]);
this.RDFC.RemoveElementAt(this.index[i], true);
}
}
this.endUpdateBatch();
},
redoTransaction: function ()
{
this.beginUpdateBatch();
for (var i=0; i<this.item.length; ++i) {
if (this.isValid[i]) {
this.RDFC.Init(this.BMDS, this.parent[i]);
this.RDFC.InsertElementAt(this.item[i], this.index[i], true);
}
}
},
merge : function (aTransaction) {return false},
QueryInterface : function (aUID) {return this},
getHelperForLanguage: function (aCount) {return null},
getInterfaces : function (aCount) {return null},
canCreateWrapper : function (aIID) {return "AllAccess"}
this.endUpdateBatch();
}
}
var BookmarkEditMenuTxnListener =
@ -1713,10 +1772,8 @@ var BookmarkEditMenuTxnListener =
transactionNumber = aTxmgr.numberOfUndoItems;
dump("N UNDO: "+transactionNumber+"\n")
if (transactionNumber == 0) {
node.setAttribute("disabled", "true");
transactionLabel = BookmarksUtils.getLocaleString("cmd_bm_undo");
} else {
node.removeAttribute("disabled");
transactionList = aTxmgr.getUndoList();
action = transactionList.getItem(transactionNumber-1).wrappedJSObject.action;
transactionLabel = BookmarksUtils.getLocaleString("cmd_bm_"+action+"_undo")
@ -1727,17 +1784,14 @@ var BookmarkEditMenuTxnListener =
transactionNumber = aTxmgr.numberOfRedoItems;
dump("N REDO: "+transactionNumber+"\n")
if (transactionNumber == 0) {
node.setAttribute("disabled", "true");
transactionLabel = BookmarksUtils.getLocaleString("cmd_bm_redo");
} else {
node.removeAttribute("disabled");
transactionList = aTxmgr.getRedoList();
action = transactionList.getItem(transactionNumber-1).wrappedJSObject.action;
transactionLabel = BookmarksUtils.getLocaleString("cmd_bm_"+action+"_redo")
}
node.setAttribute("label", transactionLabel);
}
}
function dumpOBJ (aObj)
@ -1805,4 +1859,3 @@ function dumpTXN(aTxn)
}
}
}

View File

@ -31,7 +31,6 @@ function Startup()
const windowNode = document.getElementById("bookmark-window");
const bookmarksView = document.getElementById("bookmarks-view");
var rowIndex = 0;
var titleString;
// If we've been opened with a parameter, root the tree on it.
@ -56,11 +55,10 @@ function Startup()
// always open the bookmark top root folder
if (!bookmarksView.treeBoxObject.view.isContainerOpen(0))
bookmarksView.treeBoxObject.view.toggleOpenState(0);
if (!bookmarksView.treeBoxObject.view.isContainerEmpty(0))
rowIndex = 1;
}
bookmarksView.treeBoxObject.selection.select(rowIndex);
bookmarksView.treeBoxObject.selection.select(0);
windowNode.setAttribute("title", titleString);
document.getElementById("CommandUpdate_Bookmarks").setAttribute("commandupdater","true");
@ -70,10 +68,10 @@ function Startup()
}
function Shutdown ()
function Shutdown()
{
BMSVC.transactionManager.RemoveListener(BookmarkEditMenuTxnListener);
// Store current window position and size in window attributes (for persistence)
// Store current window position and size in window attributes (for persistence).
var win = document.getElementById("bookmark-window");
win.setAttribute("x", screenX);
win.setAttribute("y", screenY);

View File

@ -206,7 +206,8 @@ function Init()
var url = Bookmarks.GetTarget(resource, RDF.GetResource(gProperties[1]), true);
if (url) {
url = url.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
if (url.substr(0, 7).toLowerCase() == "http://" ||
if (!url ||
url.substr(0, 7).toLowerCase() == "http://" ||
url.substr(0, 8).toLowerCase() == "https://") {
showScheduling = true;
}
@ -258,9 +259,9 @@ function Commit()
newvalue = newvalue.toLowerCase();
}
else if (newvalue && gProperties[i] == (NC_NS + "URL")) {
// we're dealing with the URL attribute;
// if a scheme isn't specified, use "http://"
if (newvalue.indexOf(":") < 0)
// we're dealing with the URL attribute;
// if a scheme isn't specified, use "http://"
newvalue = "http://" + newvalue;
}

View File

@ -54,13 +54,13 @@
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("&");
@ -112,7 +112,7 @@
}
formatString = formatString.replace(/%6%/, child.getAttribute("ordinal"));
persistString += formatString;
}
}
child = child.nextSibling;
}
this.setAttribute("colinfo", persistString);
@ -353,12 +353,12 @@
<parameter name="aParent"/>
<parameter name="aOrientation"/>
<body><![CDATA[
if (aItem === undefined)
return BookmarksUtils.getTargetFromFolder(this.getRootResource());
if (aOrientation == BookmarksUtils.DROP_ON) {
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);
@ -453,7 +453,7 @@
newSelection.rangedSelect(newRanges[i].min, newRanges[i].max, true);
]]></body>
</method>
<field name="_itemToBeToggled"> []</field>
<field name="_parentToBeToggled">[]</field>
<method name="preUpdateTreeSelection">
@ -571,8 +571,7 @@
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)
if (aEvent.ctrlKey)
aDragAction.action = kDSIID.DRAGDROP_ACTION_COPY;
}
})
@ -644,10 +643,21 @@
mOuter: this,
canDropOn: function(index)
{
return true;
var dragSession = DS.getCurrentSession();
if (!dragSession)
return false;
var selection = BookmarksUtils.getSelectionFromXferData(dragSession);
return !selection.containsImmutable;
},
canDropBeforeAfter: function(index, before)
{
var dragSession = DS.getCurrentSession();
if (!dragSession)
return false;
var selection = BookmarksUtils.getSelectionFromXferData(dragSession);
if (selection.containsImmutable)
return false;
if (index != 0)
return true;
if (this.mOuter.getRowResource(index).Value != "NC:BookmarksRoot")
@ -656,8 +666,7 @@
},
onDrop: function(row, orientation)
{
var dragService = Components.classes["@mozilla.org/widget/dragservice;1"].getService().QueryInterface(Components.interfaces.nsIDragService);
var dragSession = dragService.getCurrentSession();
var dragSession = DS.getCurrentSession();
if (!dragSession)
return;
//var date = Date.now();
@ -675,16 +684,12 @@
}
//var firstVisibleRow = this.mOuter.treeBoxObject.getFirstVisibleRow()
this.mOuter.treeBoxObject.selection.selectEventsSuppressed = true;
// Notify the datasource that we're about to begin a batch operation
//BMDS.beginUpdateBatch();
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);
//BMDS.endUpdateBatch();
//this.mOuter.treeBoxObject.selection.currentIndex=-1;
// temporary hack: for an unknown reason, rebuilding cause a scroll to the bottom
// if the first visible row is not 0

View File

@ -1,29 +0,0 @@
# 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):
packages/core.jar:
communicator/content/bookmarks/bm-find.js
communicator/content/bookmarks/bm-find.xul
communicator/content/bookmarks/bm-panel.js
communicator/content/bookmarks/bm-panel.xul
communicator/content/bookmarks/bm-props.js
communicator/content/bookmarks/bm-props.xul
communicator/content/bookmarks/bookmarks.js
communicator/content/bookmarks/bookmarksDD.js
communicator/content/bookmarks/bookmarks.xul

View File

@ -54,11 +54,8 @@ interface nsIBookmarksService : nsISupports
const unsigned long BOOKMARK_FIND_TYPE = 2;
boolean readBookmarks();
boolean isBookmarked(in string aURL);
boolean isBookmarkedInternal(in nsIRDFResource aSource);
boolean isBookmarkedResource(in nsIRDFResource aSource);
void addBookmarkImmediately(in string aURI, in wstring aTitle, in long bmType, in wstring docCharset);
nsIRDFResource createFolder(in wstring aName);
nsIRDFResource createFolderInContainer(in wstring aName, in nsIRDFResource aParentFolder,
in long aIndex);
@ -87,8 +84,6 @@ interface nsIBookmarksService : nsISupports
string resolveKeyword(in wstring aName);
wstring getLastCharset(in string aURL);
void importSystemBookmarks(in nsIRDFResource aParentFolder);
readonly attribute nsITransactionManager transactionManager;

View File

@ -98,7 +98,6 @@ nsIRDFResource *kNC_BookmarkSeparator;
nsIRDFResource *kNC_BookmarkAddDate;
nsIRDFResource *kNC_BookmarksTopRoot;
nsIRDFResource *kNC_BookmarksRoot;
nsIRDFResource *kNC_ID;
nsIRDFResource *kNC_Description;
nsIRDFResource *kNC_Folder;
nsIRDFResource *kNC_FolderType;
@ -227,8 +226,6 @@ bm_AddRefGlobals()
&kNC_BookmarkSeparator);
gRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "BookmarkAddDate"),
&kNC_BookmarkAddDate);
gRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "ID"),
&kNC_ID);
gRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Description"),
&kNC_Description);
gRDF->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Folder"),
@ -336,7 +333,6 @@ bm_ReleaseGlobals()
NS_IF_RELEASE(kNC_BookmarkAddDate);
NS_IF_RELEASE(kNC_BookmarksTopRoot);
NS_IF_RELEASE(kNC_BookmarksRoot);
NS_IF_RELEASE(kNC_ID);
NS_IF_RELEASE(kNC_Description);
NS_IF_RELEASE(kNC_Folder);
NS_IF_RELEASE(kNC_FolderType);
@ -1685,22 +1681,22 @@ nsBookmarksService::Init()
if (NS_SUCCEEDED(useProfile))
{
nsXPIDLString currentProfileName;
useProfile = profileService->GetCurrentProfile(getter_Copies(currentProfileName));
if (NS_SUCCEEDED(useProfile))
{
const PRUnichar *param[1] = {currentProfileName.get()};
useProfile = mBundle->FormatStringFromName(NS_LITERAL_STRING("bookmarks_root").get(),
param, 1, getter_Copies(mBookmarksRootName));
useProfile = profileService->GetCurrentProfile(getter_Copies(currentProfileName));
if (NS_SUCCEEDED(useProfile))
{
PRInt32 profileCount;
useProfile = profileService->GetProfileCount(&profileCount);
if (NS_SUCCEEDED(useProfile) && profileCount == 1)
const PRUnichar *param[1] = {currentProfileName.get()};
useProfile = mBundle->FormatStringFromName(NS_LITERAL_STRING("bookmarks_root").get(),
param, 1, getter_Copies(mBookmarksRootName));
if (NS_SUCCEEDED(useProfile))
{
ToLowerCase(currentProfileName);
if (currentProfileName.Equals(NS_LITERAL_STRING("default")))
useProfile = NS_ERROR_FAILURE;
PRInt32 profileCount;
useProfile = profileService->GetProfileCount(&profileCount);
if (NS_SUCCEEDED(useProfile) && profileCount == 1)
{
ToLowerCase(currentProfileName);
if (currentProfileName.Equals(NS_LITERAL_STRING("default")))
useProfile = NS_ERROR_FAILURE;
}
}
}
@ -2783,12 +2779,11 @@ nsBookmarksService::CreateSeparator(nsIRDFResource** aResult)
}
NS_IMETHODIMP
nsBookmarksService::CloneResource(nsIRDFResource* aSource, nsIRDFResource** aResult)
nsBookmarksService::CloneResource(nsIRDFResource* aSource,
nsIRDFResource** aResult)
{
nsresult rv;
nsCOMPtr<nsIRDFResource> resource;
rv = gRDF->GetAnonymousResource(getter_AddRefs(resource));
nsCOMPtr<nsIRDFResource> newResource;
nsresult rv = gRDF->GetAnonymousResource(getter_AddRefs(newResource));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISimpleEnumerator> arcs;
@ -2797,73 +2792,51 @@ nsBookmarksService::CloneResource(nsIRDFResource* aSource, nsIRDFResource** aRes
PRBool hasMore;
while (NS_SUCCEEDED(arcs->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> isupports;
arcs->GetNext(getter_AddRefs(isupports));
nsCOMPtr<nsISupports> supports;
rv = arcs->GetNext(getter_AddRefs(supports));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIRDFResource> property = do_QueryInterface(isupports, &rv);
nsCOMPtr<nsIRDFResource> property = do_QueryInterface(supports, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIRDFNode> targetNode;
rv = mInner->GetTarget(aSource, property, PR_TRUE, getter_AddRefs(targetNode));
// Don't duplicate the folder type.
// (NC:PersonalToolbarFolder, NC:NewBookmarkFolder, etc...)
PRBool isFolderType;
rv = property->EqualsNode(kNC_FolderType, &isFolderType);
NS_ENSURE_SUCCESS(rv, rv);
if (isFolderType)
continue;
nsCOMPtr<nsIRDFNode> target;
rv = mInner->GetTarget(aSource, property, PR_TRUE, getter_AddRefs(target));
NS_ENSURE_SUCCESS(rv, rv);
// test if the arc points to a children
// Test if the arc points to a child.
PRBool isOrdinal;
rv = gRDFC->IsOrdinalProperty(property, &isOrdinal);
if (NS_SUCCEEDED(rv) && isOrdinal) {
nsCOMPtr<nsIRDFResource> oldTargetResource = do_QueryInterface(targetNode);
nsCOMPtr<nsIRDFResource> newTargetResource;
rv = CloneResource(oldTargetResource, getter_AddRefs(newTargetResource));
NS_ENSURE_SUCCESS(rv, rv);
if (isOrdinal) {
nsCOMPtr<nsIRDFResource> oldChild = do_QueryInterface(target);
nsCOMPtr<nsIRDFResource> newChild;
rv = CloneResource(oldChild, getter_AddRefs(newChild));
NS_ENSURE_SUCCESS(rv, rv);
mInner->Assert(resource, property, newTargetResource, PR_TRUE);
} else {
mInner->Assert(resource, property, targetNode, PR_TRUE);
rv = mInner->Assert(newResource, property, newChild, PR_TRUE);
}
else {
rv = mInner->Assert(newResource, property, target, PR_TRUE);
}
NS_ENSURE_SUCCESS(rv, rv);
}
// correctly assert cloned ID
mInner->Change(resource, kNC_ID, aSource, resource);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = resource;
NS_ADDREF(*aResult);
NS_ADDREF(*aResult = newResource);
return NS_OK;
}
NS_IMETHODIMP
nsBookmarksService::AddBookmarkImmediately(const char *aURI,
const PRUnichar *aTitle,
PRInt32 aBookmarkType,
const PRUnichar *aCharset)
{
nsresult rv;
// Figure out where to add the new bookmark
nsCOMPtr<nsIRDFResource> bookmarkFolder = kNC_NewBookmarkFolder;
switch(aBookmarkType)
{
case BOOKMARK_SEARCH_TYPE:
case BOOKMARK_FIND_TYPE:
bookmarkFolder = kNC_NewSearchFolder;
break;
}
nsCOMPtr<nsIRDFResource> destinationFolder;
rv = getFolderViaHint(bookmarkFolder, PR_TRUE, getter_AddRefs(destinationFolder));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIRDFResource> bookmark;
return CreateBookmarkInContainer(aTitle, aURI, nsnull, nsnull, aCharset, destinationFolder, -1,
getter_AddRefs(bookmark));
}
NS_IMETHODIMP
nsBookmarksService::IsBookmarkedInternal(nsIRDFResource *bookmark, PRBool *isBookmarkedFlag)
nsBookmarksService::IsBookmarkedResource(nsIRDFResource *bookmark, PRBool *isBookmarkedFlag)
{
if (!bookmark) return NS_ERROR_UNEXPECTED;
if (!isBookmarkedFlag) return NS_ERROR_UNEXPECTED;
@ -2905,79 +2878,6 @@ nsBookmarksService::IsBookmarkedInternal(nsIRDFResource *bookmark, PRBool *isBoo
return rv;
}
NS_IMETHODIMP
nsBookmarksService::IsBookmarked(const char* aURL, PRBool* aIsBookmarked)
{
NS_ENSURE_ARG(aURL);
NS_ENSURE_ARG_POINTER(aIsBookmarked);
if (!mInner)
return NS_ERROR_UNEXPECTED;
*aIsBookmarked = PR_FALSE;
nsCOMPtr<nsIRDFLiteral> urlLiteral;
nsresult rv = gRDF->GetLiteral(NS_ConvertUTF8toUCS2(aURL).get(),
getter_AddRefs(urlLiteral));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIRDFResource> bookmark;
rv = GetSource(kNC_URL, urlLiteral, PR_TRUE, getter_AddRefs(bookmark));
if (NS_FAILED(rv))
return rv;
return IsBookmarkedInternal(bookmark, aIsBookmarked);
}
NS_IMETHODIMP
nsBookmarksService::GetLastCharset(const char* aURL, PRUnichar** aLastCharset)
{
NS_PRECONDITION(aURL != nsnull, "null ptr");
if (! aURL)
return NS_ERROR_NULL_POINTER;
NS_ENSURE_ARG_POINTER(aLastCharset);
if (!mInner)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIRDFLiteral> urlLiteral;
nsresult rv = gRDF->GetLiteral(NS_ConvertUTF8toUCS2(aURL).get(),
getter_AddRefs(urlLiteral));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIRDFResource> bookmark;
rv = GetSource(kNC_URL, urlLiteral, PR_TRUE, getter_AddRefs(bookmark));
if (NS_FAILED(rv))
return rv;
if (bookmark) {
// Always use mInner! Otherwise, could get into an infinite loop
// due to Assert/Change calling UpdateBookmarkLastModifiedDate().
nsCOMPtr<nsIRDFNode> nodeType;
GetSynthesizedType(bookmark, getter_AddRefs(nodeType));
if (nodeType == kNC_Bookmark) {
nsCOMPtr<nsIRDFNode> charsetNode;
rv = mInner->GetTarget(bookmark, kWEB_LastCharset, PR_TRUE,
getter_AddRefs(charsetNode));
if (NS_FAILED(rv))
return rv;
if (charsetNode) {
nsCOMPtr<nsIRDFLiteral> charsetLiteral = do_QueryInterface(charsetNode);
if (charsetLiteral) {
return charsetLiteral->GetValue(aLastCharset);
}
}
}
}
*aLastCharset = nsnull;
return NS_RDF_NO_VALUE;
}
NS_IMETHODIMP
nsBookmarksService::UpdateBookmarkIcon(const char *aURL, const PRUnichar *aIconURL)
{
@ -3180,9 +3080,9 @@ nsBookmarksService::GetSynthesizedType(nsIRDFResource *aNode, nsIRDFNode **aType
if (isContainer)
{
*aType = kNC_Folder;
*aType = kNC_Folder;
}
else if (NS_SUCCEEDED(rv = IsBookmarkedInternal(aNode,
else if (NS_SUCCEEDED(rv = IsBookmarkedResource(aNode,
&isBookmarkedFlag)) && (isBookmarkedFlag == PR_TRUE))
{
*aType = kNC_Bookmark;
@ -3547,7 +3447,7 @@ nsBookmarksService::GetTarget(nsIRDFResource* aSource,
{
*aTarget = nsnull;
nsresult rv;
nsresult rv;
if (aTruthValue && (aProperty == kRDF_type))
{
@ -4212,12 +4112,10 @@ nsBookmarksService::setFolderHint(nsIRDFResource *newSource, nsIRDFResource *obj
continue;
}
// if not setting a new Personal Toolbar Folder, just assert new type, and then done
if (objType != kNC_PersonalToolbarFolder)
{
if (NS_SUCCEEDED(rv = mInner->Assert(newSource, kNC_FolderType, objType, PR_TRUE)))
{ }
// If not setting a new Personal Toolbar Folder, just assert new type, and
// then done.
if (objType != kNC_PersonalToolbarFolder) {
rv = mInner->Assert(newSource, kNC_FolderType, objType, PR_TRUE);
mDirty = PR_TRUE;
return rv;
@ -4251,7 +4149,7 @@ nsBookmarksService::setFolderHint(nsIRDFResource *newSource, nsIRDFResource *obj
mDirty = PR_TRUE;
Flush();
return rv;
return NS_OK;
}
nsresult
@ -4268,16 +4166,10 @@ nsBookmarksService::getFolderViaHint(nsIRDFResource *objType, PRBool fallbackFla
if ((rv != NS_RDF_NO_VALUE) && (oldSource))
{
const char *uri = nsnull;
oldSource->GetValueConst(&uri);
if (uri)
{
PRBool isBookmarkedFlag = PR_FALSE;
if (NS_SUCCEEDED(rv = IsBookmarked(uri, &isBookmarkedFlag)) &&
(isBookmarkedFlag == PR_TRUE))
{
*folder = oldSource;
}
PRBool isBookmarkedFlag = PR_FALSE;
if (NS_SUCCEEDED(rv = IsBookmarkedResource(oldSource, &isBookmarkedFlag)) &&
isBookmarkedFlag) {
*folder = oldSource;
}
}
@ -4797,7 +4689,6 @@ nsBookmarksService::LoadBookmarks()
}
}
// Sets the default bookmarks root name.
nsCOMPtr<nsIRDFLiteral> brNameLiteral;
rv = gRDF->GetLiteral(mBookmarksRootName.get(), getter_AddRefs(brNameLiteral));
@ -5047,9 +4938,9 @@ nsBookmarksService::WriteBookmarks(nsIFile* aBookmarksFile,
static const char kBookmarkIntro[] = "<DL><p>" NS_LINEBREAK;
static const char kIndent[] = " ";
static const char kContainerIntro[] = "<DT><H3";
static const char kSpace[] = " ";
static const char kSpaceStr[] = " ";
static const char kTrueEnd[] = "true\"";
static const char kQuote[] = "\"";
static const char kQuoteStr[] = "\"";
static const char kCloseAngle[] = ">";
static const char kCloseH3[] = "</H3>" NS_LINEBREAK;
static const char kHROpen[] = "<HR";
@ -5151,7 +5042,7 @@ nsBookmarksService::WriteBookmarksContainer(nsIRDFDataSource *ds,
if (NS_SUCCEEDED(rv = mInner->HasAssertion(child, kNC_FolderType, kNC_NewBookmarkFolder,
PR_TRUE, &hasType)) && (hasType == PR_TRUE))
{
rv = strm->Write(kSpace, sizeof(kSpace)-1, &dummy);
rv = strm->Write(kSpaceStr, sizeof(kSpaceStr)-1, &dummy);
rv |= strm->Write(kNewBookmarkFolderEquals, sizeof(kNewBookmarkFolderEquals)-1, &dummy);
rv |= strm->Write(kTrueEnd, sizeof(kTrueEnd)-1, &dummy);
if (NS_FAILED(rv)) break;
@ -5159,7 +5050,7 @@ nsBookmarksService::WriteBookmarksContainer(nsIRDFDataSource *ds,
if (NS_SUCCEEDED(rv = mInner->HasAssertion(child, kNC_FolderType, kNC_NewSearchFolder,
PR_TRUE, &hasType)) && (hasType == PR_TRUE))
{
rv = strm->Write(kSpace, sizeof(kSpace)-1, &dummy);
rv = strm->Write(kSpaceStr, sizeof(kSpaceStr)-1, &dummy);
rv |= strm->Write(kNewSearchFolderEquals, sizeof(kNewSearchFolderEquals)-1, &dummy);
rv |= strm->Write(kTrueEnd, sizeof(kTrueEnd)-1, &dummy);
if (NS_FAILED(rv)) break;
@ -5167,7 +5058,7 @@ nsBookmarksService::WriteBookmarksContainer(nsIRDFDataSource *ds,
if (NS_SUCCEEDED(rv = mInner->HasAssertion(child, kNC_FolderType, kNC_PersonalToolbarFolder,
PR_TRUE, &hasType)) && (hasType == PR_TRUE))
{
rv = strm->Write(kSpace, sizeof(kSpace)-1, &dummy);
rv = strm->Write(kSpaceStr, sizeof(kSpaceStr)-1, &dummy);
rv |= strm->Write(kPersonalToolbarFolderEquals, sizeof(kPersonalToolbarFolderEquals)-1, &dummy);
rv |= strm->Write(kTrueEnd, sizeof(kTrueEnd)-1, &dummy);
if (NS_FAILED(rv)) break;
@ -5178,10 +5069,10 @@ nsBookmarksService::WriteBookmarksContainer(nsIRDFDataSource *ds,
rv = child->GetValueConst(&id);
if (NS_SUCCEEDED(rv) && (id))
{
rv = strm->Write(kSpace, sizeof(kSpace)-1, &dummy);
rv = strm->Write(kSpaceStr, sizeof(kSpaceStr)-1, &dummy);
rv |= strm->Write(kIDEquals, sizeof(kIDEquals)-1, &dummy);
rv |= strm->Write(id, strlen(id), &dummy);
rv |= strm->Write(kQuote, sizeof(kQuote)-1, &dummy);
rv |= strm->Write(kQuoteStr, sizeof(kQuoteStr)-1, &dummy);
if (NS_FAILED(rv)) break;
}
@ -5279,10 +5170,10 @@ nsBookmarksService::WriteBookmarksContainer(nsIRDFDataSource *ds,
rv = child->GetValueConst(&id);
if (NS_SUCCEEDED(rv) && (id))
{
rv = strm->Write(kSpace, sizeof(kSpace)-1, &dummy);
rv = strm->Write(kSpaceStr, sizeof(kSpaceStr)-1, &dummy);
rv |= strm->Write(kIDEquals, sizeof(kIDEquals)-1, &dummy);
rv |= strm->Write(id, strlen(id), &dummy);
rv |= strm->Write(kQuote, sizeof(kQuote)-1, &dummy);
rv |= strm->Write(kQuoteStr, sizeof(kQuoteStr)-1, &dummy);
if (NS_FAILED(rv)) break;
}
@ -5464,7 +5355,7 @@ nsBookmarksService::WriteBookmarkProperties(nsIRDFDataSource *ds,
{
if (isFirst == PR_FALSE)
{
rv |= strm->Write(kSpace, sizeof(kSpace)-1, &dummy);
rv |= strm->Write(kSpaceStr, sizeof(kSpaceStr)-1, &dummy);
}
if (property == kNC_Description)
@ -5487,7 +5378,7 @@ nsBookmarksService::WriteBookmarkProperties(nsIRDFDataSource *ds,
{
rv |= strm->Write(htmlAttrib, strlen(htmlAttrib), &dummy);
rv |= strm->Write(attribute, strlen(attribute), &dummy);
rv |= strm->Write(kQuote, sizeof(kQuote)-1, &dummy);
rv |= strm->Write(kQuoteStr, sizeof(kQuoteStr)-1, &dummy);
}
nsCRT::free(attribute);
attribute = nsnull;
@ -5508,7 +5399,7 @@ nsBookmarksService::CanAccept(nsIRDFResource* aSource,
nsresult rv;
PRBool isBookmarkedFlag = PR_FALSE, canAcceptFlag = PR_FALSE, isOrdinal;
if (NS_SUCCEEDED(rv = IsBookmarkedInternal(aSource, &isBookmarkedFlag)) &&
if (NS_SUCCEEDED(rv = IsBookmarkedResource(aSource, &isBookmarkedFlag)) &&
(isBookmarkedFlag == PR_TRUE) &&
(NS_SUCCEEDED(rv = gRDFC->IsOrdinalProperty(aProperty, &isOrdinal))))
{
@ -5548,7 +5439,6 @@ nsBookmarksService::OnAssert(nsIRDFDataSource* aDataSource,
{
if (mUpdateBatchNest != 0) return NS_OK;
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; ++i)
{
@ -5628,12 +5518,9 @@ nsBookmarksService::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource)
NS_IMETHODIMP
nsBookmarksService::OnEndUpdateBatch(nsIRDFDataSource* aDataSource)
{
if (mUpdateBatchNest > 0)
{
--mUpdateBatchNest;
}
NS_ASSERTION(mUpdateBatchNest > 0, "badly nested update batch");
if (mUpdateBatchNest == 0)
if (--mUpdateBatchNest == 0)
{
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; ++i) {