Back to index

lightning-sunbird  0.9+nobinonly
nsBindingManager.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Original Author: David W. Hyatt (hyatt@netscape.com)
00024  *   Alec Flett <alecf@netscape.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #ifndef nsBindingManager_h_
00041 #define nsBindingManager_h_
00042 
00043 #include "nsIBindingManager.h"
00044 #include "nsIStyleRuleSupplier.h"
00045 #include "nsStubDocumentObserver.h"
00046 #include "pldhash.h"
00047 #include "nsInterfaceHashtable.h"
00048 #include "nsRefPtrHashtable.h"
00049 #include "nsURIHashKey.h"
00050 #include "plevent.h"
00051 
00052 class nsIContent;
00053 class nsIXPConnectWrappedJS;
00054 class nsIAtom;
00055 class nsIDOMNodeList;
00056 class nsVoidArray;
00057 class nsIDocument;
00058 class nsIURI;
00059 class nsIXBLDocumentInfo;
00060 class nsIStreamListener;
00061 class nsStyleSet;
00062 
00063 class nsBindingManager : public nsIBindingManager,
00064                          public nsIStyleRuleSupplier,
00065                          public nsStubDocumentObserver
00066 {
00067   NS_DECL_ISUPPORTS
00068 
00069 public:
00070   nsBindingManager(nsIDocument* aDocument);
00071   ~nsBindingManager();
00072 
00073   virtual nsXBLBinding* GetBinding(nsIContent* aContent);
00074   NS_IMETHOD SetBinding(nsIContent* aContent, nsXBLBinding* aBinding);
00075 
00076   NS_IMETHOD GetInsertionParent(nsIContent* aContent, nsIContent** aResult);
00077   NS_IMETHOD SetInsertionParent(nsIContent* aContent, nsIContent* aResult);
00078 
00079   NS_IMETHOD GetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS** aResult);
00080   NS_IMETHOD SetWrappedJS(nsIContent* aContent, nsIXPConnectWrappedJS* aResult);
00081 
00082   NS_IMETHOD ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument,
00083                                nsIDocument* aNewDocument);
00084 
00085   NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult);
00086 
00087   NS_IMETHOD GetContentListFor(nsIContent* aContent, nsIDOMNodeList** aResult);
00088   NS_IMETHOD SetContentListFor(nsIContent* aContent, nsVoidArray* aList);
00089   NS_IMETHOD HasContentListFor(nsIContent* aContent, PRBool* aResult);
00090 
00091   NS_IMETHOD GetAnonymousNodesFor(nsIContent* aContent, nsIDOMNodeList** aResult);
00092   NS_IMETHOD SetAnonymousNodesFor(nsIContent* aContent, nsVoidArray* aList);
00093 
00094   NS_IMETHOD GetXBLChildNodesFor(nsIContent* aContent, nsIDOMNodeList** aResult);
00095 
00096   virtual nsIContent* GetInsertionPoint(nsIContent* aParent,
00097                                         nsIContent* aChild, PRUint32* aIndex);
00098   virtual nsIContent* GetSingleInsertionPoint(nsIContent* aParent,
00099                                               PRUint32* aIndex,  
00100                                               PRBool* aMultipleInsertionPoints);
00101 
00102   NS_IMETHOD AddLayeredBinding(nsIContent* aContent, nsIURI* aURL);
00103   NS_IMETHOD RemoveLayeredBinding(nsIContent* aContent, nsIURI* aURL);
00104   NS_IMETHOD LoadBindingDocument(nsIDocument* aBoundDoc, nsIURI* aURL,
00105                                  nsIDocument** aResult);
00106 
00107   NS_IMETHOD AddToAttachedQueue(nsXBLBinding* aBinding);
00108   NS_IMETHOD ClearAttachedQueue();
00109   NS_IMETHOD ProcessAttachedQueue();
00110 
00111   NS_IMETHOD ExecuteDetachedHandlers();
00112 
00113   NS_IMETHOD PutXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
00114   NS_IMETHOD GetXBLDocumentInfo(nsIURI* aURI, nsIXBLDocumentInfo** aResult);
00115   NS_IMETHOD RemoveXBLDocumentInfo(nsIXBLDocumentInfo* aDocumentInfo);
00116 
00117   NS_IMETHOD PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener);
00118   NS_IMETHOD GetLoadingDocListener(nsIURI* aURL, nsIStreamListener** aResult);
00119   NS_IMETHOD RemoveLoadingDocListener(nsIURI* aURL);
00120 
00121   NS_IMETHOD FlushSkinBindings();
00122 
00123   NS_IMETHOD GetBindingImplementation(nsIContent* aContent, REFNSIID aIID, void** aResult);
00124 
00125   NS_IMETHOD ShouldBuildChildFrames(nsIContent* aContent, PRBool* aResult);
00126 
00127   // nsIStyleRuleSupplier
00128   NS_IMETHOD WalkRules(nsStyleSet* aStyleSet, 
00129                        nsIStyleRuleProcessor::EnumFunc aFunc,
00130                        RuleProcessorData* aData,
00131                        PRBool* aCutOffInheritance);
00132 
00133   // nsIDocumentObserver
00134   virtual void ContentAppended(nsIDocument* aDocument,
00135                                nsIContent* aContainer,
00136                                PRInt32     aNewIndexInContainer);
00137   virtual void ContentInserted(nsIDocument* aDocument,
00138                                nsIContent* aContainer,
00139                                nsIContent* aChild,
00140                                PRInt32 aIndexInContainer);
00141   virtual void ContentRemoved(nsIDocument* aDocument,
00142                               nsIContent* aContainer,
00143                               nsIContent* aChild,
00144                               PRInt32 aIndexInContainer);
00145   virtual void DocumentWillBeDestroyed(nsIDocument* aDocument);
00146 
00147   struct ProcessAttachedQueueEvent;
00148   friend struct ProcessAttachedQueueEvent;
00149 
00150   struct ProcessAttachedQueueEvent : public PLEvent {
00151     ProcessAttachedQueueEvent(nsBindingManager* aBindingManager);
00152     ~ProcessAttachedQueueEvent();
00153 
00154     void HandleEvent() {
00155       mBindingManager->DoProcessAttachedQueue();
00156     }
00157 
00158     nsRefPtr<nsBindingManager> mBindingManager;
00159   };
00160 
00161   // Notify the binding manager when an outermost update begins and
00162   // ends.  The end method can execute script.
00163   void BeginOutermostUpdate();
00164   void EndOutermostUpdate();
00165 
00166 protected:
00167   nsresult GetXBLChildNodesInternal(nsIContent* aContent,
00168                                     nsIDOMNodeList** aResult,
00169                                     PRBool* aIsAnonymousContentList);
00170   nsresult GetAnonymousNodesInternal(nsIContent* aContent,
00171                                      nsIDOMNodeList** aResult,
00172                                      PRBool* aIsAnonymousContentList);
00173 
00174   nsIContent* GetEnclosingScope(nsIContent* aContent) {
00175     return aContent->GetBindingParent();
00176   }
00177 
00178   nsresult GetNestedInsertionPoint(nsIContent* aParent, nsIContent* aChild, nsIContent** aResult);
00179 
00180   // Same as ProcessAttachedQueue, but also nulls out
00181   // mProcessAttachedQueueEvent
00182   void DoProcessAttachedQueue();
00183 
00184 // MEMBER VARIABLES
00185 protected: 
00186   // A mapping from nsIContent* to the nsXBLBinding* that is
00187   // installed on that element.
00188   nsRefPtrHashtable<nsISupportsHashKey,nsXBLBinding> mBindingTable;
00189 
00190   // A mapping from nsIContent* to an nsIDOMNodeList*
00191   // (nsAnonymousContentList*).  This list contains an accurate
00192   // reflection of our *explicit* children (once intermingled with
00193   // insertion points) in the altered DOM.
00194   PLDHashTable mContentListTable;
00195 
00196   // A mapping from nsIContent* to an nsIDOMNodeList*
00197   // (nsAnonymousContentList*).  This list contains an accurate
00198   // reflection of our *anonymous* children (if and only if they are
00199   // intermingled with insertion points) in the altered DOM.  This
00200   // table is not used if no insertion points were defined directly
00201   // underneath a <content> tag in a binding.  The NodeList from the
00202   // <content> is used instead as a performance optimization.
00203   PLDHashTable mAnonymousNodesTable;
00204 
00205   // A mapping from nsIContent* to nsIContent*.  The insertion parent
00206   // is our one true parent in the transformed DOM.  This gives us a
00207   // more-or-less O(1) way of obtaining our transformed parent.
00208   PLDHashTable mInsertionParentTable;
00209 
00210   // A mapping from nsIContent* to nsIXPWrappedJS* (an XPConnect
00211   // wrapper for JS objects).  For XBL bindings that implement XPIDL
00212   // interfaces, and that get referred to from C++, this table caches
00213   // the XPConnect wrapper for the binding.  By caching it, I control
00214   // its lifetime, and I prevent a re-wrap of the same script object
00215   // (in the case where multiple bindings in an XBL inheritance chain
00216   // both implement an XPIDL interface).
00217   PLDHashTable mWrapperTable;
00218 
00219   // A mapping from a URL (a string) to nsIXBLDocumentInfo*.  This table
00220   // is the cache of all binding documents that have been loaded by a
00221   // given bound document.
00222   nsInterfaceHashtable<nsURIHashKey,nsIXBLDocumentInfo> mDocumentTable;
00223 
00224   // A mapping from a URL (a string) to a nsIStreamListener. This
00225   // table is the currently loading binding docs.  If they're in this
00226   // table, they have not yet finished loading.
00227   nsInterfaceHashtable<nsURIHashKey,nsIStreamListener> mLoadingDocTable;
00228 
00229   // A queue of binding attached event handlers that are awaiting execution.
00230   nsVoidArray mAttachedStack;
00231   PRPackedBool mProcessingAttachedStack;
00232   PRPackedBool mProcessOnEndUpdate;  
00233 
00234   // Our posted event to process the attached queue, if any
00235   ProcessAttachedQueueEvent* mProcessAttachedQueueEvent;
00236 
00237   // Our document.  This is a weak ref; the document owns us
00238   nsIDocument* mDocument;
00239 };
00240 
00241 PRBool PR_CALLBACK ReleaseInsertionPoint(void* aElement, void* aData);
00242 
00243 #endif