LCOV - app.info - content/xbl/src/nsXBLBinding.cpp

LCOV - code coverage report
| Current view: | directory - content/xbl/src - nsXBLBinding.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 677 | 2 | 0.3 %
| Date: | 2012-06-02 | Functions: | 49 | 2 | 4.1 %

           1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
           2                 : /* ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is Mozilla Communicator client code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * Netscape Communications Corporation.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *   Brendan Eich (brendan@mozilla.org)
          24                 :  *   Scott MacGregor (mscott@netscape.com)
          25                 :  *
          26                 :  * Alternatively, the contents of this file may be used under the terms of
          27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          30                 :  * of those above. If you wish to allow use of your version of this file only
          31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          32                 :  * use your version of this file under the terms of the MPL, indicate your
          33                 :  * decision by deleting the provisions above and replace them with the notice
          34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          35                 :  * the provisions above, a recipient may use your version of this file under
          36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          37                 :  *
          38                 :  * ***** END LICENSE BLOCK ***** */
          39                 :
          40                 : #include "nsCOMPtr.h"
          41                 : #include "nsIAtom.h"
          42                 : #include "nsXBLDocumentInfo.h"
          43                 : #include "nsIInputStream.h"
          44                 : #include "nsINameSpaceManager.h"
          45                 : #include "nsHashtable.h"
          46                 : #include "nsIURI.h"
          47                 : #include "nsIURL.h"
          48                 : #include "nsIDOMEventTarget.h"
          49                 : #include "nsIChannel.h"
          50                 : #include "nsXPIDLString.h"
          51                 : #include "nsReadableUtils.h"
          52                 : #include "nsIParser.h"
          53                 : #include "nsParserCIID.h"
          54                 : #include "nsNetUtil.h"
          55                 : #include "plstr.h"
          56                 : #include "nsIContent.h"
          57                 : #include "nsIDocument.h"
          58                 : #include "nsContentUtils.h"
          59                 : #ifdef MOZ_XUL
          60                 : #include "nsIXULDocument.h"
          61                 : #endif
          62                 : #include "nsIXMLContentSink.h"
          63                 : #include "nsContentCID.h"
          64                 : #include "nsXMLDocument.h"
          65                 : #include "jsapi.h"
          66                 : #include "nsXBLService.h"
          67                 : #include "nsXBLInsertionPoint.h"
          68                 : #include "nsIXPConnect.h"
          69                 : #include "nsIScriptContext.h"
          70                 : #include "nsCRT.h"
          71                 :
          72                 : // Event listeners
          73                 : #include "nsEventListenerManager.h"
          74                 : #include "nsIDOMEventListener.h"
          75                 : #include "nsAttrName.h"
          76                 :
          77                 : #include "nsGkAtoms.h"
          78                 :
          79                 : #include "nsIDOMAttr.h"
          80                 : #include "nsIDOMNamedNodeMap.h"
          81                 :
          82                 : #include "nsXBLPrototypeHandler.h"
          83                 :
          84                 : #include "nsXBLPrototypeBinding.h"
          85                 : #include "nsXBLBinding.h"
          86                 : #include "nsIPrincipal.h"
          87                 : #include "nsIScriptSecurityManager.h"
          88                 : #include "nsEventListenerManager.h"
          89                 : #include "nsGUIEvent.h"
          90                 :
          91                 : #include "prprf.h"
          92                 : #include "nsNodeUtils.h"
          93                 :
          94                 : // Nasty hack.  Maybe we could move some of the classinfo utility methods
          95                 : // (e.g. WrapNative and ThrowJSException) over to nsContentUtils?
          96                 : #include "nsDOMClassInfo.h"
          97                 : #include "nsJSUtils.h"
          98                 :
          99                 : #include "mozilla/dom/Element.h"
         100                 :
         101                 : // Helper classes
         102                 :
         103                 : /***********************************************************************/
         104                 : //
         105                 : // The JS class for XBLBinding
         106                 : //
         107                 : static void
         108               0 : XBLFinalize(JSContext *cx, JSObject *obj)
         109                 : {
         110                 :   nsXBLDocumentInfo* docInfo =
         111               0 :     static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(obj));
         112               0 :   NS_RELEASE(docInfo);
         113                 :
         114               0 :   nsXBLJSClass* c = static_cast<nsXBLJSClass*>(::JS_GetClass(obj));
         115               0 :   c->Drop();
         116               0 : }
         117                 :
         118                 : static JSBool
         119               0 : XBLResolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
         120                 :            JSObject **objp)
         121                 : {
         122                 :   // Note: if we get here, that means that the implementation for some binding
         123                 :   // was installed, which means that AllowScripts() tested true.  Hence no need
         124                 :   // to do checks like that here.
         125                 :
         126                 :   // Default to not resolving things.
         127               0 :   NS_ASSERTION(*objp, "Must have starting object");
         128                 :
         129               0 :   JSObject* origObj = *objp;
         130               0 :   *objp = NULL;
         131                 :
         132               0 :   if (!JSID_IS_STRING(id)) {
         133               0 :     return JS_TRUE;
         134                 :   }
         135                 :
         136               0 :   nsDependentJSString fieldName(id);
         137                 :
         138               0 :   jsval slotVal = ::JS_GetReservedSlot(obj, 0);
         139               0 :   NS_ASSERTION(!JSVAL_IS_VOID(slotVal), "How did that happen?");
         140                 :
         141                 :   nsXBLPrototypeBinding* protoBinding =
         142               0 :     static_cast<nsXBLPrototypeBinding*>(JSVAL_TO_PRIVATE(slotVal));
         143               0 :   NS_ASSERTION(protoBinding, "Must have prototype binding!");
         144                 :
         145               0 :   nsXBLProtoImplField* field = protoBinding->FindField(fieldName);
         146               0 :   if (!field) {
         147               0 :     return JS_TRUE;
         148                 :   }
         149                 :
         150                 :   // We have this field.  Time to install it.  Get our node.
         151               0 :   JSClass* nodeClass = ::JS_GetClass(origObj);
         152               0 :   if (!nodeClass) {
         153               0 :     return JS_FALSE;
         154                 :   }
         155                 :
         156               0 :   if (~nodeClass->flags &
         157                 :       (JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) {
         158               0 :     nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_UNEXPECTED);
         159               0 :     return JS_FALSE;
         160                 :   }
         161                 :
         162                 :   nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
         163               0 :     do_QueryInterface(static_cast<nsISupports*>(::JS_GetPrivate(origObj)));
         164               0 :   if (!xpcWrapper) {
         165                 :     // Looks like whatever |origObj| is it's not our nsIContent.  It might well
         166                 :     // be the proto our binding installed, however, where the private is the
         167                 :     // nsXBLDocumentInfo, so just baul out quietly.  Do NOT throw an exception
         168                 :     // here.
         169                 :     // We could make this stricter by checking the class maybe, but whatever
         170               0 :     return JS_TRUE;
         171                 :   }
         172                 :
         173               0 :   nsCOMPtr<nsIContent> content = do_QueryWrappedNative(xpcWrapper);
         174               0 :   if (!content) {
         175               0 :     nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_UNEXPECTED);
         176               0 :     return JS_FALSE;
         177                 :   }
         178                 :
         179                 :   // This mirrors code in nsXBLProtoImpl::InstallImplementation
         180               0 :   nsIDocument* doc = content->OwnerDoc();
         181                 :
         182               0 :   nsIScriptGlobalObject* global = doc->GetScriptGlobalObject();
         183               0 :   if (!global) {
         184               0 :     return JS_TRUE;
         185                 :   }
         186                 :
         187               0 :   nsCOMPtr<nsIScriptContext> context = global->GetContext();
         188               0 :   if (!context) {
         189               0 :     return JS_TRUE;
         190                 :   }
         191                 :
         192                 :
         193                 :   // Now we either resolve or fail
         194                 :   bool didInstall;
         195                 :   nsresult rv = field->InstallField(context, origObj,
         196               0 :                                     content->NodePrincipal(),
         197                 :                                     protoBinding->DocURI(),
         198               0 :                                     &didInstall);
         199               0 :   if (NS_FAILED(rv)) {
         200               0 :     if (!::JS_IsExceptionPending(cx)) {
         201               0 :       nsDOMClassInfo::ThrowJSException(cx, rv);
         202                 :     }
         203                 :
         204               0 :     return JS_FALSE;
         205                 :   }
         206                 :
         207               0 :   if (didInstall) {
         208               0 :     *objp = origObj;
         209                 :   }
         210                 :   // else we didn't resolve this field after all
         211                 :
         212               0 :   return JS_TRUE;
         213                 : }
         214                 :
         215               0 : nsXBLJSClass::nsXBLJSClass(const nsAFlatCString& aClassName)
         216                 : {
         217               0 :   memset(this, 0, sizeof(nsXBLJSClass));
         218               0 :   next = prev = static_cast<JSCList*>(this);
         219               0 :   name = ToNewCString(aClassName);
         220                 :   flags =
         221                 :     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
         222                 :     JSCLASS_NEW_RESOLVE | JSCLASS_NEW_RESOLVE_GETS_START |
         223                 :     // Our one reserved slot holds the relevant nsXBLPrototypeBinding
         224               0 :     JSCLASS_HAS_RESERVED_SLOTS(1);
         225               0 :   addProperty = delProperty = getProperty = ::JS_PropertyStub;
         226               0 :   setProperty = ::JS_StrictPropertyStub;
         227               0 :   enumerate = ::JS_EnumerateStub;
         228               0 :   resolve = (JSResolveOp)XBLResolve;
         229               0 :   convert = ::JS_ConvertStub;
         230               0 :   finalize = XBLFinalize;
         231               0 : }
         232                 :
         233                 : nsrefcnt
         234               0 : nsXBLJSClass::Destroy()
         235                 : {
         236               0 :   NS_ASSERTION(next == prev && prev == static_cast<JSCList*>(this),
         237                 :                "referenced nsXBLJSClass is on LRU list already!?");
         238                 :
         239               0 :   if (nsXBLService::gClassTable) {
         240               0 :     nsCStringKey key(name);
         241               0 :     (nsXBLService::gClassTable)->Remove(&key);
         242                 :   }
         243                 :
         244               0 :   if (nsXBLService::gClassLRUListLength >= nsXBLService::gClassLRUListQuota) {
         245                 :     // Over LRU list quota, just unhash and delete this class.
         246               0 :     delete this;
         247                 :   } else {
         248                 :     // Put this most-recently-used class on end of the LRU-sorted freelist.
         249               0 :     JSCList* mru = static_cast<JSCList*>(this);
         250               0 :     JS_APPEND_LINK(mru, &nsXBLService::gClassLRUList);
         251               0 :     nsXBLService::gClassLRUListLength++;
         252                 :   }
         253                 :
         254               0 :   return 0;
         255                 : }
         256                 :
         257                 : // Implementation /////////////////////////////////////////////////////////////////
         258                 :
         259                 : // Constructors/Destructors
         260               0 : nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding)
         261                 :   : mPrototypeBinding(aBinding),
         262                 :     mInsertionPointTable(nsnull),
         263                 :     mIsStyleBinding(true),
         264               0 :     mMarkedForDeath(false)
         265                 : {
         266               0 :   NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!");
         267                 :   // Grab a ref to the document info so the prototype binding won't die
         268               0 :   NS_ADDREF(mPrototypeBinding->XBLDocumentInfo());
         269               0 : }
         270                 :
         271                 :
         272               0 : nsXBLBinding::~nsXBLBinding(void)
         273                 : {
         274               0 :   if (mContent) {
         275               0 :     nsXBLBinding::UninstallAnonymousContent(mContent->OwnerDoc(), mContent);
         276                 :   }
         277               0 :   delete mInsertionPointTable;
         278               0 :   nsXBLDocumentInfo* info = mPrototypeBinding->XBLDocumentInfo();
         279               0 :   NS_RELEASE(info);
         280               0 : }
         281                 :
         282                 : static PLDHashOperator
         283               0 : TraverseKey(nsISupports* aKey, nsInsertionPointList* aData, void* aClosure)
         284                 : {
         285                 :   nsCycleCollectionTraversalCallback &cb =
         286               0 :     *static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
         287                 :
         288               0 :   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mInsertionPointTable key");
         289               0 :   cb.NoteXPCOMChild(aKey);
         290               0 :   if (aData) {
         291               0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY(*aData, nsXBLInsertionPoint,
         292                 :                                                "mInsertionPointTable value")
         293                 :   }
         294               0 :   return PL_DHASH_NEXT;
         295                 : }
         296                 :
         297            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLBinding)
         298               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLBinding)
         299                 :   // XXX Probably can't unlink mPrototypeBinding->XBLDocumentInfo(), because
         300                 :   //     mPrototypeBinding is weak.
         301               0 :   if (tmp->mContent) {
         302               0 :     nsXBLBinding::UninstallAnonymousContent(tmp->mContent->OwnerDoc(),
         303               0 :                                             tmp->mContent);
         304                 :   }
         305               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContent)
         306               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNextBinding)
         307               0 :   delete tmp->mInsertionPointTable;
         308               0 :   tmp->mInsertionPointTable = nsnull;
         309               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
         310               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXBLBinding)
         311               0 :   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb,
         312                 :                                      "mPrototypeBinding->XBLDocumentInfo()");
         313                 :   cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObjectOwner*>(
         314               0 :                       tmp->mPrototypeBinding->XBLDocumentInfo()));
         315               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContent)
         316               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNextBinding, nsXBLBinding)
         317               0 :   if (tmp->mInsertionPointTable)
         318               0 :     tmp->mInsertionPointTable->EnumerateRead(TraverseKey, &cb);
         319               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
         320               0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXBLBinding, AddRef)
         321               0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXBLBinding, Release)
         322                 :
         323                 : void
         324               0 : nsXBLBinding::SetBaseBinding(nsXBLBinding* aBinding)
         325                 : {
         326               0 :   if (mNextBinding) {
         327               0 :     NS_ERROR("Base XBL binding is already defined!");
         328               0 :     return;
         329                 :   }
         330                 :
         331               0 :   mNextBinding = aBinding; // Comptr handles rel/add
         332                 : }
         333                 :
         334                 : void
         335               0 : nsXBLBinding::InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement)
         336                 : {
         337                 :   // We need to ensure two things.
         338                 :   // (1) The anonymous content should be fooled into thinking it's in the bound
         339                 :   // element's document, assuming that the bound element is in a document
         340                 :   // Note that we don't change the current doc of aAnonParent here, since that
         341                 :   // quite simply does not matter.  aAnonParent is just a way of keeping refs
         342                 :   // to all its kids, which are anonymous content from the point of view of
         343                 :   // aElement.
         344                 :   // (2) The children's parent back pointer should not be to this synthetic root
         345                 :   // but should instead point to the enclosing parent element.
         346               0 :   nsIDocument* doc = aElement->GetCurrentDoc();
         347               0 :   bool allowScripts = AllowScripts();
         348                 :
         349               0 :   nsAutoScriptBlocker scriptBlocker;
         350               0 :   for (nsIContent* child = aAnonParent->GetFirstChild();
         351                 :        child;
         352               0 :        child = child->GetNextSibling()) {
         353               0 :     child->UnbindFromTree();
         354                 :     nsresult rv =
         355               0 :       child->BindToTree(doc, aElement, mBoundElement, allowScripts);
         356               0 :     if (NS_FAILED(rv)) {
         357                 :       // Oh, well... Just give up.
         358                 :       // XXXbz This really shouldn't be a void method!
         359               0 :       child->UnbindFromTree();
         360                 :       return;
         361                 :     }
         362                 :
         363               0 :     child->SetFlags(NODE_IS_ANONYMOUS);
         364                 :
         365                 : #ifdef MOZ_XUL
         366                 :     // To make XUL templates work (and other goodies that happen when
         367                 :     // an element is added to a XUL document), we need to notify the
         368                 :     // XUL document using its special API.
         369               0 :     nsCOMPtr<nsIXULDocument> xuldoc(do_QueryInterface(doc));
         370               0 :     if (xuldoc)
         371               0 :       xuldoc->AddSubtreeToDocument(child);
         372                 : #endif
         373                 :   }
         374                 : }
         375                 :
         376                 : void
         377               0 : nsXBLBinding::UninstallAnonymousContent(nsIDocument* aDocument,
         378                 :                                         nsIContent* aAnonParent)
         379                 : {
         380               0 :   nsAutoScriptBlocker scriptBlocker;
         381                 :   // Hold a strong ref while doing this, just in case.
         382               0 :   nsCOMPtr<nsIContent> anonParent = aAnonParent;
         383                 : #ifdef MOZ_XUL
         384                 :   nsCOMPtr<nsIXULDocument> xuldoc =
         385               0 :     do_QueryInterface(aDocument);
         386                 : #endif
         387               0 :   for (nsIContent* child = aAnonParent->GetFirstChild();
         388                 :        child;
         389               0 :        child = child->GetNextSibling()) {
         390               0 :     child->UnbindFromTree();
         391                 : #ifdef MOZ_XUL
         392               0 :     if (xuldoc) {
         393               0 :       xuldoc->RemoveSubtreeFromDocument(child);
         394                 :     }
         395                 : #endif
         396                 :   }
         397               0 : }
         398                 :
         399                 : void
         400               0 : nsXBLBinding::SetBoundElement(nsIContent* aElement)
         401                 : {
         402               0 :   mBoundElement = aElement;
         403               0 :   if (mNextBinding)
         404               0 :     mNextBinding->SetBoundElement(aElement);
         405               0 : }
         406                 :
         407                 : bool
         408               0 : nsXBLBinding::HasStyleSheets() const
         409                 : {
         410                 :   // Find out if we need to re-resolve style.  We'll need to do this
         411                 :   // if we have additional stylesheets in our binding document.
         412               0 :   if (mPrototypeBinding->HasStyleSheets())
         413               0 :     return true;
         414                 :
         415               0 :   return mNextBinding ? mNextBinding->HasStyleSheets() : false;
         416                 : }
         417                 :
         418                 : struct EnumData {
         419                 :   nsXBLBinding* mBinding;
         420                 :
         421               0 :   EnumData(nsXBLBinding* aBinding)
         422               0 :     :mBinding(aBinding)
         423               0 :   {}
         424                 : };
         425                 :
         426                 : struct ContentListData : public EnumData {
         427                 :   nsBindingManager* mBindingManager;
         428                 :   nsresult          mRv;
         429                 :
         430               0 :   ContentListData(nsXBLBinding* aBinding, nsBindingManager* aManager)
         431               0 :     :EnumData(aBinding), mBindingManager(aManager), mRv(NS_OK)
         432               0 :   {}
         433                 : };
         434                 :
         435                 : static PLDHashOperator
         436               0 : BuildContentLists(nsISupports* aKey,
         437                 :                   nsAutoPtr<nsInsertionPointList>& aData,
         438                 :                   void* aClosure)
         439                 : {
         440               0 :   ContentListData* data = (ContentListData*)aClosure;
         441               0 :   nsBindingManager* bm = data->mBindingManager;
         442               0 :   nsXBLBinding* binding = data->mBinding;
         443                 :
         444               0 :   nsIContent *boundElement = binding->GetBoundElement();
         445                 :
         446               0 :   PRInt32 count = aData->Length();
         447                 :
         448               0 :   if (count == 0)
         449               0 :     return PL_DHASH_NEXT;
         450                 :
         451                 :   // Figure out the relevant content node.
         452               0 :   nsXBLInsertionPoint* currPoint = aData->ElementAt(0);
         453               0 :   nsCOMPtr<nsIContent> parent = currPoint->GetInsertionParent();
         454               0 :   if (!parent) {
         455               0 :     data->mRv = NS_ERROR_FAILURE;
         456               0 :     return PL_DHASH_STOP;
         457                 :   }
         458               0 :   PRInt32 currIndex = currPoint->GetInsertionIndex();
         459                 :
         460                 :   // XXX Could this array just be altered in place and passed directly to
         461                 :   // SetContentListFor?  We'd save space if we could pull this off.
         462               0 :   nsInsertionPointList* contentList = new nsInsertionPointList;
         463               0 :   if (!contentList) {
         464               0 :     data->mRv = NS_ERROR_OUT_OF_MEMORY;
         465               0 :     return PL_DHASH_STOP;
         466                 :   }
         467                 :
         468               0 :   nsCOMPtr<nsIDOMNodeList> nodeList;
         469               0 :   if (parent == boundElement) {
         470                 :     // We are altering anonymous nodes to accommodate insertion points.
         471               0 :     nodeList = binding->GetAnonymousNodes();
         472                 :   }
         473                 :   else {
         474                 :     // We are altering the explicit content list of a node to accommodate insertion points.
         475               0 :     nsCOMPtr<nsIDOMNode> node(do_QueryInterface(parent));
         476               0 :     node->GetChildNodes(getter_AddRefs(nodeList));
         477                 :   }
         478                 :
         479               0 :   nsXBLInsertionPoint* pseudoPoint = nsnull;
         480                 :   PRUint32 childCount;
         481               0 :   nodeList->GetLength(&childCount);
         482               0 :   PRInt32 j = 0;
         483                 :
         484               0 :   for (PRUint32 i = 0; i < childCount; i++) {
         485               0 :     nsCOMPtr<nsIDOMNode> node;
         486               0 :     nodeList->Item(i, getter_AddRefs(node));
         487               0 :     nsCOMPtr<nsIContent> child(do_QueryInterface(node));
         488               0 :     if (((PRInt32)i) == currIndex) {
         489                 :       // Add the currPoint to the insertion point list.
         490               0 :       contentList->AppendElement(currPoint);
         491                 :
         492                 :       // Get the next real insertion point and update our currIndex.
         493               0 :       j++;
         494               0 :       if (j < count) {
         495               0 :         currPoint = aData->ElementAt(j);
         496               0 :         currIndex = currPoint->GetInsertionIndex();
         497                 :       }
         498                 :
         499                 :       // Null out our current pseudo-point.
         500               0 :       pseudoPoint = nsnull;
         501                 :     }
         502                 :
         503               0 :     if (!pseudoPoint) {
         504               0 :       pseudoPoint = new nsXBLInsertionPoint(parent, (PRUint32) -1, nsnull);
         505               0 :       if (pseudoPoint) {
         506               0 :         contentList->AppendElement(pseudoPoint);
         507                 :       }
         508                 :     }
         509               0 :     if (pseudoPoint) {
         510               0 :       pseudoPoint->AddChild(child);
         511                 :     }
         512                 :   }
         513                 :
         514                 :   // Add in all the remaining insertion points.
         515               0 :   contentList->AppendElements(aData->Elements() + j, count - j);
         516                 :
         517                 :   // Now set the content list using the binding manager,
         518                 :   // If the bound element is the parent, then we alter the anonymous node list
         519                 :   // instead.  This allows us to always maintain two distinct lists should
         520                 :   // insertion points be nested into an inner binding.
         521               0 :   if (parent == boundElement)
         522               0 :     bm->SetAnonymousNodesFor(parent, contentList);
         523                 :   else
         524               0 :     bm->SetContentListFor(parent, contentList);
         525               0 :   return PL_DHASH_NEXT;
         526                 : }
         527                 :
         528                 : static PLDHashOperator
         529               0 : RealizeDefaultContent(nsISupports* aKey,
         530                 :                       nsAutoPtr<nsInsertionPointList>& aData,
         531                 :                       void* aClosure)
         532                 : {
         533               0 :   ContentListData* data = (ContentListData*)aClosure;
         534               0 :   nsBindingManager* bm = data->mBindingManager;
         535               0 :   nsXBLBinding* binding = data->mBinding;
         536                 :
         537               0 :   PRInt32 count = aData->Length();
         538                 :
         539               0 :   for (PRInt32 i = 0; i < count; i++) {
         540               0 :     nsXBLInsertionPoint* currPoint = aData->ElementAt(i);
         541               0 :     PRInt32 insCount = currPoint->ChildCount();
         542                 :
         543               0 :     if (insCount == 0) {
         544               0 :       nsCOMPtr<nsIContent> defContent = currPoint->GetDefaultContentTemplate();
         545               0 :       if (defContent) {
         546                 :         // We need to take this template and use it to realize the
         547                 :         // actual default content (through cloning).
         548                 :         // Clone this insertion point element.
         549               0 :         nsCOMPtr<nsIContent> insParent = currPoint->GetInsertionParent();
         550               0 :         if (!insParent) {
         551               0 :           data->mRv = NS_ERROR_FAILURE;
         552               0 :           return PL_DHASH_STOP;
         553                 :         }
         554               0 :         nsIDocument *document = insParent->OwnerDoc();
         555               0 :         nsCOMPtr<nsIDOMNode> clonedNode;
         556               0 :         nsCOMArray<nsINode> nodesWithProperties;
         557                 :         nsNodeUtils::Clone(defContent, true, document->NodeInfoManager(),
         558               0 :                            nodesWithProperties, getter_AddRefs(clonedNode));
         559                 :
         560                 :         // Now that we have the cloned content, install the default content as
         561                 :         // if it were additional anonymous content.
         562               0 :         nsCOMPtr<nsIContent> clonedContent(do_QueryInterface(clonedNode));
         563               0 :         binding->InstallAnonymousContent(clonedContent, insParent);
         564                 :
         565                 :         // Cache the clone so that it can be properly destroyed if/when our
         566                 :         // other anonymous content is destroyed.
         567               0 :         currPoint->SetDefaultContent(clonedContent);
         568                 :
         569                 :         // Now make sure the kids of the clone are added to the insertion point as
         570                 :         // children.
         571               0 :         for (nsIContent* child = clonedContent->GetFirstChild();
         572                 :              child;
         573               0 :              child = child->GetNextSibling()) {
         574               0 :           bm->SetInsertionParent(child, insParent);
         575               0 :           currPoint->AddChild(child);
         576                 :         }
         577                 :       }
         578                 :     }
         579                 :   }
         580                 :
         581               0 :   return PL_DHASH_NEXT;
         582                 : }
         583                 :
         584                 : static PLDHashOperator
         585               0 : ChangeDocumentForDefaultContent(nsISupports* aKey,
         586                 :                                 nsAutoPtr<nsInsertionPointList>& aData,
         587                 :                                 void* aClosure)
         588                 : {
         589               0 :   PRInt32 count = aData->Length();
         590               0 :   for (PRInt32 i = 0; i < count; i++) {
         591               0 :     aData->ElementAt(i)->UnbindDefaultContent();
         592                 :   }
         593                 :
         594               0 :   return PL_DHASH_NEXT;
         595                 : }
         596                 :
         597                 : void
         598               0 : nsXBLBinding::GenerateAnonymousContent()
         599                 : {
         600               0 :   NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
         601                 :                "Someone forgot a script blocker");
         602                 :
         603                 :   // Fetch the content element for this binding.
         604                 :   nsIContent* content =
         605               0 :     mPrototypeBinding->GetImmediateChild(nsGkAtoms::content);
         606                 :
         607               0 :   if (!content) {
         608                 :     // We have no anonymous content.
         609               0 :     if (mNextBinding)
         610               0 :       mNextBinding->GenerateAnonymousContent();
         611                 :
         612               0 :     return;
         613                 :   }
         614                 :
         615                 :   // Find out if we're really building kids or if we're just
         616                 :   // using the attribute-setting shorthand hack.
         617               0 :   PRUint32 contentCount = content->GetChildCount();
         618                 :
         619                 :   // Plan to build the content by default.
         620               0 :   bool hasContent = (contentCount > 0);
         621               0 :   bool hasInsertionPoints = mPrototypeBinding->HasInsertionPoints();
         622                 :
         623                 : #ifdef DEBUG
         624                 :   // See if there's an includes attribute.
         625               0 :   if (nsContentUtils::HasNonEmptyAttr(content, kNameSpaceID_None,
         626               0 :                                       nsGkAtoms::includes)) {
         627               0 :     nsCAutoString message("An XBL Binding with URI ");
         628               0 :     nsCAutoString uri;
         629               0 :     mPrototypeBinding->BindingURI()->GetSpec(uri);
         630               0 :     message += uri;
         631               0 :     message += " is still using the deprecated\n<content includes=\"\"> syntax! Use <children> instead!\n";
         632               0 :     NS_WARNING(message.get());
         633                 :   }
         634                 : #endif
         635                 :
         636               0 :   if (hasContent || hasInsertionPoints) {
         637               0 :     nsIDocument* doc = mBoundElement->OwnerDoc();
         638                 :
         639               0 :     nsBindingManager *bindingManager = doc->BindingManager();
         640                 :
         641               0 :     nsCOMPtr<nsIDOMNodeList> children;
         642               0 :     bindingManager->GetContentListFor(mBoundElement, getter_AddRefs(children));
         643                 :
         644               0 :     nsCOMPtr<nsIDOMNode> node;
         645               0 :     nsCOMPtr<nsIContent> childContent;
         646                 :     PRUint32 length;
         647               0 :     children->GetLength(&length);
         648               0 :     if (length > 0 && !hasInsertionPoints) {
         649                 :       // There are children being placed underneath us, but we have no specified
         650                 :       // insertion points, and therefore no place to put the kids.  Don't generate
         651                 :       // anonymous content.
         652                 :       // Special case template and observes.
         653               0 :       for (PRUint32 i = 0; i < length; i++) {
         654               0 :         children->Item(i, getter_AddRefs(node));
         655               0 :         childContent = do_QueryInterface(node);
         656                 :
         657               0 :         nsINodeInfo *ni = childContent->NodeInfo();
         658               0 :         nsIAtom *localName = ni->NameAtom();
         659               0 :         if (ni->NamespaceID() != kNameSpaceID_XUL ||
         660                 :             (localName != nsGkAtoms::observes &&
         661                 :              localName != nsGkAtoms::_template)) {
         662               0 :           hasContent = false;
         663               0 :           break;
         664                 :         }
         665                 :       }
         666                 :     }
         667                 :
         668               0 :     if (hasContent || hasInsertionPoints) {
         669               0 :       nsCOMPtr<nsIDOMNode> clonedNode;
         670               0 :       nsCOMArray<nsINode> nodesWithProperties;
         671                 :       nsNodeUtils::Clone(content, true, doc->NodeInfoManager(),
         672               0 :                          nodesWithProperties, getter_AddRefs(clonedNode));
         673                 :
         674               0 :       mContent = do_QueryInterface(clonedNode);
         675               0 :       InstallAnonymousContent(mContent, mBoundElement);
         676                 :
         677               0 :       if (hasInsertionPoints) {
         678                 :         // Now check and see if we have a single insertion point
         679                 :         // or multiple insertion points.
         680                 :
         681                 :         // Enumerate the prototype binding's insertion table to build
         682                 :         // our table of instantiated insertion points.
         683               0 :         mPrototypeBinding->InstantiateInsertionPoints(this);
         684                 :
         685                 :         // We now have our insertion point table constructed.  We
         686                 :         // enumerate this table.  For each array of insertion points
         687                 :         // bundled under the same content node, we generate a content
         688                 :         // list.  In the case of the bound element, we generate a new
         689                 :         // anonymous node list that will be used in place of the binding's
         690                 :         // cached anonymous node list.
         691               0 :         ContentListData data(this, bindingManager);
         692               0 :         mInsertionPointTable->Enumerate(BuildContentLists, &data);
         693               0 :         if (NS_FAILED(data.mRv)) {
         694                 :           return;
         695                 :         }
         696                 :
         697                 :         // We need to place the children
         698                 :         // at their respective insertion points.
         699               0 :         PRUint32 index = 0;
         700               0 :         bool multiplePoints = false;
         701                 :         nsIContent *singlePoint = GetSingleInsertionPoint(&index,
         702               0 :                                                           &multiplePoints);
         703                 :
         704               0 :         if (children) {
         705               0 :           if (multiplePoints) {
         706                 :             // We must walk the entire content list in order to determine where
         707                 :             // each child belongs.
         708               0 :             children->GetLength(&length);
         709               0 :             for (PRUint32 i = 0; i < length; i++) {
         710               0 :               children->Item(i, getter_AddRefs(node));
         711               0 :               childContent = do_QueryInterface(node);
         712                 :
         713                 :               // Now determine the insertion point in the prototype table.
         714                 :               PRUint32 index;
         715               0 :               nsIContent *point = GetInsertionPoint(childContent, &index);
         716               0 :               bindingManager->SetInsertionParent(childContent, point);
         717                 :
         718                 :               // Find the correct nsIXBLInsertion point in our table.
         719               0 :               nsInsertionPointList* arr = nsnull;
         720               0 :               GetInsertionPointsFor(point, &arr);
         721               0 :               nsXBLInsertionPoint* insertionPoint = nsnull;
         722               0 :               PRInt32 arrCount = arr->Length();
         723               0 :               for (PRInt32 j = 0; j < arrCount; j++) {
         724               0 :                 insertionPoint = arr->ElementAt(j);
         725               0 :                 if (insertionPoint->Matches(point, index))
         726               0 :                   break;
         727               0 :                 insertionPoint = nsnull;
         728                 :               }
         729                 :
         730               0 :               if (insertionPoint)
         731               0 :                 insertionPoint->AddChild(childContent);
         732                 :               else {
         733                 :                 // We were unable to place this child.  All anonymous content
         734                 :                 // should be thrown out.  Special-case template and observes.
         735                 :
         736               0 :                 nsINodeInfo *ni = childContent->NodeInfo();
         737               0 :                 nsIAtom *localName = ni->NameAtom();
         738               0 :                 if (ni->NamespaceID() != kNameSpaceID_XUL ||
         739                 :                     (localName != nsGkAtoms::observes &&
         740                 :                      localName != nsGkAtoms::_template)) {
         741                 :                   // Undo InstallAnonymousContent
         742               0 :                   UninstallAnonymousContent(doc, mContent);
         743                 :
         744                 :                   // Kill all anonymous content.
         745               0 :                   mContent = nsnull;
         746               0 :                   bindingManager->SetContentListFor(mBoundElement, nsnull);
         747               0 :                   bindingManager->SetAnonymousNodesFor(mBoundElement, nsnull);
         748                 :                   return;
         749                 :                 }
         750                 :               }
         751                 :             }
         752                 :           }
         753                 :           else {
         754                 :             // All of our children are shunted to this single insertion point.
         755               0 :             nsInsertionPointList* arr = nsnull;
         756               0 :             GetInsertionPointsFor(singlePoint, &arr);
         757               0 :             nsXBLInsertionPoint* insertionPoint = arr->ElementAt(0);
         758                 :
         759               0 :             nsCOMPtr<nsIDOMNode> node;
         760               0 :             nsCOMPtr<nsIContent> content;
         761                 :             PRUint32 length;
         762               0 :             children->GetLength(&length);
         763                 :
         764               0 :             for (PRUint32 i = 0; i < length; i++) {
         765               0 :               children->Item(i, getter_AddRefs(node));
         766               0 :               content = do_QueryInterface(node);
         767               0 :               bindingManager->SetInsertionParent(content, singlePoint);
         768               0 :               insertionPoint->AddChild(content);
         769                 :             }
         770                 :           }
         771                 :         }
         772                 :
         773                 :         // Now that all of our children have been added, we need to walk all of our
         774                 :         // nsIXBLInsertion points to see if any of them have default content that
         775                 :         // needs to be built.
         776               0 :         mInsertionPointTable->Enumerate(RealizeDefaultContent, &data);
         777               0 :         if (NS_FAILED(data.mRv)) {
         778                 :           return;
         779                 :         }
         780                 :       }
         781                 :     }
         782                 :
         783               0 :     mPrototypeBinding->SetInitialAttributes(mBoundElement, mContent);
         784                 :   }
         785                 :
         786                 :   // Always check the content element for potential attributes.
         787                 :   // This shorthand hack always happens, even when we didn't
         788                 :   // build anonymous content.
         789                 :   const nsAttrName* attrName;
         790               0 :   for (PRUint32 i = 0; (attrName = content->GetAttrNameAt(i)); ++i) {
         791               0 :     PRInt32 namespaceID = attrName->NamespaceID();
         792                 :     // Hold a strong reference here so that the atom doesn't go away during
         793                 :     // UnsetAttr.
         794               0 :     nsCOMPtr<nsIAtom> name = attrName->LocalName();
         795                 :
         796               0 :     if (name != nsGkAtoms::includes) {
         797               0 :       if (!nsContentUtils::HasNonEmptyAttr(mBoundElement, namespaceID, name)) {
         798               0 :         nsAutoString value2;
         799               0 :         content->GetAttr(namespaceID, name, value2);
         800                 :         mBoundElement->SetAttr(namespaceID, name, attrName->GetPrefix(),
         801               0 :                                value2, false);
         802                 :       }
         803                 :     }
         804                 :
         805                 :     // Conserve space by wiping the attributes off the clone.
         806               0 :     if (mContent)
         807               0 :       mContent->UnsetAttr(namespaceID, name, false);
         808                 :   }
         809                 : }
         810                 :
         811                 : void
         812               0 : nsXBLBinding::InstallEventHandlers()
         813                 : {
         814                 :   // Don't install handlers if scripts aren't allowed.
         815               0 :   if (AllowScripts()) {
         816                 :     // Fetch the handlers prototypes for this binding.
         817               0 :     nsXBLPrototypeHandler* handlerChain = mPrototypeBinding->GetPrototypeHandlers();
         818                 :
         819               0 :     if (handlerChain) {
         820                 :       nsEventListenerManager* manager =
         821               0 :         mBoundElement->GetListenerManager(true);
         822               0 :       if (!manager)
         823               0 :         return;
         824                 :
         825                 :       bool isChromeDoc =
         826               0 :         nsContentUtils::IsChromeDoc(mBoundElement->OwnerDoc());
         827               0 :       bool isChromeBinding = mPrototypeBinding->IsChrome();
         828                 :       nsXBLPrototypeHandler* curr;
         829               0 :       for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
         830                 :         // Fetch the event type.
         831               0 :         nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName();
         832               0 :         if (!eventAtom ||
         833               0 :             eventAtom == nsGkAtoms::keyup ||
         834               0 :             eventAtom == nsGkAtoms::keydown ||
         835               0 :             eventAtom == nsGkAtoms::keypress)
         836               0 :           continue;
         837                 :
         838               0 :         nsXBLEventHandler* handler = curr->GetEventHandler();
         839               0 :         if (handler) {
         840                 :           // Figure out if we're using capturing or not.
         841               0 :           PRInt32 flags = (curr->GetPhase() == NS_PHASE_CAPTURING) ?
         842               0 :             NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
         843                 :
         844                 :           // If this is a command, add it in the system event group
         845               0 :           if ((curr->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND |
         846                 :                                   NS_HANDLER_TYPE_SYSTEM)) &&
         847               0 :               (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
         848               0 :             flags |= NS_EVENT_FLAG_SYSTEM_EVENT;
         849                 :           }
         850                 :
         851               0 :           bool hasAllowUntrustedAttr = curr->HasAllowUntrustedAttr();
         852               0 :           if ((hasAllowUntrustedAttr && curr->AllowUntrustedEvents()) ||
         853               0 :               (!hasAllowUntrustedAttr && !isChromeDoc)) {
         854               0 :             flags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
         855                 :           }
         856                 :
         857                 :           manager->AddEventListenerByType(handler,
         858               0 :                                           nsDependentAtomString(eventAtom),
         859               0 :                                           flags);
         860                 :         }
         861                 :       }
         862                 :
         863                 :       const nsCOMArray<nsXBLKeyEventHandler>* keyHandlers =
         864               0 :         mPrototypeBinding->GetKeyEventHandlers();
         865                 :       PRInt32 i;
         866               0 :       for (i = 0; i < keyHandlers->Count(); ++i) {
         867               0 :         nsXBLKeyEventHandler* handler = keyHandlers->ObjectAt(i);
         868               0 :         handler->SetIsBoundToChrome(isChromeDoc);
         869                 :
         870               0 :         nsAutoString type;
         871               0 :         handler->GetEventName(type);
         872                 :
         873                 :         // If this is a command, add it in the system event group, otherwise
         874                 :         // add it to the standard event group.
         875                 :
         876                 :         // Figure out if we're using capturing or not.
         877               0 :         PRInt32 flags = (handler->GetPhase() == NS_PHASE_CAPTURING) ?
         878               0 :           NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
         879                 :
         880               0 :         if ((handler->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND |
         881                 :                                    NS_HANDLER_TYPE_SYSTEM)) &&
         882               0 :             (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
         883               0 :           flags |= NS_EVENT_FLAG_SYSTEM_EVENT;
         884                 :         }
         885                 :
         886                 :         // For key handlers we have to set NS_PRIV_EVENT_UNTRUSTED_PERMITTED flag.
         887                 :         // Whether the handling of the event is allowed or not is handled in
         888                 :         // nsXBLKeyEventHandler::HandleEvent
         889               0 :         flags |= NS_PRIV_EVENT_UNTRUSTED_PERMITTED;
         890                 :
         891               0 :         manager->AddEventListenerByType(handler, type, flags);
         892                 :       }
         893                 :     }
         894                 :   }
         895                 :
         896               0 :   if (mNextBinding)
         897               0 :     mNextBinding->InstallEventHandlers();
         898                 : }
         899                 :
         900                 : nsresult
         901               0 : nsXBLBinding::InstallImplementation()
         902                 : {
         903                 :   // Always install the base class properties first, so that
         904                 :   // derived classes can reference the base class properties.
         905                 :
         906               0 :   if (mNextBinding) {
         907               0 :     nsresult rv = mNextBinding->InstallImplementation();
         908               0 :     NS_ENSURE_SUCCESS(rv, rv);
         909                 :   }
         910                 :
         911                 :   // iterate through each property in the prototype's list and install the property.
         912               0 :   if (AllowScripts())
         913               0 :     return mPrototypeBinding->InstallImplementation(mBoundElement);
         914                 :
         915               0 :   return NS_OK;
         916                 : }
         917                 :
         918                 : nsIAtom*
         919               0 : nsXBLBinding::GetBaseTag(PRInt32* aNameSpaceID)
         920                 : {
         921               0 :   nsIAtom *tag = mPrototypeBinding->GetBaseTag(aNameSpaceID);
         922               0 :   if (!tag && mNextBinding)
         923               0 :     return mNextBinding->GetBaseTag(aNameSpaceID);
         924                 :
         925               0 :   return tag;
         926                 : }
         927                 :
         928                 : void
         929               0 : nsXBLBinding::AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID,
         930                 :                                bool aRemoveFlag, bool aNotify)
         931                 : {
         932                 :   // XXX Change if we ever allow multiple bindings in a chain to contribute anonymous content
         933               0 :   if (!mContent) {
         934               0 :     if (mNextBinding)
         935                 :       mNextBinding->AttributeChanged(aAttribute, aNameSpaceID,
         936               0 :                                      aRemoveFlag, aNotify);
         937                 :   } else {
         938                 :     mPrototypeBinding->AttributeChanged(aAttribute, aNameSpaceID, aRemoveFlag,
         939               0 :                                         mBoundElement, mContent, aNotify);
         940                 :   }
         941               0 : }
         942                 :
         943                 : void
         944               0 : nsXBLBinding::ExecuteAttachedHandler()
         945                 : {
         946               0 :   if (mNextBinding)
         947               0 :     mNextBinding->ExecuteAttachedHandler();
         948                 :
         949               0 :   if (AllowScripts())
         950               0 :     mPrototypeBinding->BindingAttached(mBoundElement);
         951               0 : }
         952                 :
         953                 : void
         954               0 : nsXBLBinding::ExecuteDetachedHandler()
         955                 : {
         956               0 :   if (AllowScripts())
         957               0 :     mPrototypeBinding->BindingDetached(mBoundElement);
         958                 :
         959               0 :   if (mNextBinding)
         960               0 :     mNextBinding->ExecuteDetachedHandler();
         961               0 : }
         962                 :
         963                 : void
         964               0 : nsXBLBinding::UnhookEventHandlers()
         965                 : {
         966               0 :   nsXBLPrototypeHandler* handlerChain = mPrototypeBinding->GetPrototypeHandlers();
         967                 :
         968               0 :   if (handlerChain) {
         969                 :     nsEventListenerManager* manager =
         970               0 :       mBoundElement->GetListenerManager(false);
         971               0 :     if (!manager) {
         972               0 :       return;
         973                 :     }
         974                 :
         975               0 :     bool isChromeBinding = mPrototypeBinding->IsChrome();
         976                 :     nsXBLPrototypeHandler* curr;
         977               0 :     for (curr = handlerChain; curr; curr = curr->GetNextHandler()) {
         978               0 :       nsXBLEventHandler* handler = curr->GetCachedEventHandler();
         979               0 :       if (!handler) {
         980               0 :         continue;
         981                 :       }
         982                 :
         983               0 :       nsCOMPtr<nsIAtom> eventAtom = curr->GetEventName();
         984               0 :       if (!eventAtom ||
         985               0 :           eventAtom == nsGkAtoms::keyup ||
         986               0 :           eventAtom == nsGkAtoms::keydown ||
         987               0 :           eventAtom == nsGkAtoms::keypress)
         988               0 :         continue;
         989                 :
         990                 :       // Figure out if we're using capturing or not.
         991               0 :       PRInt32 flags = (curr->GetPhase() == NS_PHASE_CAPTURING) ?
         992               0 :         NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
         993                 :
         994                 :       // If this is a command, remove it from the system event group,
         995                 :       // otherwise remove it from the standard event group.
         996                 :
         997               0 :       if ((curr->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND |
         998                 :                               NS_HANDLER_TYPE_SYSTEM)) &&
         999               0 :           (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
        1000               0 :         flags |= NS_EVENT_FLAG_SYSTEM_EVENT;
        1001                 :       }
        1002                 :
        1003                 :       manager->RemoveEventListenerByType(handler,
        1004               0 :                                          nsDependentAtomString(eventAtom),
        1005               0 :                                          flags);
        1006                 :     }
        1007                 :
        1008                 :     const nsCOMArray<nsXBLKeyEventHandler>* keyHandlers =
        1009               0 :       mPrototypeBinding->GetKeyEventHandlers();
        1010                 :     PRInt32 i;
        1011               0 :     for (i = 0; i < keyHandlers->Count(); ++i) {
        1012               0 :       nsXBLKeyEventHandler* handler = keyHandlers->ObjectAt(i);
        1013                 :
        1014               0 :       nsAutoString type;
        1015               0 :       handler->GetEventName(type);
        1016                 :
        1017                 :       // Figure out if we're using capturing or not.
        1018               0 :       PRInt32 flags = (handler->GetPhase() == NS_PHASE_CAPTURING) ?
        1019               0 :         NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
        1020                 :
        1021                 :       // If this is a command, remove it from the system event group, otherwise
        1022                 :       // remove it from the standard event group.
        1023                 :
        1024               0 :       if ((handler->GetType() & (NS_HANDLER_TYPE_XBL_COMMAND | NS_HANDLER_TYPE_SYSTEM)) &&
        1025               0 :           (isChromeBinding || mBoundElement->IsInNativeAnonymousSubtree())) {
        1026               0 :         flags |= NS_EVENT_FLAG_SYSTEM_EVENT;
        1027                 :       }
        1028                 :
        1029               0 :       manager->RemoveEventListenerByType(handler, type, flags);
        1030                 :     }
        1031                 :   }
        1032                 : }
        1033                 :
        1034                 : void
        1035               0 : nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument)
        1036                 : {
        1037               0 :   if (aOldDocument != aNewDocument) {
        1038                 :     // Only style bindings get their prototypes unhooked.  First do ourselves.
        1039               0 :     if (mIsStyleBinding) {
        1040                 :       // Now the binding dies.  Unhook our prototypes.
        1041               0 :       if (mPrototypeBinding->HasImplementation()) {
        1042               0 :         nsIScriptGlobalObject *global = aOldDocument->GetScopeObject();
        1043               0 :         if (global) {
        1044               0 :           JSObject *scope = global->GetGlobalJSObject();
        1045                 :           // scope might be null if we've cycle-collected the global
        1046                 :           // object, since the Unlink phase of cycle collection happens
        1047                 :           // after JS GC finalization.  But in that case, we don't care
        1048                 :           // about fixing the prototype chain, since everything's going
        1049                 :           // away immediately.
        1050                 :
        1051               0 :           nsCOMPtr<nsIScriptContext> context = global->GetContext();
        1052               0 :           if (context && scope) {
        1053               0 :             JSContext *cx = context->GetNativeContext();
        1054                 :
        1055               0 :             nsCxPusher pusher;
        1056               0 :             pusher.Push(cx);
        1057                 :
        1058               0 :             nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
        1059               0 :             nsIXPConnect *xpc = nsContentUtils::XPConnect();
        1060                 :             nsresult rv =
        1061                 :               xpc->GetWrappedNativeOfNativeObject(cx, scope, mBoundElement,
        1062                 :                                                   NS_GET_IID(nsISupports),
        1063               0 :                                                   getter_AddRefs(wrapper));
        1064               0 :             if (NS_FAILED(rv))
        1065                 :               return;
        1066                 :
        1067                 :             JSObject* scriptObject;
        1068               0 :             if (wrapper)
        1069               0 :                 wrapper->GetJSObject(&scriptObject);
        1070                 :             else
        1071               0 :                 scriptObject = nsnull;
        1072                 :
        1073               0 :             if (scriptObject) {
        1074                 :               // XXX Stay in sync! What if a layered binding has an
        1075                 :               // <interface>?!
        1076                 :               // XXXbz what does that comment mean, really?  It seems to date
        1077                 :               // back to when there was such a thing as an <interface>, whever
        1078                 :               // that was...
        1079                 :
        1080                 :               // Find the right prototype.
        1081               0 :               JSObject* base = scriptObject;
        1082                 :               JSObject* proto;
        1083               0 :               JSAutoRequest ar(cx);
        1084               0 :               JSAutoEnterCompartment ac;
        1085               0 :               if (!ac.enter(cx, scriptObject)) {
        1086                 :                 return;
        1087                 :               }
        1088                 :
        1089               0 :               for ( ; true; base = proto) { // Will break out on null proto
        1090               0 :                 proto = ::JS_GetPrototype(base);
        1091               0 :                 if (!proto) {
        1092               0 :                   break;
        1093                 :                 }
        1094                 :
        1095               0 :                 JSClass* clazz = ::JS_GetClass(proto);
        1096               0 :                 if (!clazz ||
        1097                 :                     (~clazz->flags &
        1098                 :                      (JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) ||
        1099                 :                     JSCLASS_RESERVED_SLOTS(clazz) != 1 ||
        1100                 :                     clazz->resolve != (JSResolveOp)XBLResolve ||
        1101                 :                     clazz->finalize != XBLFinalize) {
        1102                 :                   // Clearly not the right class
        1103               0 :                   continue;
        1104                 :                 }
        1105                 :
        1106                 :                 nsRefPtr<nsXBLDocumentInfo> docInfo =
        1107               0 :                   static_cast<nsXBLDocumentInfo*>(::JS_GetPrivate(proto));
        1108               0 :                 if (!docInfo) {
        1109                 :                   // Not the proto we seek
        1110               0 :                   continue;
        1111                 :                 }
        1112                 :
        1113               0 :                 jsval protoBinding = ::JS_GetReservedSlot(proto, 0);
        1114                 :
        1115               0 :                 if (JSVAL_TO_PRIVATE(protoBinding) != mPrototypeBinding) {
        1116                 :                   // Not the right binding
        1117               0 :                   continue;
        1118                 :                 }
        1119                 :
        1120                 :                 // Alright!  This is the right prototype.  Pull it out of the
        1121                 :                 // proto chain.
        1122               0 :                 JSObject* grandProto = ::JS_GetPrototype(proto);
        1123               0 :                 ::JS_SetPrototype(cx, base, grandProto);
        1124               0 :                 break;
        1125                 :               }
        1126                 :
        1127               0 :               mPrototypeBinding->UndefineFields(cx, scriptObject);
        1128                 :
        1129                 :               // Don't remove the reference from the document to the
        1130                 :               // wrapper here since it'll be removed by the element
        1131                 :               // itself when that's taken out of the document.
        1132                 :             }
        1133                 :           }
        1134                 :         }
        1135                 :       }
        1136                 :
        1137                 :       // Remove our event handlers
        1138               0 :       UnhookEventHandlers();
        1139                 :     }
        1140                 :
        1141                 :     {
        1142               0 :       nsAutoScriptBlocker scriptBlocker;
        1143                 :
        1144                 :       // Then do our ancestors.  This reverses the construction order, so that at
        1145                 :       // all times things are consistent as far as everyone is concerned.
        1146               0 :       if (mNextBinding) {
        1147               0 :         mNextBinding->ChangeDocument(aOldDocument, aNewDocument);
        1148                 :       }
        1149                 :
        1150                 :       // Update the anonymous content.
        1151                 :       // XXXbz why not only for style bindings?
        1152               0 :       nsIContent *anonymous = mContent;
        1153               0 :       if (anonymous) {
        1154                 :         // Also kill the default content within all our insertion points.
        1155               0 :         if (mInsertionPointTable)
        1156                 :           mInsertionPointTable->Enumerate(ChangeDocumentForDefaultContent,
        1157               0 :                                           nsnull);
        1158                 :
        1159               0 :         nsXBLBinding::UninstallAnonymousContent(aOldDocument, anonymous);
        1160                 :       }
        1161                 :
        1162                 :       // Make sure that henceforth we don't claim that mBoundElement's children
        1163                 :       // have insertion parents in the old document.
        1164               0 :       nsBindingManager* bindingManager = aOldDocument->BindingManager();
        1165               0 :       for (nsIContent* child = mBoundElement->GetLastChild();
        1166                 :            child;
        1167               0 :            child = child->GetPreviousSibling()) {
        1168               0 :         bindingManager->SetInsertionParent(child, nsnull);
        1169                 :       }
        1170                 :     }
        1171                 :   }
        1172                 : }
        1173                 :
        1174                 : bool
        1175               0 : nsXBLBinding::InheritsStyle() const
        1176                 : {
        1177                 :   // XXX Will have to change if we ever allow multiple bindings to contribute anonymous content.
        1178                 :   // Most derived binding with anonymous content determines style inheritance for now.
        1179                 :
        1180                 :   // XXX What about bindings with <content> but no kids, e.g., my treecell-text binding?
        1181               0 :   if (mContent)
        1182               0 :     return mPrototypeBinding->InheritsStyle();
        1183                 :
        1184               0 :   if (mNextBinding)
        1185               0 :     return mNextBinding->InheritsStyle();
        1186                 :
        1187               0 :   return true;
        1188                 : }
        1189                 :
        1190                 : void
        1191               0 : nsXBLBinding::WalkRules(nsIStyleRuleProcessor::EnumFunc aFunc, void* aData)
        1192                 : {
        1193               0 :   if (mNextBinding)
        1194               0 :     mNextBinding->WalkRules(aFunc, aData);
        1195                 :
        1196               0 :   nsIStyleRuleProcessor *rules = mPrototypeBinding->GetRuleProcessor();
        1197               0 :   if (rules)
        1198               0 :     (*aFunc)(rules, aData);
        1199               0 : }
        1200                 :
        1201                 : // Internal helper methods ////////////////////////////////////////////////////////////////
        1202                 :
        1203                 : // static
        1204                 : nsresult
        1205               0 : nsXBLBinding::DoInitJSClass(JSContext *cx, JSObject *global, JSObject *obj,
        1206                 :                             const nsAFlatCString& aClassName,
        1207                 :                             nsXBLPrototypeBinding* aProtoBinding,
        1208                 :                             JSObject** aClassObject)
        1209                 : {
        1210                 :   // First ensure our JS class is initialized.
        1211               0 :   nsCAutoString className(aClassName);
        1212               0 :   JSObject* parent_proto = nsnull;  // If we have an "obj" we can set this
        1213               0 :   JSAutoRequest ar(cx);
        1214                 :
        1215               0 :   JSAutoEnterCompartment ac;
        1216               0 :   if (!ac.enter(cx, global)) {
        1217               0 :     return NS_ERROR_FAILURE;
        1218                 :   }
        1219                 :
        1220               0 :   if (obj) {
        1221                 :     // Retrieve the current prototype of obj.
        1222               0 :     parent_proto = ::JS_GetPrototype(obj);
        1223               0 :     if (parent_proto) {
        1224                 :       // We need to create a unique classname based on aClassName and
        1225                 :       // parent_proto.  Append a space (an invalid URI character) to ensure that
        1226                 :       // we don't have accidental collisions with the case when parent_proto is
        1227                 :       // null and aClassName ends in some bizarre numbers (yeah, it's unlikely).
        1228                 :       jsid parent_proto_id;
        1229               0 :       if (!::JS_GetObjectId(cx, parent_proto, &parent_proto_id)) {
        1230                 :         // Probably OOM
        1231               0 :         return NS_ERROR_OUT_OF_MEMORY;
        1232                 :       }
        1233                 :
        1234                 :       // One space, maybe "0x", at most 16 chars (on a 64-bit system) of long,
        1235                 :       // and a null-terminator (which PR_snprintf ensures is there even if the
        1236                 :       // string representation of what we're printing does not fit in the buffer
        1237                 :       // provided).
        1238                 :       char buf[20];
        1239               0 :       PR_snprintf(buf, sizeof(buf), " %lx", parent_proto_id);
        1240               0 :       className.Append(buf);
        1241                 :     }
        1242                 :   }
        1243                 :
        1244                 :   jsval val;
        1245               0 :   JSObject* proto = NULL;
        1246               0 :   if ((!::JS_LookupPropertyWithFlags(cx, global, className.get(),
        1247                 :                                      JSRESOLVE_CLASSNAME,
        1248               0 :                                      &val)) ||
        1249               0 :       JSVAL_IS_PRIMITIVE(val)) {
        1250                 :     // We need to initialize the class.
        1251                 :
        1252                 :     nsXBLJSClass* c;
        1253                 :     void* classObject;
        1254               0 :     nsCStringKey key(className);
        1255               0 :     classObject = (nsXBLService::gClassTable)->Get(&key);
        1256                 :
        1257               0 :     if (classObject) {
        1258               0 :       c = static_cast<nsXBLJSClass*>(classObject);
        1259                 :
        1260                 :       // If c is on the LRU list (i.e., not linked to itself), remove it now!
        1261               0 :       JSCList* link = static_cast<JSCList*>(c);
        1262               0 :       if (c->next != link) {
        1263               0 :         JS_REMOVE_AND_INIT_LINK(link);
        1264               0 :         nsXBLService::gClassLRUListLength--;
        1265                 :       }
        1266                 :     } else {
        1267               0 :       if (JS_CLIST_IS_EMPTY(&nsXBLService::gClassLRUList)) {
        1268                 :         // We need to create a struct for this class.
        1269               0 :         c = new nsXBLJSClass(className);
        1270                 :
        1271               0 :         if (!c)
        1272               0 :           return NS_ERROR_OUT_OF_MEMORY;
        1273                 :       } else {
        1274                 :         // Pull the least recently used class struct off the list.
        1275               0 :         JSCList* lru = (nsXBLService::gClassLRUList).next;
        1276               0 :         JS_REMOVE_AND_INIT_LINK(lru);
        1277               0 :         nsXBLService::gClassLRUListLength--;
        1278                 :
        1279                 :         // Remove any mapping from the old name to the class struct.
        1280               0 :         c = static_cast<nsXBLJSClass*>(lru);
        1281               0 :         nsCStringKey oldKey(c->name);
        1282               0 :         (nsXBLService::gClassTable)->Remove(&oldKey);
        1283                 :
        1284                 :         // Change the class name and we're done.
        1285               0 :         nsMemory::Free((void*) c->name);
        1286               0 :         c->name = ToNewCString(className);
        1287                 :       }
        1288                 :
        1289                 :       // Add c to our table.
        1290               0 :       (nsXBLService::gClassTable)->Put(&key, (void*)c);
        1291                 :     }
        1292                 :
        1293                 :     // The prototype holds a strong reference to its class struct.
        1294               0 :     c->Hold();
        1295                 :
        1296                 :     // Make a new object prototyped by parent_proto and parented by global.
        1297                 :     proto = ::JS_InitClass(cx,                  // context
        1298                 :                            global,              // global object
        1299                 :                            parent_proto,        // parent proto
        1300                 :                            c,                   // JSClass
        1301                 :                            nsnull,              // JSNative ctor
        1302                 :                            0,                   // ctor args
        1303                 :                            nsnull,              // proto props
        1304                 :                            nsnull,              // proto funcs
        1305                 :                            nsnull,              // ctor props (static)
        1306               0 :                            nsnull);             // ctor funcs (static)
        1307               0 :     if (!proto) {
        1308                 :       // This will happen if we're OOM or if the security manager
        1309                 :       // denies defining the new class...
        1310                 :
        1311               0 :       (nsXBLService::gClassTable)->Remove(&key);
        1312                 :
        1313               0 :       c->Drop();
        1314                 :
        1315               0 :       return NS_ERROR_OUT_OF_MEMORY;
        1316                 :     }
        1317                 :
        1318                 :     // Keep this proto binding alive while we're alive.  Do this first so that
        1319                 :     // we can guarantee that in XBLFinalize this will be non-null.
        1320                 :     // Note that we can't just store aProtoBinding in the private and
        1321                 :     // addref/release the nsXBLDocumentInfo through it, because cycle
        1322                 :     // collection doesn't seem to work right if the private is not an
        1323                 :     // nsISupports.
        1324               0 :     nsXBLDocumentInfo* docInfo = aProtoBinding->XBLDocumentInfo();
        1325               0 :     ::JS_SetPrivate(proto, docInfo);
        1326               0 :     NS_ADDREF(docInfo);
        1327                 :
        1328               0 :     ::JS_SetReservedSlot(proto, 0, PRIVATE_TO_JSVAL(aProtoBinding));
        1329                 :
        1330               0 :     *aClassObject = proto;
        1331                 :   }
        1332                 :   else {
        1333               0 :     proto = JSVAL_TO_OBJECT(val);
        1334                 :   }
        1335                 :
        1336               0 :   if (obj) {
        1337                 :     // Set the prototype of our object to be the new class.
        1338               0 :     if (!::JS_SetPrototype(cx, obj, proto)) {
        1339               0 :       return NS_ERROR_FAILURE;
        1340                 :     }
        1341                 :   }
        1342                 :
        1343               0 :   return NS_OK;
        1344                 : }
        1345                 :
        1346                 : bool
        1347               0 : nsXBLBinding::AllowScripts()
        1348                 : {
        1349               0 :   if (!mPrototypeBinding->GetAllowScripts())
        1350               0 :     return false;
        1351                 :
        1352                 :   // Nasty hack.  Use the JSContext of the bound node, since the
        1353                 :   // security manager API expects to get the docshell type from
        1354                 :   // that.  But use the nsIPrincipal of our document.
        1355               0 :   nsIScriptSecurityManager* mgr = nsContentUtils::GetSecurityManager();
        1356               0 :   if (!mgr) {
        1357               0 :     return false;
        1358                 :   }
        1359                 :
        1360               0 :   nsIDocument* doc = mBoundElement ? mBoundElement->OwnerDoc() : nsnull;
        1361               0 :   if (!doc) {
        1362               0 :     return false;
        1363                 :   }
        1364                 :
        1365               0 :   nsIScriptGlobalObject* global = doc->GetScriptGlobalObject();
        1366               0 :   if (!global) {
        1367               0 :     return false;
        1368                 :   }
        1369                 :
        1370               0 :   nsCOMPtr<nsIScriptContext> context = global->GetContext();
        1371               0 :   if (!context) {
        1372               0 :     return false;
        1373                 :   }
        1374                 :
        1375               0 :   JSContext* cx = context->GetNativeContext();
        1376                 :
        1377                 :   nsCOMPtr<nsIDocument> ourDocument =
        1378               0 :     mPrototypeBinding->XBLDocumentInfo()->GetDocument();
        1379                 :   bool canExecute;
        1380                 :   nsresult rv =
        1381               0 :     mgr->CanExecuteScripts(cx, ourDocument->NodePrincipal(), &canExecute);
        1382               0 :   if (NS_FAILED(rv) || !canExecute) {
        1383               0 :     return false;
        1384                 :   }
        1385                 :
        1386                 :   // Now one last check: make sure that we're not allowing a privilege
        1387                 :   // escalation here.
        1388                 :   bool haveCert;
        1389               0 :   doc->NodePrincipal()->GetHasCertificate(&haveCert);
        1390               0 :   if (!haveCert) {
        1391               0 :     return true;
        1392                 :   }
        1393                 :
        1394                 :   bool subsumes;
        1395               0 :   rv = ourDocument->NodePrincipal()->Subsumes(doc->NodePrincipal(), &subsumes);
        1396               0 :   return NS_SUCCEEDED(rv) && subsumes;
        1397                 : }
        1398                 :
        1399                 : void
        1400               0 : nsXBLBinding::RemoveInsertionParent(nsIContent* aParent)
        1401                 : {
        1402               0 :   if (mNextBinding) {
        1403               0 :     mNextBinding->RemoveInsertionParent(aParent);
        1404                 :   }
        1405               0 :   if (mInsertionPointTable) {
        1406               0 :     nsInsertionPointList* list = nsnull;
        1407               0 :     mInsertionPointTable->Get(aParent, &list);
        1408               0 :     if (list) {
        1409               0 :       PRInt32 count = list->Length();
        1410               0 :       for (PRInt32 i = 0; i < count; ++i) {
        1411               0 :         nsRefPtr<nsXBLInsertionPoint> currPoint = list->ElementAt(i);
        1412               0 :         currPoint->UnbindDefaultContent();
        1413                 : #ifdef DEBUG
        1414               0 :         nsCOMPtr<nsIContent> parent = currPoint->GetInsertionParent();
        1415               0 :         NS_ASSERTION(!parent || parent == aParent, "Wrong insertion parent!");
        1416                 : #endif
        1417               0 :         currPoint->ClearInsertionParent();
        1418                 :       }
        1419               0 :       mInsertionPointTable->Remove(aParent);
        1420                 :     }
        1421                 :   }
        1422               0 : }
        1423                 :
        1424                 : bool
        1425               0 : nsXBLBinding::HasInsertionParent(nsIContent* aParent)
        1426                 : {
        1427               0 :   if (mInsertionPointTable) {
        1428               0 :     nsInsertionPointList* list = nsnull;
        1429               0 :     mInsertionPointTable->Get(aParent, &list);
        1430               0 :     if (list) {
        1431               0 :       return true;
        1432                 :     }
        1433                 :   }
        1434               0 :   return mNextBinding ? mNextBinding->HasInsertionParent(aParent) : false;
        1435                 : }
        1436                 :
        1437                 : nsresult
        1438               0 : nsXBLBinding::GetInsertionPointsFor(nsIContent* aParent,
        1439                 :                                     nsInsertionPointList** aResult)
        1440                 : {
        1441               0 :   if (!mInsertionPointTable) {
        1442                 :     mInsertionPointTable =
        1443               0 :       new nsClassHashtable<nsISupportsHashKey, nsInsertionPointList>;
        1444               0 :     if (!mInsertionPointTable || !mInsertionPointTable->Init(4)) {
        1445               0 :       delete mInsertionPointTable;
        1446               0 :       mInsertionPointTable = nsnull;
        1447               0 :       return NS_ERROR_OUT_OF_MEMORY;
        1448                 :     }
        1449                 :   }
        1450                 :
        1451               0 :   mInsertionPointTable->Get(aParent, aResult);
        1452                 :
        1453               0 :   if (!*aResult) {
        1454               0 :     *aResult = new nsInsertionPointList;
        1455               0 :     if (!*aResult || !mInsertionPointTable->Put(aParent, *aResult)) {
        1456               0 :       delete *aResult;
        1457               0 :       *aResult = nsnull;
        1458               0 :       return NS_ERROR_OUT_OF_MEMORY;
        1459                 :     }
        1460               0 :     if (aParent) {
        1461               0 :       aParent->SetFlags(NODE_IS_INSERTION_PARENT);
        1462                 :     }
        1463                 :   }
        1464                 :
        1465               0 :   return NS_OK;
        1466                 : }
        1467                 :
        1468                 : nsInsertionPointList*
        1469               0 : nsXBLBinding::GetExistingInsertionPointsFor(nsIContent* aParent)
        1470                 : {
        1471               0 :   if (!mInsertionPointTable) {
        1472               0 :     return nsnull;
        1473                 :   }
        1474                 :
        1475               0 :   nsInsertionPointList* result = nsnull;
        1476               0 :   mInsertionPointTable->Get(aParent, &result);
        1477               0 :   return result;
        1478                 : }
        1479                 :
        1480                 : nsIContent*
        1481               0 : nsXBLBinding::GetInsertionPoint(const nsIContent* aChild, PRUint32* aIndex)
        1482                 : {
        1483               0 :   if (mContent) {
        1484                 :     return mPrototypeBinding->GetInsertionPoint(mBoundElement, mContent,
        1485               0 :                                                 aChild, aIndex);
        1486                 :   }
        1487                 :
        1488               0 :   if (mNextBinding)
        1489               0 :     return mNextBinding->GetInsertionPoint(aChild, aIndex);
        1490                 :
        1491               0 :   return nsnull;
        1492                 : }
        1493                 :
        1494                 : nsIContent*
        1495               0 : nsXBLBinding::GetSingleInsertionPoint(PRUint32* aIndex,
        1496                 :                                       bool* aMultipleInsertionPoints)
        1497                 : {
        1498               0 :   *aMultipleInsertionPoints = false;
        1499               0 :   if (mContent) {
        1500                 :     return mPrototypeBinding->GetSingleInsertionPoint(mBoundElement, mContent,
        1501                 :                                                       aIndex,
        1502               0 :                                                       aMultipleInsertionPoints);
        1503                 :   }
        1504                 :
        1505               0 :   if (mNextBinding)
        1506                 :     return mNextBinding->GetSingleInsertionPoint(aIndex,
        1507               0 :                                                  aMultipleInsertionPoints);
        1508                 :
        1509               0 :   return nsnull;
        1510                 : }
        1511                 :
        1512                 : nsXBLBinding*
        1513               0 : nsXBLBinding::RootBinding()
        1514                 : {
        1515               0 :   if (mNextBinding)
        1516               0 :     return mNextBinding->RootBinding();
        1517                 :
        1518               0 :   return this;
        1519                 : }
        1520                 :
        1521                 : nsXBLBinding*
        1522               0 : nsXBLBinding::GetFirstStyleBinding()
        1523                 : {
        1524               0 :   if (mIsStyleBinding)
        1525               0 :     return this;
        1526                 :
        1527               0 :   return mNextBinding ? mNextBinding->GetFirstStyleBinding() : nsnull;
        1528                 : }
        1529                 :
        1530                 : bool
        1531               0 : nsXBLBinding::ResolveAllFields(JSContext *cx, JSObject *obj) const
        1532                 : {
        1533               0 :   if (!mPrototypeBinding->ResolveAllFields(cx, obj)) {
        1534               0 :     return false;
        1535                 :   }
        1536                 :
        1537               0 :   if (mNextBinding) {
        1538               0 :     return mNextBinding->ResolveAllFields(cx, obj);
        1539                 :   }
        1540                 :
        1541               0 :   return true;
        1542                 : }
        1543                 :
        1544                 : void
        1545               0 : nsXBLBinding::MarkForDeath()
        1546                 : {
        1547               0 :   mMarkedForDeath = true;
        1548               0 :   ExecuteDetachedHandler();
        1549               0 : }
        1550                 :
        1551                 : bool
        1552               0 : nsXBLBinding::ImplementsInterface(REFNSIID aIID) const
        1553                 : {
        1554               0 :   return mPrototypeBinding->ImplementsInterface(aIID) ||
        1555               0 :     (mNextBinding && mNextBinding->ImplementsInterface(aIID));
        1556                 : }
        1557                 :
        1558                 : nsINodeList*
        1559               0 : nsXBLBinding::GetAnonymousNodes()
        1560                 : {
        1561               0 :   if (mContent) {
        1562               0 :     return mContent->GetChildNodesList();
        1563                 :   }
        1564                 :
        1565               0 :   if (mNextBinding)
        1566               0 :     return mNextBinding->GetAnonymousNodes();
        1567                 :
        1568               0 :   return nsnull;
        1569            4392 : }

Generated by: LCOV version 1.7