diff --git a/mozilla/browser/components/bookmarks/content/bookmarksMenu.js b/mozilla/browser/components/bookmarks/content/bookmarksMenu.js index c2070ad73fb..e7cf549291f 100644 --- a/mozilla/browser/components/bookmarks/content/bookmarksMenu.js +++ b/mozilla/browser/components/bookmarks/content/bookmarksMenu.js @@ -853,8 +853,8 @@ var BookmarksToolbarRDFObserver = }, onChange: function (aDataSource, aSource, aProperty, aOldTarget, aNewTarget) {}, onMove: function (aDataSource, aOldSource, aNewSource, aProperty, aTarget) {}, - beginUpdateBatch: function (aDataSource) {}, - endUpdateBatch: function (aDataSource) {}, + onBeginUpdateBatch: function (aDataSource) {}, + onEndUpdateBatch: function (aDataSource) {}, _overflowTimerInEffect: false, setOverflowTimeout: function (aSource, aProperty) diff --git a/mozilla/browser/components/bookmarks/content/bookmarksTree.xml b/mozilla/browser/components/bookmarks/content/bookmarksTree.xml index 51c8a17895d..92264d4f649 100644 --- a/mozilla/browser/components/bookmarks/content/bookmarksTree.xml +++ b/mozilla/browser/components/bookmarks/content/bookmarksTree.xml @@ -609,13 +609,11 @@ default: this.mOuter.saveSelection(); // 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); + //BMDS.beginUpdateBatch(); BookmarksController.doCommand(aCommand, selection, target); - //observer.endUpdateBatch(this.db); + //BMDS.endUpdateBatch(); //var firstVisibleRow = this.mOuter.treeBoxObject.getFirstVisibleRow() //this.mOuter.treeBoxObject.selection.currentIndex=-1; - //this.mOuter.tree.builder.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); @@ -678,8 +676,7 @@ //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); + //BMDS.beginUpdateBatch(); const kDSIID = Components.interfaces.nsIDragService; const kCopyAction = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK; @@ -687,9 +684,8 @@ BookmarksUtils.insertSelection("drag", selection, target); else BookmarksUtils.moveSelection ("drag", selection, target); - //observer.endUpdateBatch(this.db); + //BMDS.endUpdateBatch(); //this.mOuter.treeBoxObject.selection.currentIndex=-1; - //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); diff --git a/mozilla/browser/components/bookmarks/src/nsBookmarksService.cpp b/mozilla/browser/components/bookmarks/src/nsBookmarksService.cpp index a34077b6fcd..7fbad7b6bd6 100644 --- a/mozilla/browser/components/bookmarks/src/nsBookmarksService.cpp +++ b/mozilla/browser/components/bookmarks/src/nsBookmarksService.cpp @@ -3395,9 +3395,9 @@ nsBookmarksService::ImportSystemBookmarks(nsIRDFResource* aParentFolder) BookmarkParser parser; parser.Init(ieFavoritesFile, mInner); - BeginUpdateBatch(this); + BeginUpdateBatch(); parser.Parse(aParentFolder, kNC_Bookmark); - EndUpdateBatch(this); + EndUpdateBatch(); #endif return NS_OK; @@ -4526,9 +4526,9 @@ nsBookmarksService::ReadFavorites() { BookmarkParser parser; parser.Init(ieFavoritesFile, mInner); - BeginUpdateBatch(this); + BeginUpdateBatch(); parser.Parse(kNC_IEFavoritesRoot, kNC_IEFavorite); - EndUpdateBatch(this); + EndUpdateBatch(); nsCOMPtr ieTitleLiteral; rv = gRDF->GetLiteral(ieTitle.get(), getter_AddRefs(ieTitleLiteral)); @@ -4703,9 +4703,9 @@ nsBookmarksService::LoadBookmarks() parser.ParserFoundIEFavoritesRoot(&foundIERoot); } - BeginUpdateBatch(this); + BeginUpdateBatch(); parser.Parse(kNC_BookmarksRoot, kNC_Bookmark); - EndUpdateBatch(this); + EndUpdateBatch(); mBookmarksAvailable = PR_TRUE; PRBool foundPTFolder = PR_FALSE; @@ -5536,13 +5536,13 @@ nsBookmarksService::OnMove(nsIRDFDataSource* aDataSource, } NS_IMETHODIMP -nsBookmarksService::BeginUpdateBatch(nsIRDFDataSource* aDataSource) +nsBookmarksService::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource) { if (mUpdateBatchNest++ == 0) { PRInt32 count = mObservers.Count(); for (PRInt32 i = 0; i < count; ++i) { - (void) mObservers[i]->BeginUpdateBatch(aDataSource); + (void) mObservers[i]->OnBeginUpdateBatch(this); } } @@ -5550,7 +5550,7 @@ nsBookmarksService::BeginUpdateBatch(nsIRDFDataSource* aDataSource) } NS_IMETHODIMP -nsBookmarksService::EndUpdateBatch(nsIRDFDataSource* aDataSource) +nsBookmarksService::OnEndUpdateBatch(nsIRDFDataSource* aDataSource) { if (mUpdateBatchNest > 0) { @@ -5561,7 +5561,7 @@ nsBookmarksService::EndUpdateBatch(nsIRDFDataSource* aDataSource) { PRInt32 count = mObservers.Count(); for (PRInt32 i = 0; i < count; ++i) { - (void) mObservers[i]->EndUpdateBatch(aDataSource); + (void) mObservers[i]->OnEndUpdateBatch(this); } } diff --git a/mozilla/browser/components/bookmarks/src/nsBookmarksService.h b/mozilla/browser/components/bookmarks/src/nsBookmarksService.h index 61eecde97e0..dadc7254ac5 100644 --- a/mozilla/browser/components/bookmarks/src/nsBookmarksService.h +++ b/mozilla/browser/components/bookmarks/src/nsBookmarksService.h @@ -286,6 +286,14 @@ public: nsIRDFResource* aCommand, nsISupportsArray/**/* aArguments); + NS_IMETHOD BeginUpdateBatch() { + return mInner->BeginUpdateBatch(); + } + + NS_IMETHOD EndUpdateBatch() { + return mInner->EndUpdateBatch(); + } + // nsIRDFRemoteDataSource NS_DECL_NSIRDFREMOTEDATASOURCE diff --git a/mozilla/browser/components/downloads/content/downloadPanel.js b/mozilla/browser/components/downloads/content/downloadPanel.js index 3ba0584cfcd..f4ace75a929 100644 --- a/mozilla/browser/components/downloads/content/downloadPanel.js +++ b/mozilla/browser/components/downloads/content/downloadPanel.js @@ -166,19 +166,13 @@ var downloadViewController = { gDownloadManager.startBatchUpdate(); // Notify the datasource that we're about to begin a batch operation - var observer = gDownloadHistoryView.builder.QueryInterface(Components.interfaces.nsIRDFObserver); - var ds = gDownloadHistoryView.database; - observer.beginUpdateBatch(ds); - + gDownloadManager.datasource.beginUpdateBatch(); for (i = 0; i <= selectedItems.length - 1; ++i) { gDownloadManager.removeDownload(selectedItems[i].id); } + gDownloadManager.datasource.endUpdateBatch(); gDownloadManager.endBatchUpdate(); - observer.endUpdateBatch(ds); - var remote = gDownloadManager.datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource); - remote.Flush(); - gDownloadHistoryView.builder.rebuild(); var rowCount = gDownloadHistoryView.getRowCount(); if (selectedIndex > ( rowCount- 1)) selectedIndex = rowCount - 1; diff --git a/mozilla/browser/components/downloads/src/nsDownloadManager.cpp b/mozilla/browser/components/downloads/src/nsDownloadManager.cpp index 79c7a1be8b4..ca58595ba81 100644 --- a/mozilla/browser/components/downloads/src/nsDownloadManager.cpp +++ b/mozilla/browser/components/downloads/src/nsDownloadManager.cpp @@ -679,8 +679,12 @@ nsDownloadManager::StartBatchUpdate() NS_IMETHODIMP nsDownloadManager::EndBatchUpdate() { - --mBatches; - return NS_OK; + nsresult rv = NS_OK; + if (--mBatches == 0) { + nsCOMPtr remote = do_QueryInterface(mDataSource); + rv = remote->Flush(); + } + return rv; } NS_IMETHODIMP diff --git a/mozilla/browser/components/prefwindow/content/pref-privacy.js b/mozilla/browser/components/prefwindow/content/pref-privacy.js index a1b696425c3..6d765ae92a2 100644 --- a/mozilla/browser/components/prefwindow/content/pref-privacy.js +++ b/mozilla/browser/components/prefwindow/content/pref-privacy.js @@ -216,10 +216,6 @@ var PrivacyPanel = { } dlMgr.endBatchUpdate(); - var rds = ds.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource); - if (rds) - rds.Flush(); - return true; }, diff --git a/mozilla/browser/components/search/resources/content/search-panel.js b/mozilla/browser/components/search/resources/content/search-panel.js index d69c5f8bc8f..13b45646b95 100644 --- a/mozilla/browser/components/search/resources/content/search-panel.js +++ b/mozilla/browser/components/search/resources/content/search-panel.js @@ -110,11 +110,11 @@ var RDF_observer = { }, - beginUpdateBatch : function(ds) + onBeginUpdateBatch : function(ds) { }, - endUpdateBatch : function(ds) + onEndUpdateBatch : function(ds) { } } diff --git a/mozilla/chrome/src/nsChromeUIDataSource.cpp b/mozilla/chrome/src/nsChromeUIDataSource.cpp index 1959d3a3f33..f5c60eca30a 100644 --- a/mozilla/chrome/src/nsChromeUIDataSource.cpp +++ b/mozilla/chrome/src/nsChromeUIDataSource.cpp @@ -287,6 +287,16 @@ nsChromeUIDataSource::DoCommand(nsISupportsArray/**/* aSources, return mComposite->DoCommand(aSources, aCommand, aArguments); } +NS_IMETHODIMP +nsChromeUIDataSource::BeginUpdateBatch() { + return mComposite->BeginUpdateBatch(); +} + +NS_IMETHODIMP +nsChromeUIDataSource::EndUpdateBatch() { + return mComposite->EndUpdateBatch(); +} + ////////////////////////////////////////////////////////////////////// NS_IMETHODIMP @@ -299,7 +309,6 @@ nsChromeUIDataSource::OnAssert(nsIRDFDataSource* aDataSource, for (PRInt32 i = count - 1; i >= 0; --i) { mObservers[i]->OnAssert(this, aSource, aProperty, aTarget); - // XXX ignore return value? } return NS_OK; } @@ -313,7 +322,6 @@ nsChromeUIDataSource::OnUnassert(nsIRDFDataSource* aDataSource, PRInt32 count = mObservers.Count(); for (PRInt32 i = count - 1; i >= 0; --i) { mObservers[i]->OnUnassert(aDataSource, aSource, aProperty, aTarget); - // XXX ignore return value? } return NS_OK; } @@ -330,7 +338,6 @@ nsChromeUIDataSource::OnChange(nsIRDFDataSource* aDataSource, for (PRInt32 i = count - 1; i >= 0; --i) { mObservers[i]->OnChange(aDataSource, aSource, aProperty, aOldTarget, aNewTarget); - // XXX ignore return value? } return NS_OK; } @@ -347,20 +354,29 @@ nsChromeUIDataSource::OnMove(nsIRDFDataSource* aDataSource, for (PRInt32 i = count - 1; i >= 0; --i) { mObservers[i]->OnMove(aDataSource, aOldSource, aNewSource, aProperty, aTarget); - // XXX ignore return value? } return NS_OK; } NS_IMETHODIMP -nsChromeUIDataSource::BeginUpdateBatch(nsIRDFDataSource* aDataSource) +nsChromeUIDataSource::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource) { + PRInt32 count = mObservers.Count(); + + for (PRInt32 i = count - 1; i >= 0; --i) { + mObservers[i]->OnBeginUpdateBatch(aDataSource); + } return NS_OK; } NS_IMETHODIMP -nsChromeUIDataSource::EndUpdateBatch(nsIRDFDataSource* aDataSource) +nsChromeUIDataSource::OnEndUpdateBatch(nsIRDFDataSource* aDataSource) { + PRInt32 count = mObservers.Count(); + + for (PRInt32 i = count - 1; i >= 0; --i) { + mObservers[i]->OnEndUpdateBatch(aDataSource); + } return NS_OK; } diff --git a/mozilla/content/shared/public/nsXULAtomList.h b/mozilla/content/shared/public/nsXULAtomList.h index e99bff267d6..50c24890c0d 100644 --- a/mozilla/content/shared/public/nsXULAtomList.h +++ b/mozilla/content/shared/public/nsXULAtomList.h @@ -290,6 +290,7 @@ XUL_ATOM(dir, "dir") XUL_ATOM(properties, "properties") XUL_ATOM(resource, "resource") XUL_ATOM(sort, "sort") +XUL_ATOM(sortLocked, "sortLocked") XUL_ATOM(sortDirection, "sortDirection") XUL_ATOM(sortActive, "sortActive") XUL_ATOM(sortResource, "sortResource") diff --git a/mozilla/content/xul/templates/public/MANIFEST_IDL b/mozilla/content/xul/templates/public/MANIFEST_IDL index 14e6445dbe2..2da6d05fed0 100644 --- a/mozilla/content/xul/templates/public/MANIFEST_IDL +++ b/mozilla/content/xul/templates/public/MANIFEST_IDL @@ -1,2 +1,3 @@ nsIXULSortService.idl nsIXULTemplateBuilder.idl +nsIXULBuilderListener.idl diff --git a/mozilla/content/xul/templates/public/Makefile.in b/mozilla/content/xul/templates/public/Makefile.in index 1ec994762a4..28f854e340a 100644 --- a/mozilla/content/xul/templates/public/Makefile.in +++ b/mozilla/content/xul/templates/public/Makefile.in @@ -31,6 +31,7 @@ MODULE = xultmpl XPIDLSRCS = \ nsIXULSortService.idl \ nsIXULTemplateBuilder.idl \ + nsIXULBuilderListener.idl \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/mozilla/content/xul/templates/public/nsIXULBuilderListener.idl b/mozilla/content/xul/templates/public/nsIXULBuilderListener.idl new file mode 100644 index 00000000000..bddd936c236 --- /dev/null +++ b/mozilla/content/xul/templates/public/nsIXULBuilderListener.idl @@ -0,0 +1,61 @@ +/* -*- Mode: idl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** 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 Corp. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Jan Varga + * + * Alternatively, the contents of this file may be used under the terms of + * either 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 ***** */ + + +#include "nsISupports.idl" + +interface nsIXULTemplateBuilder; + +// An nsIXULBuilderListener object is a listener that will be notified +// when a template builder rebuilds its content. +[scriptable, uuid(ac46be8f-c863-4c23-84a2-d0fcc8dfa9f4)] +interface nsIXULBuilderListener: nsISupports { + + /** + * Called before a template builder rebuilds its content. + * @param aBuilder the template builder that rebuilds the content. + */ + void willRebuild(in nsIXULTemplateBuilder aBuilder); + + /** + * Called after a template builder has rebuilt its content. + * @param aBuilder the template builder that has rebuilt the content. + */ + void didRebuild(in nsIXULTemplateBuilder aBuilder); + +}; diff --git a/mozilla/content/xul/templates/public/nsIXULTemplateBuilder.idl b/mozilla/content/xul/templates/public/nsIXULTemplateBuilder.idl index 3244b1a77a4..8dc965fae76 100644 --- a/mozilla/content/xul/templates/public/nsIXULTemplateBuilder.idl +++ b/mozilla/content/xul/templates/public/nsIXULTemplateBuilder.idl @@ -22,6 +22,7 @@ * Contributor(s): * Chris Waterson * Ben Goodger + * Jan Varga * * * Alternatively, the contents of this file may be used under the terms of @@ -43,6 +44,8 @@ #include "nsIRDFCompositeDataSource.idl" #include "nsIRDFResource.idl" +interface nsIXULBuilderListener; + [ptr] native nsIContent_ptr(nsIContent); [scriptable, uuid(fb744f8e-1dd1-11b2-a5d7-935c9ab60602)] @@ -77,6 +80,17 @@ interface nsIXULTemplateBuilder : nsISupports * built. */ [noscript] void createContents(in nsIContent_ptr aElement); + + /** + * Add a listener to this template builder. The template builder + * holds a strong reference to the listener. + */ + void addListener(in nsIXULBuilderListener aListener); + + /** + * Remove a listener from this template builder. + */ + void removeListener(in nsIXULBuilderListener aListener); }; /** diff --git a/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp b/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp index 7b891c15e61..e471c793504 100644 --- a/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp +++ b/mozilla/content/xul/templates/src/nsXULContentBuilder.cpp @@ -130,7 +130,6 @@ class nsXULContentBuilder : public nsXULTemplateBuilder { public: // nsIXULTemplateBuilder interface - NS_IMETHOD Rebuild(); NS_IMETHOD CreateContents(nsIContent* aElement); // nsIDocumentObserver interface @@ -243,6 +242,9 @@ protected: virtual nsresult InitializeRuleNetworkForSimpleRules(InnerNode** aChildNode); + virtual nsresult + RebuildAll(); + virtual nsresult CompileCondition(nsIAtom* aTag, nsTemplateRule* aRule, @@ -288,9 +290,6 @@ protected: */ nsRDFSortState sortState; - nsresult - Rebuild(nsIContent* aElement); - virtual nsresult ReplaceMatch(nsIRDFResource* aMember, const nsTemplateMatch* aOldMatch, nsTemplateMatch* aNewMatch); @@ -1671,77 +1670,6 @@ nsXULContentBuilder::GetElementFactory(PRInt32 aNameSpaceID, nsIElementFactory** // nsIXULTemplateBuilder methods // -nsresult -nsXULContentBuilder::Rebuild(nsIContent* aElement) -{ - NS_PRECONDITION(aElement != nsnull, "null ptr"); - if (! aElement) - return NS_ERROR_NULL_POINTER; - - nsresult rv; - - // Next, see if it's a XUL element whose contents have never even - // been generated. If so, short-circuit and bail; there's nothing - // for us to "rebuild" yet. They'll get built correctly the next - // time somebody asks for them. - nsCOMPtr xulcontent = do_QueryInterface(aElement); - - if (xulcontent) { - PRBool containerContentsBuilt = PR_FALSE; - xulcontent->GetLazyState(nsIXULContent::eContainerContentsBuilt, containerContentsBuilt); - - if (! containerContentsBuilt) - return NS_OK; - } - - // If we get here, then we've tried to generate content for this - // element. Remove it. - rv = RemoveGeneratedContent(aElement); - if (NS_FAILED(rv)) return rv; - - if (aElement == mRoot) { - // Nuke the content support map and conflict set completely. - mContentSupportMap.Clear(); - mTemplateMap.Clear(); - mConflictSet.Clear(); - - rv = CompileRules(); - if (NS_FAILED(rv)) return rv; - } - - // Forces the XUL element to remember that it needs to - // re-generate its children next time around. - if (xulcontent) { - xulcontent->SetLazyState(nsIXULContent::eChildrenMustBeRebuilt); - xulcontent->ClearLazyState(nsIXULContent::eTemplateContentsBuilt); - xulcontent->ClearLazyState(nsIXULContent::eContainerContentsBuilt); - } - - // Now, regenerate both the template- and container-generated - // contents for the current element... - nsCOMPtr container; - PRInt32 newIndex; - CreateTemplateAndContainerContents(aElement, getter_AddRefs(container), &newIndex); - - if (container) { - nsCOMPtr doc; - mRoot->GetDocument(*getter_AddRefs(doc)); - NS_ASSERTION(doc != nsnull, "root element has no document"); - if (! doc) - return NS_ERROR_UNEXPECTED; - - doc->ContentAppended(container, newIndex); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsXULContentBuilder::Rebuild() -{ - return Rebuild(mRoot); -} - NS_IMETHODIMP nsXULContentBuilder::CreateContents(nsIContent* aElement) { @@ -2078,6 +2006,75 @@ nsXULContentBuilder::InitializeRuleNetworkForSimpleRules(InnerNode** aChildNode) return NS_OK; } +nsresult +nsXULContentBuilder::RebuildAll() +{ + NS_PRECONDITION(mRoot != nsnull, "not initialized"); + if (! mRoot) + return NS_ERROR_NOT_INITIALIZED; + + nsCOMPtr doc; + nsresult rv = mRoot->GetDocument(*getter_AddRefs(doc)); + if (NS_FAILED(rv)) return rv; + + // Bail out early if we are being torn down. + if (!doc) + return NS_OK; + + // See if it's a XUL element whose contents have never even + // been generated. If so, short-circuit and bail; there's nothing + // for us to "rebuild" yet. They'll get built correctly the next + // time somebody asks for them. + nsCOMPtr xulcontent = do_QueryInterface(mRoot); + + if (xulcontent) { + PRBool containerContentsBuilt = PR_FALSE; + xulcontent->GetLazyState(nsIXULContent::eContainerContentsBuilt, containerContentsBuilt); + + if (! containerContentsBuilt) + return NS_OK; + } + + // If we get here, then we've tried to generate content for this + // element. Remove it. + rv = RemoveGeneratedContent(mRoot); + if (NS_FAILED(rv)) return rv; + + // Nuke the content support map and conflict set completely. + mContentSupportMap.Clear(); + mTemplateMap.Clear(); + mConflictSet.Clear(); + + rv = CompileRules(); + if (NS_FAILED(rv)) return rv; + + // Forces the XUL element to remember that it needs to + // re-generate its children next time around. + if (xulcontent) { + xulcontent->SetLazyState(nsIXULContent::eChildrenMustBeRebuilt); + xulcontent->ClearLazyState(nsIXULContent::eTemplateContentsBuilt); + xulcontent->ClearLazyState(nsIXULContent::eContainerContentsBuilt); + } + + // Now, regenerate both the template- and container-generated + // contents for the current element... + nsCOMPtr container; + PRInt32 newIndex; + CreateTemplateAndContainerContents(mRoot, getter_AddRefs(container), &newIndex); + + if (container) { + nsCOMPtr doc; + mRoot->GetDocument(*getter_AddRefs(doc)); + NS_ASSERTION(doc != nsnull, "root element has no document"); + if (! doc) + return NS_ERROR_UNEXPECTED; + + doc->ContentAppended(container, newIndex); + } + + return NS_OK; +} + nsresult nsXULContentBuilder::CompileCondition(nsIAtom* aTag, nsTemplateRule* aRule, diff --git a/mozilla/content/xul/templates/src/nsXULContentUtils.cpp b/mozilla/content/xul/templates/src/nsXULContentUtils.cpp index 9fb9f95c89a..475b6f061c6 100644 --- a/mozilla/content/xul/templates/src/nsXULContentUtils.cpp +++ b/mozilla/content/xul/templates/src/nsXULContentUtils.cpp @@ -226,6 +226,7 @@ nsXULContentUtils::GetElementResource(nsIContent* aElement, nsIRDFResource** aRe nsresult nsXULContentUtils::GetElementRefResource(nsIContent* aElement, nsIRDFResource** aResult) { + *aResult = nsnull; // Perform a reverse mapping from an element in the content model // to an RDF resource. Check for a "ref" attribute first, then // fallback on an "id" attribute. diff --git a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp index 96393e8c531..2445c78a845 100644 --- a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp +++ b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.cpp @@ -81,6 +81,7 @@ #include "nsIRDFContainerUtils.h" #include "nsIXULDocument.h" #include "nsIXULTemplateBuilder.h" +#include "nsIXULBuilderListener.h" #include "nsIRDFNode.h" #include "nsIRDFObserver.h" #include "nsIRDFRemoteDataSource.h" @@ -151,7 +152,6 @@ PRLogModuleInfo* gXULTemplateLog; nsXULTemplateBuilder::nsXULTemplateBuilder(void) : mDB(nsnull), mRoot(nsnull), - mTimer(nsnull), mUpdateBatchNest(0), mRulesCompiled(PR_FALSE), mFlags(0), @@ -227,6 +227,22 @@ nsXULTemplateBuilder::GetDatabase(nsIRDFCompositeDataSource** aResult) return NS_OK; } +NS_IMETHODIMP +nsXULTemplateBuilder::Rebuild() +{ + for (PRInt32 i = mListeners.Count() - 1; i >= 0; --i) { + mListeners[i]->WillRebuild(this); + } + + nsresult rv = RebuildAll(); + + for (PRInt32 i = mListeners.Count() - 1; i >= 0; --i) { + mListeners[i]->DidRebuild(this); + } + + return rv; +} + NS_IMETHODIMP nsXULTemplateBuilder::Init(nsIContent* aElement) { @@ -241,6 +257,26 @@ nsXULTemplateBuilder::CreateContents(nsIContent* aElement) return NS_OK; } +NS_IMETHODIMP +nsXULTemplateBuilder::AddListener(nsIXULBuilderListener* aListener) +{ + NS_ENSURE_ARG(aListener); + + mListeners.AppendObject(aListener); + + return NS_OK; +} + +NS_IMETHODIMP +nsXULTemplateBuilder::RemoveListener(nsIXULBuilderListener* aListener) +{ + NS_ENSURE_ARG(aListener); + + mListeners.RemoveObject(aListener); + + return NS_OK; +} + //---------------------------------------------------------------------- // // nsIDocumentOberver interface @@ -613,7 +649,7 @@ nsXULTemplateBuilder::OnMove(nsIRDFDataSource* aDataSource, NS_IMETHODIMP -nsXULTemplateBuilder::BeginUpdateBatch(nsIRDFDataSource* aDataSource) +nsXULTemplateBuilder::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource) { mUpdateBatchNest++; return NS_OK; @@ -621,10 +657,12 @@ nsXULTemplateBuilder::BeginUpdateBatch(nsIRDFDataSource* aDataSource) NS_IMETHODIMP -nsXULTemplateBuilder::EndUpdateBatch(nsIRDFDataSource* aDataSource) +nsXULTemplateBuilder::OnEndUpdateBatch(nsIRDFDataSource* aDataSource) { - if (mUpdateBatchNest > 0) - --mUpdateBatchNest; + NS_ASSERTION(mUpdateBatchNest > 0, "badly nested update batch"); + if (--mUpdateBatchNest == 0) { + Rebuild(); + } return NS_OK; } diff --git a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.h b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.h index dd200481cf7..d5ac0bd8d18 100644 --- a/mozilla/content/xul/templates/src/nsXULTemplateBuilder.h +++ b/mozilla/content/xul/templates/src/nsXULTemplateBuilder.h @@ -52,7 +52,6 @@ #include "nsIRDFDataSource.h" #include "nsIRDFObserver.h" #include "nsIRDFService.h" -#include "nsITimer.h" #include "nsIXULTemplateBuilder.h" #include "nsConflictSet.h" @@ -60,6 +59,7 @@ #include "nsResourceSet.h" #include "nsRuleNetwork.h" #include "nsVoidArray.h" +#include "nsCOMArray.h" #include "prlog.h" #ifdef PR_LOGGING @@ -91,12 +91,8 @@ public: NS_DECL_ISUPPORTS // nsIXULTemplateBuilder interface - NS_IMETHOD GetRoot(nsIDOMElement** aResult); - NS_IMETHOD GetDatabase(nsIRDFCompositeDataSource** aResult); - NS_IMETHOD Rebuild() = 0; // must be implemented by subclasses - NS_IMETHOD Init(nsIContent* aElement); - NS_IMETHOD CreateContents(nsIContent* aElement); - + NS_DECL_NSIXULTEMPLATEBUILDER + // nsISecurityCheckedComponent NS_DECL_NSISECURITYCHECKEDCOMPONENT @@ -125,6 +121,9 @@ public: virtual nsresult InitializeRuleNetworkForSimpleRules(InnerNode** aChildNode) = 0; + virtual nsresult + RebuildAll() = 0; // must be implemented by subclasses + /** * Find the - - + + - + -