LCOV - code coverage report
Current view: directory - content/xul/document/src - nsXULPrototypeDocument.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 326 4 1.2 %
Date: 2012-04-21 Functions: 56 3 5.4 %

       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                 :  *   Chris Waterson <waterson@netscape.com>
      24                 :  *   L. David Baron <dbaron@dbaron.org>
      25                 :  *   Ben Goodger <ben@netscape.com>
      26                 :  *   Mark Hammond <mhammond@skippinet.com.au>
      27                 :  *
      28                 :  * Alternatively, the contents of this file may be used under the terms of
      29                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      30                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      31                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      32                 :  * of those above. If you wish to allow use of your version of this file only
      33                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      34                 :  * use your version of this file under the terms of the MPL, indicate your
      35                 :  * decision by deleting the provisions above and replace them with the notice
      36                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      37                 :  * the provisions above, a recipient may use your version of this file under
      38                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      39                 :  *
      40                 :  * ***** END LICENSE BLOCK ***** */
      41                 : 
      42                 : 
      43                 : #include "nsXULPrototypeDocument.h"
      44                 : #include "nsXULDocument.h"
      45                 : 
      46                 : #include "nsAString.h"
      47                 : #include "nsIObjectInputStream.h"
      48                 : #include "nsIObjectOutputStream.h"
      49                 : #include "nsIPrincipal.h"
      50                 : #include "nsIScriptGlobalObject.h"
      51                 : #include "nsIScriptObjectPrincipal.h"
      52                 : #include "nsIScriptSecurityManager.h"
      53                 : #include "nsIScriptRuntime.h"
      54                 : #include "nsIServiceManager.h"
      55                 : #include "nsIArray.h"
      56                 : #include "nsIURI.h"
      57                 : #include "jsapi.h"
      58                 : #include "nsString.h"
      59                 : #include "nsIConsoleService.h"
      60                 : #include "nsIScriptError.h"
      61                 : #include "mozilla/FunctionTimer.h"
      62                 : #include "nsIDOMScriptObjectFactory.h"
      63                 : #include "nsDOMCID.h"
      64                 : #include "nsNodeInfoManager.h"
      65                 : #include "nsContentUtils.h"
      66                 : #include "nsCCUncollectableMarker.h"
      67                 : #include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
      68                 : #include "xpcpublic.h"
      69                 : 
      70                 : static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
      71                 :                      NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
      72                 : 
      73                 : 
      74                 : class nsXULPDGlobalObject : public nsIScriptGlobalObject,
      75                 :                             public nsIScriptObjectPrincipal
      76                 : {
      77                 : public:
      78                 :     nsXULPDGlobalObject(nsXULPrototypeDocument* owner);
      79                 : 
      80                 :     // nsISupports interface
      81               0 :     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      82                 : 
      83                 :     // nsIScriptGlobalObject methods
      84                 :     virtual void OnFinalize(JSObject* aObject);
      85                 :     virtual void SetScriptsEnabled(bool aEnabled, bool aFireTimeouts);
      86                 : 
      87                 :     virtual JSObject* GetGlobalJSObject();
      88                 :     virtual nsresult EnsureScriptEnvironment(PRUint32 aLangID);
      89                 : 
      90                 :     virtual nsIScriptContext *GetScriptContext(PRUint32 lang);
      91                 :     virtual nsresult SetScriptContext(PRUint32 language, nsIScriptContext *ctx);
      92                 : 
      93                 :     // nsIScriptObjectPrincipal methods
      94                 :     virtual nsIPrincipal* GetPrincipal();
      95                 : 
      96            1396 :     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULPDGlobalObject,
      97                 :                                              nsIScriptGlobalObject)
      98                 : 
      99                 :     void ClearGlobalObjectOwner();
     100                 : 
     101                 : protected:
     102                 :     virtual ~nsXULPDGlobalObject();
     103                 : 
     104                 :     nsXULPrototypeDocument* mGlobalObjectOwner; // weak reference
     105                 : 
     106                 :     nsCOMPtr<nsIScriptContext> mContext;
     107                 :     JSObject* mJSObject;
     108                 : 
     109                 :     nsCOMPtr<nsIPrincipal> mCachedPrincipal;
     110                 : 
     111                 :     static JSClass gSharedGlobalClass;
     112                 : };
     113                 : 
     114                 : nsIPrincipal* nsXULPrototypeDocument::gSystemPrincipal;
     115                 : nsXULPDGlobalObject* nsXULPrototypeDocument::gSystemGlobal;
     116                 : PRUint32 nsXULPrototypeDocument::gRefCnt;
     117                 : 
     118                 : 
     119                 : void
     120               0 : nsXULPDGlobalObject_finalize(JSContext *cx, JSObject *obj)
     121                 : {
     122               0 :     nsISupports *nativeThis = (nsISupports*)JS_GetPrivate(obj);
     123                 : 
     124               0 :     nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(nativeThis));
     125                 : 
     126               0 :     if (sgo) {
     127               0 :         sgo->OnFinalize(obj);
     128                 :     }
     129                 : 
     130                 :     // The addref was part of JSObject construction
     131               0 :     NS_RELEASE(nativeThis);
     132               0 : }
     133                 : 
     134                 : 
     135                 : JSBool
     136               0 : nsXULPDGlobalObject_resolve(JSContext *cx, JSObject *obj, jsid id)
     137                 : {
     138               0 :     JSBool did_resolve = JS_FALSE;
     139                 : 
     140               0 :     return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
     141                 : }
     142                 : 
     143                 : 
     144                 : JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
     145                 :     "nsXULPrototypeScript compilation scope",
     146                 :     XPCONNECT_GLOBAL_FLAGS,
     147                 :     JS_PropertyStub,  JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     148                 :     JS_EnumerateStub, nsXULPDGlobalObject_resolve,  JS_ConvertStub,
     149                 :     nsXULPDGlobalObject_finalize, NULL, NULL, NULL, NULL,
     150                 :     TraceXPCGlobal
     151                 : };
     152                 : 
     153                 : 
     154                 : 
     155                 : //----------------------------------------------------------------------
     156                 : //
     157                 : // ctors, dtors, n' stuff
     158                 : //
     159                 : 
     160               0 : nsXULPrototypeDocument::nsXULPrototypeDocument()
     161                 :     : mRoot(nsnull),
     162                 :       mLoaded(false),
     163               0 :       mCCGeneration(0)
     164                 : {
     165               0 :     ++gRefCnt;
     166               0 : }
     167                 : 
     168                 : 
     169                 : nsresult
     170               0 : nsXULPrototypeDocument::Init()
     171                 : {
     172               0 :     mNodeInfoManager = new nsNodeInfoManager();
     173               0 :     NS_ENSURE_TRUE(mNodeInfoManager, NS_ERROR_OUT_OF_MEMORY);
     174                 : 
     175               0 :     return mNodeInfoManager->Init(nsnull);
     176                 : }
     177                 : 
     178               0 : nsXULPrototypeDocument::~nsXULPrototypeDocument()
     179                 : {
     180               0 :     if (mGlobalObject) {
     181                 :         // cleaup cycles etc.
     182               0 :         mGlobalObject->ClearGlobalObjectOwner();
     183                 :     }
     184                 : 
     185               0 :     if (mRoot)
     186               0 :         mRoot->ReleaseSubtree();
     187                 : 
     188               0 :     if (--gRefCnt == 0) {
     189               0 :         NS_IF_RELEASE(gSystemPrincipal);
     190               0 :         NS_IF_RELEASE(gSystemGlobal);
     191                 :     }
     192               0 : }
     193                 : 
     194            1396 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULPrototypeDocument)
     195               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXULPrototypeDocument)
     196               0 :     tmp->mPrototypeWaiters.Clear();
     197               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     198               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULPrototypeDocument)
     199               0 :     if (nsCCUncollectableMarker::InGeneration(cb, tmp->mCCGeneration)) {
     200               0 :         return NS_SUCCESS_INTERRUPTED_TRAVERSE;
     201                 :     }
     202               0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mRoot,
     203                 :                                                     nsXULPrototypeElement)
     204               0 :     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mGlobalObject");
     205               0 :     cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObject*>(tmp->mGlobalObject));
     206               0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
     207                 :                                                     nsNodeInfoManager)
     208               0 :     for (PRUint32 i = 0; i < tmp->mPrototypeWaiters.Length(); ++i) {
     209               0 :         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mPrototypeWaiters[i]");
     210               0 :         cb.NoteXPCOMChild(static_cast<nsINode*>(tmp->mPrototypeWaiters[i].get()));
     211                 :     }
     212               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     213                 : 
     214               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULPrototypeDocument)
     215               0 :     NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObjectOwner)
     216               0 :     NS_INTERFACE_MAP_ENTRY(nsISerializable)
     217               0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObjectOwner)
     218               0 : NS_INTERFACE_MAP_END
     219                 : 
     220               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULPrototypeDocument)
     221               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULPrototypeDocument)
     222                 : 
     223                 : NS_IMETHODIMP
     224               0 : NS_NewXULPrototypeDocument(nsXULPrototypeDocument** aResult)
     225                 : {
     226               0 :     *aResult = new nsXULPrototypeDocument();
     227               0 :     if (! *aResult)
     228               0 :         return NS_ERROR_OUT_OF_MEMORY;
     229                 : 
     230                 :     nsresult rv;
     231               0 :     rv = (*aResult)->Init();
     232               0 :     if (NS_FAILED(rv)) {
     233               0 :         delete *aResult;
     234               0 :         *aResult = nsnull;
     235               0 :         return rv;
     236                 :     }
     237                 : 
     238               0 :     NS_ADDREF(*aResult);
     239               0 :     return rv;
     240                 : }
     241                 : 
     242                 : // Helper method that shares a system global among all prototype documents
     243                 : // that have the system principal as their security principal.   Called by
     244                 : // nsXULPrototypeDocument::Read and
     245                 : // nsXULPrototypeDocument::GetScriptGlobalObject.
     246                 : // This method greatly reduces the number of nsXULPDGlobalObjects and their
     247                 : // nsIScriptContexts in apps that load many XUL documents via chrome: URLs.
     248                 : 
     249                 : nsXULPDGlobalObject *
     250               0 : nsXULPrototypeDocument::NewXULPDGlobalObject()
     251                 : {
     252                 :     // Now compare DocumentPrincipal() to gSystemPrincipal, in order to create
     253                 :     // gSystemGlobal if the two pointers are equal.  Thus, gSystemGlobal
     254                 :     // implies gSystemPrincipal.
     255                 :     nsXULPDGlobalObject *global;
     256               0 :     if (DocumentPrincipal() == gSystemPrincipal) {
     257               0 :         if (!gSystemGlobal) {
     258               0 :             gSystemGlobal = new nsXULPDGlobalObject(nsnull);
     259               0 :             if (! gSystemGlobal)
     260               0 :                 return nsnull;
     261               0 :             NS_ADDREF(gSystemGlobal);
     262                 :         }
     263               0 :         global = gSystemGlobal;
     264                 :     } else {
     265               0 :         global = new nsXULPDGlobalObject(this); // does not refcount
     266               0 :         if (! global)
     267               0 :             return nsnull;
     268                 :     }
     269               0 :     return global;
     270                 : }
     271                 : 
     272                 : //----------------------------------------------------------------------
     273                 : //
     274                 : // nsISerializable methods
     275                 : //
     276                 : 
     277                 : NS_IMETHODIMP
     278               0 : nsXULPrototypeDocument::Read(nsIObjectInputStream* aStream)
     279                 : {
     280                 :     NS_TIME_FUNCTION;
     281                 :     nsresult rv;
     282                 : 
     283               0 :     rv = aStream->ReadObject(true, getter_AddRefs(mURI));
     284                 : 
     285                 :     PRUint32 count, i;
     286               0 :     nsCOMPtr<nsIURI> styleOverlayURI;
     287                 : 
     288               0 :     rv |= aStream->Read32(&count);
     289               0 :     if (NS_FAILED(rv)) return rv;
     290                 : 
     291               0 :     for (i = 0; i < count; ++i) {
     292               0 :         rv |= aStream->ReadObject(true, getter_AddRefs(styleOverlayURI));
     293               0 :         mStyleSheetReferences.AppendObject(styleOverlayURI);
     294                 :     }
     295                 : 
     296                 : 
     297                 :     // nsIPrincipal mNodeInfoManager->mPrincipal
     298               0 :     nsCOMPtr<nsIPrincipal> principal;
     299               0 :     rv |= aStream->ReadObject(true, getter_AddRefs(principal));
     300                 :     // Better safe than sorry....
     301               0 :     mNodeInfoManager->SetDocumentPrincipal(principal);
     302                 : 
     303                 : 
     304                 :     // nsIScriptGlobalObject mGlobalObject
     305               0 :     mGlobalObject = NewXULPDGlobalObject();
     306               0 :     if (! mGlobalObject)
     307               0 :         return NS_ERROR_OUT_OF_MEMORY;
     308                 : 
     309               0 :     mRoot = new nsXULPrototypeElement();
     310               0 :     if (! mRoot)
     311               0 :        return NS_ERROR_OUT_OF_MEMORY;
     312                 : 
     313                 :     // nsINodeInfo table
     314               0 :     nsCOMArray<nsINodeInfo> nodeInfos;
     315                 : 
     316               0 :     rv |= aStream->Read32(&count);
     317               0 :     nsAutoString namespaceURI, prefixStr, localName;
     318                 :     bool prefixIsNull;
     319               0 :     nsCOMPtr<nsIAtom> prefix;
     320               0 :     for (i = 0; i < count; ++i) {
     321               0 :         rv |= aStream->ReadString(namespaceURI);
     322               0 :         rv |= aStream->ReadBoolean(&prefixIsNull);
     323               0 :         if (prefixIsNull) {
     324               0 :             prefix = nsnull;
     325                 :         } else {
     326               0 :             rv |= aStream->ReadString(prefixStr);
     327               0 :             prefix = do_GetAtom(prefixStr);
     328                 :         }
     329               0 :         rv |= aStream->ReadString(localName);
     330                 : 
     331               0 :         nsCOMPtr<nsINodeInfo> nodeInfo;
     332                 :         // Using PR_UINT16_MAX here as we don't know which nodeinfos will be
     333                 :         // used for attributes and which for elements. And that doesn't really
     334                 :         // matter.
     335                 :         rv |= mNodeInfoManager->GetNodeInfo(localName, prefix, namespaceURI,
     336                 :                                             PR_UINT16_MAX,
     337               0 :                                             getter_AddRefs(nodeInfo));
     338               0 :         if (!nodeInfos.AppendObject(nodeInfo))
     339               0 :             rv |= NS_ERROR_OUT_OF_MEMORY;
     340                 :     }
     341                 : 
     342                 :     // Document contents
     343                 :     PRUint32 type;
     344               0 :     while (NS_SUCCEEDED(rv)) {
     345               0 :         rv |= aStream->Read32(&type);
     346                 : 
     347               0 :         if ((nsXULPrototypeNode::Type)type == nsXULPrototypeNode::eType_PI) {
     348               0 :             nsRefPtr<nsXULPrototypePI> pi = new nsXULPrototypePI();
     349               0 :             if (! pi) {
     350               0 :                rv |= NS_ERROR_OUT_OF_MEMORY;
     351                 :                break;
     352                 :             }
     353                 : 
     354               0 :             rv |= pi->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
     355               0 :             rv |= AddProcessingInstruction(pi);
     356               0 :         } else if ((nsXULPrototypeNode::Type)type == nsXULPrototypeNode::eType_Element) {
     357               0 :             rv |= mRoot->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
     358               0 :             break;
     359                 :         } else {
     360               0 :             NS_NOTREACHED("Unexpected prototype node type");
     361               0 :             rv |= NS_ERROR_FAILURE;
     362               0 :             break;
     363                 :         }
     364                 :     }
     365               0 :     rv |= NotifyLoadDone();
     366                 : 
     367               0 :     return rv;
     368                 : }
     369                 : 
     370                 : static nsresult
     371               0 : GetNodeInfos(nsXULPrototypeElement* aPrototype,
     372                 :              nsCOMArray<nsINodeInfo>& aArray)
     373                 : {
     374                 :     nsresult rv;
     375               0 :     if (aArray.IndexOf(aPrototype->mNodeInfo) < 0) {
     376               0 :         if (!aArray.AppendObject(aPrototype->mNodeInfo)) {
     377               0 :             return NS_ERROR_OUT_OF_MEMORY;
     378                 :         }
     379                 :     }
     380                 : 
     381                 :     // Search attributes
     382                 :     PRUint32 i;
     383               0 :     for (i = 0; i < aPrototype->mNumAttributes; ++i) {
     384               0 :         nsCOMPtr<nsINodeInfo> ni;
     385               0 :         nsAttrName* name = &aPrototype->mAttributes[i].mName;
     386               0 :         if (name->IsAtom()) {
     387                 :             ni = aPrototype->mNodeInfo->NodeInfoManager()->
     388                 :                 GetNodeInfo(name->Atom(), nsnull, kNameSpaceID_None,
     389               0 :                             nsIDOMNode::ATTRIBUTE_NODE);
     390               0 :             NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
     391                 :         }
     392                 :         else {
     393               0 :             ni = name->NodeInfo();
     394                 :         }
     395                 : 
     396               0 :         if (aArray.IndexOf(ni) < 0) {
     397               0 :             if (!aArray.AppendObject(ni)) {
     398               0 :                 return NS_ERROR_OUT_OF_MEMORY;
     399                 :             }
     400                 :         }
     401                 :     }
     402                 : 
     403                 :     // Search children
     404               0 :     for (i = 0; i < aPrototype->mChildren.Length(); ++i) {
     405               0 :         nsXULPrototypeNode* child = aPrototype->mChildren[i];
     406               0 :         if (child->mType == nsXULPrototypeNode::eType_Element) {
     407                 :             rv = GetNodeInfos(static_cast<nsXULPrototypeElement*>(child),
     408               0 :                               aArray);
     409               0 :             NS_ENSURE_SUCCESS(rv, rv);
     410                 :         }
     411                 :     }
     412                 : 
     413               0 :     return NS_OK;
     414                 : }
     415                 : 
     416                 : NS_IMETHODIMP
     417               0 : nsXULPrototypeDocument::Write(nsIObjectOutputStream* aStream)
     418                 : {
     419                 :     nsresult rv;
     420                 : 
     421               0 :     rv = aStream->WriteCompoundObject(mURI, NS_GET_IID(nsIURI), true);
     422                 :     
     423                 :     PRUint32 count;
     424                 : 
     425               0 :     count = mStyleSheetReferences.Count();
     426               0 :     rv |= aStream->Write32(count);
     427                 : 
     428                 :     PRUint32 i;
     429               0 :     for (i = 0; i < count; ++i) {
     430               0 :         rv |= aStream->WriteCompoundObject(mStyleSheetReferences[i],
     431               0 :                                            NS_GET_IID(nsIURI), true);
     432                 :     }
     433                 : 
     434                 :     // nsIPrincipal mNodeInfoManager->mPrincipal
     435               0 :     rv |= aStream->WriteObject(mNodeInfoManager->DocumentPrincipal(),
     436               0 :                                true);
     437                 :     
     438                 : #ifdef DEBUG
     439                 :     // XXX Worrisome if we're caching things without system principal.
     440               0 :     if (!nsContentUtils::IsSystemPrincipal(mNodeInfoManager->DocumentPrincipal())) {
     441               0 :         NS_WARNING("Serializing document without system principal");
     442                 :     }
     443                 : #endif
     444                 : 
     445                 :     // nsINodeInfo table
     446               0 :     nsCOMArray<nsINodeInfo> nodeInfos;
     447               0 :     if (mRoot)
     448               0 :         rv |= GetNodeInfos(mRoot, nodeInfos);
     449                 : 
     450               0 :     PRUint32 nodeInfoCount = nodeInfos.Count();
     451               0 :     rv |= aStream->Write32(nodeInfoCount);
     452               0 :     for (i = 0; i < nodeInfoCount; ++i) {
     453               0 :         nsINodeInfo *nodeInfo = nodeInfos[i];
     454               0 :         NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
     455                 : 
     456               0 :         nsAutoString namespaceURI;
     457               0 :         rv |= nodeInfo->GetNamespaceURI(namespaceURI);
     458               0 :         rv |= aStream->WriteWStringZ(namespaceURI.get());
     459                 : 
     460               0 :         nsAutoString prefix;
     461               0 :         nodeInfo->GetPrefix(prefix);
     462               0 :         bool nullPrefix = DOMStringIsNull(prefix);
     463               0 :         rv |= aStream->WriteBoolean(nullPrefix);
     464               0 :         if (!nullPrefix) {
     465               0 :             rv |= aStream->WriteWStringZ(prefix.get());
     466                 :         }
     467                 : 
     468               0 :         nsAutoString localName;
     469               0 :         nodeInfo->GetName(localName);
     470               0 :         rv |= aStream->WriteWStringZ(localName.get());
     471                 :     }
     472                 : 
     473                 :     // Now serialize the document contents
     474               0 :     nsIScriptGlobalObject* globalObject = GetScriptGlobalObject();
     475               0 :     NS_ENSURE_TRUE(globalObject, NS_ERROR_UNEXPECTED);
     476                 : 
     477               0 :     count = mProcessingInstructions.Length();
     478               0 :     for (i = 0; i < count; ++i) {
     479               0 :         nsXULPrototypePI* pi = mProcessingInstructions[i];
     480               0 :         rv |= pi->Serialize(aStream, globalObject, &nodeInfos);
     481                 :     }
     482                 : 
     483               0 :     if (mRoot)
     484               0 :         rv |= mRoot->Serialize(aStream, globalObject, &nodeInfos);
     485                 :  
     486               0 :     return rv;
     487                 : }
     488                 : 
     489                 : 
     490                 : //----------------------------------------------------------------------
     491                 : //
     492                 : 
     493                 : nsresult
     494               0 : nsXULPrototypeDocument::InitPrincipal(nsIURI* aURI, nsIPrincipal* aPrincipal)
     495                 : {
     496               0 :     NS_ENSURE_ARG_POINTER(aURI);
     497                 : 
     498               0 :     mURI = aURI;
     499               0 :     mNodeInfoManager->SetDocumentPrincipal(aPrincipal);
     500               0 :     return NS_OK;
     501                 : }
     502                 :     
     503                 : 
     504                 : nsIURI*
     505               0 : nsXULPrototypeDocument::GetURI()
     506                 : {
     507               0 :     NS_ASSERTION(mURI, "null URI");
     508               0 :     return mURI;
     509                 : }
     510                 : 
     511                 : 
     512                 : nsXULPrototypeElement*
     513               0 : nsXULPrototypeDocument::GetRootElement()
     514                 : {
     515               0 :     return mRoot;
     516                 : }
     517                 : 
     518                 : 
     519                 : void
     520               0 : nsXULPrototypeDocument::SetRootElement(nsXULPrototypeElement* aElement)
     521                 : {
     522               0 :     mRoot = aElement;
     523               0 : }
     524                 : 
     525                 : nsresult
     526               0 : nsXULPrototypeDocument::AddProcessingInstruction(nsXULPrototypePI* aPI)
     527                 : {
     528               0 :     NS_PRECONDITION(aPI, "null ptr");
     529               0 :     if (!mProcessingInstructions.AppendElement(aPI)) {
     530               0 :         return NS_ERROR_OUT_OF_MEMORY;
     531                 :     }
     532               0 :     return NS_OK;
     533                 : }
     534                 : 
     535                 : const nsTArray<nsRefPtr<nsXULPrototypePI> >&
     536               0 : nsXULPrototypeDocument::GetProcessingInstructions() const
     537                 : {
     538               0 :     return mProcessingInstructions;
     539                 : }
     540                 : 
     541                 : void
     542               0 : nsXULPrototypeDocument::AddStyleSheetReference(nsIURI* aURI)
     543                 : {
     544               0 :     NS_PRECONDITION(aURI, "null ptr");
     545               0 :     if (!mStyleSheetReferences.AppendObject(aURI)) {
     546                 :         NS_WARNING("mStyleSheetReferences->AppendElement() failed."
     547               0 :                    "Stylesheet overlay dropped.");
     548                 :     }
     549               0 : }
     550                 : 
     551                 : const nsCOMArray<nsIURI>&
     552               0 : nsXULPrototypeDocument::GetStyleSheetReferences() const
     553                 : {
     554               0 :     return mStyleSheetReferences;
     555                 : }
     556                 : 
     557                 : NS_IMETHODIMP
     558               0 : nsXULPrototypeDocument::GetHeaderData(nsIAtom* aField, nsAString& aData) const
     559                 : {
     560                 :     // XXX Not implemented
     561               0 :     aData.Truncate();
     562               0 :     return NS_OK;
     563                 : }
     564                 : 
     565                 : 
     566                 : NS_IMETHODIMP
     567               0 : nsXULPrototypeDocument::SetHeaderData(nsIAtom* aField, const nsAString& aData)
     568                 : {
     569                 :     // XXX Not implemented
     570               0 :     return NS_OK;
     571                 : }
     572                 : 
     573                 : 
     574                 : 
     575                 : nsIPrincipal*
     576               0 : nsXULPrototypeDocument::DocumentPrincipal()
     577                 : {
     578               0 :     NS_PRECONDITION(mNodeInfoManager, "missing nodeInfoManager");
     579               0 :     return mNodeInfoManager->DocumentPrincipal();
     580                 : }
     581                 : 
     582                 : void
     583               0 : nsXULPrototypeDocument::SetDocumentPrincipal(nsIPrincipal* aPrincipal)
     584                 : {
     585               0 :     mNodeInfoManager->SetDocumentPrincipal(aPrincipal);
     586               0 : }
     587                 : 
     588                 : nsNodeInfoManager*
     589               0 : nsXULPrototypeDocument::GetNodeInfoManager()
     590                 : {
     591               0 :     return mNodeInfoManager;
     592                 : }
     593                 : 
     594                 : 
     595                 : nsresult
     596               0 : nsXULPrototypeDocument::AwaitLoadDone(nsXULDocument* aDocument, bool* aResult)
     597                 : {
     598               0 :     nsresult rv = NS_OK;
     599                 : 
     600               0 :     *aResult = mLoaded;
     601                 : 
     602               0 :     if (!mLoaded) {
     603               0 :         rv = mPrototypeWaiters.AppendElement(aDocument)
     604               0 :               ? NS_OK : NS_ERROR_OUT_OF_MEMORY; // addrefs
     605                 :     }
     606                 : 
     607               0 :     return rv;
     608                 : }
     609                 : 
     610                 : 
     611                 : nsresult
     612               0 : nsXULPrototypeDocument::NotifyLoadDone()
     613                 : {
     614                 :     // Call back to each XUL document that raced to start the same
     615                 :     // prototype document load, lost the race, but hit the XUL
     616                 :     // prototype cache because the winner filled the cache with
     617                 :     // the not-yet-loaded prototype object.
     618                 : 
     619               0 :     nsresult rv = NS_OK;
     620                 : 
     621               0 :     mLoaded = true;
     622                 : 
     623               0 :     for (PRUint32 i = mPrototypeWaiters.Length(); i > 0; ) {
     624               0 :         --i;
     625                 :         // true means that OnPrototypeLoadDone will also
     626                 :         // call ResumeWalk().
     627               0 :         rv = mPrototypeWaiters[i]->OnPrototypeLoadDone(true);
     628               0 :         if (NS_FAILED(rv)) break;
     629                 :     }
     630               0 :     mPrototypeWaiters.Clear();
     631                 : 
     632               0 :     return rv;
     633                 : }
     634                 : 
     635                 : //----------------------------------------------------------------------
     636                 : //
     637                 : // nsIScriptGlobalObjectOwner methods
     638                 : //
     639                 : 
     640                 : nsIScriptGlobalObject*
     641               0 : nsXULPrototypeDocument::GetScriptGlobalObject()
     642                 : {
     643               0 :     if (!mGlobalObject)
     644               0 :         mGlobalObject = NewXULPDGlobalObject();
     645                 : 
     646               0 :     return mGlobalObject;
     647                 : }
     648                 : 
     649                 : //----------------------------------------------------------------------
     650                 : //
     651                 : // nsXULPDGlobalObject
     652                 : //
     653                 : 
     654               0 : nsXULPDGlobalObject::nsXULPDGlobalObject(nsXULPrototypeDocument* owner)
     655                 :   : mGlobalObjectOwner(owner)
     656               0 :   , mJSObject(NULL)
     657                 : {
     658               0 : }
     659                 : 
     660                 : 
     661               0 : nsXULPDGlobalObject::~nsXULPDGlobalObject()
     662                 : {
     663               0 : }
     664                 : 
     665            1396 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULPDGlobalObject)
     666               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsXULPDGlobalObject)
     667               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULPDGlobalObject)
     668               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
     669               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     670                 : 
     671               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULPDGlobalObject)
     672               0 :   NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
     673               0 :   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
     674               0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObject)
     675               0 : NS_INTERFACE_MAP_END
     676                 : 
     677               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULPDGlobalObject)
     678               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULPDGlobalObject)
     679                 : 
     680                 : //----------------------------------------------------------------------
     681                 : //
     682                 : // nsIScriptGlobalObject methods
     683                 : //
     684                 : 
     685                 : nsresult
     686               0 : nsXULPDGlobalObject::SetScriptContext(PRUint32 lang_id, nsIScriptContext *aScriptContext)
     687                 : {
     688               0 :   NS_ABORT_IF_FALSE(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
     689                 :                     "We don't support this language ID");
     690                 :   // almost a clone of nsGlobalWindow
     691               0 :   if (!aScriptContext) {
     692               0 :     NS_WARNING("Possibly early removal of script object, see bug #41608");
     693                 :   } else {
     694                 :     // should probably assert the context is clean???
     695               0 :     aScriptContext->WillInitializeContext();
     696               0 :     nsresult rv = aScriptContext->InitContext();
     697               0 :     NS_ENSURE_SUCCESS(rv, rv);
     698                 :   }
     699                 : 
     700               0 :   NS_ASSERTION(!aScriptContext || !mContext, "Bad call to SetContext()!");
     701                 : 
     702               0 :   JSObject* global = NULL;
     703                 : 
     704               0 :   if (aScriptContext) {
     705               0 :     aScriptContext->SetGCOnDestruction(false);
     706               0 :     aScriptContext->DidInitializeContext();
     707               0 :     global = aScriptContext->GetNativeGlobal();
     708               0 :     NS_ASSERTION(global, "GetNativeGlobal returned NULL!");
     709                 :   }
     710               0 :   mContext = aScriptContext;
     711               0 :   mJSObject = global;
     712               0 :   return NS_OK;
     713                 : }
     714                 : 
     715                 : nsresult
     716               0 : nsXULPDGlobalObject::EnsureScriptEnvironment(PRUint32 lang_id)
     717                 : {
     718               0 :   NS_ABORT_IF_FALSE(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
     719                 :                     "We don't support this language ID");
     720               0 :   if (mContext) {
     721               0 :     return NS_OK;
     722                 :   }
     723               0 :   NS_ASSERTION(!mJSObject, "Have global without context?");
     724                 : 
     725               0 :   nsCOMPtr<nsIScriptRuntime> languageRuntime;
     726                 :   nsresult rv = NS_GetScriptRuntimeByID(nsIProgrammingLanguage::JAVASCRIPT,
     727               0 :                                         getter_AddRefs(languageRuntime));
     728               0 :   NS_ENSURE_SUCCESS(rv, NS_OK);
     729                 : 
     730               0 :   nsCOMPtr<nsIScriptContext> ctxNew = languageRuntime->CreateContext();
     731                 :   // We have to setup a special global object.  We do this then
     732                 :   // attach it as the global for this context.  Then, ::SetScriptContext
     733                 :   // will re-fetch the global and set it up in our language globals array.
     734                 :   {
     735               0 :     JSContext *cx = ctxNew->GetNativeContext();
     736               0 :     JSAutoRequest ar(cx);
     737                 : 
     738               0 :     nsIPrincipal *principal = GetPrincipal();
     739                 :     JSObject *newGlob;
     740                 :     JSCompartment *compartment;
     741                 : 
     742                 :     rv = xpc_CreateGlobalObject(cx, &gSharedGlobalClass, principal, nsnull,
     743               0 :                                 false, &newGlob, &compartment);
     744               0 :     NS_ENSURE_SUCCESS(rv, NS_OK);
     745                 : 
     746               0 :     ::JS_SetGlobalObject(cx, newGlob);
     747                 : 
     748                 :     // Add an owning reference from JS back to us. This'll be
     749                 :     // released when the JSObject is finalized.
     750               0 :     ::JS_SetPrivate(newGlob, this);
     751               0 :     NS_ADDREF(this);
     752                 :   }
     753                 : 
     754               0 :   NS_ENSURE_SUCCESS(rv, NS_OK);
     755               0 :   rv = SetScriptContext(lang_id, ctxNew);
     756               0 :   NS_ENSURE_SUCCESS(rv, NS_OK);
     757               0 :   return NS_OK;
     758                 : }
     759                 : 
     760                 : nsIScriptContext*
     761               0 : nsXULPDGlobalObject::GetScriptContext(PRUint32 lang_id)
     762                 : {
     763               0 :   NS_ABORT_IF_FALSE(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
     764                 :                     "We don't support this language ID");
     765                 :   // This global object creates a context on demand - do that now.
     766               0 :   nsresult rv = EnsureScriptEnvironment(nsIProgrammingLanguage::JAVASCRIPT);
     767               0 :   if (NS_FAILED(rv)) {
     768               0 :     NS_ERROR("Failed to setup script language");
     769               0 :     return NULL;
     770                 :   }
     771                 :   // Note that EnsureScriptEnvironment has validated lang_id
     772               0 :   return mContext;
     773                 : }
     774                 : 
     775                 : JSObject*
     776               0 : nsXULPDGlobalObject::GetGlobalJSObject()
     777                 : {
     778               0 :   return mJSObject;
     779                 : }
     780                 : 
     781                 : 
     782                 : void
     783               0 : nsXULPDGlobalObject::ClearGlobalObjectOwner()
     784                 : {
     785               0 :   NS_ASSERTION(!mCachedPrincipal, "This shouldn't ever be set until now!");
     786                 : 
     787                 :   // Cache mGlobalObjectOwner's principal if possible.
     788               0 :   if (this != nsXULPrototypeDocument::gSystemGlobal)
     789               0 :     mCachedPrincipal = mGlobalObjectOwner->DocumentPrincipal();
     790                 : 
     791               0 :   mContext = NULL;
     792               0 :   mGlobalObjectOwner = NULL;
     793               0 : }
     794                 : 
     795                 : 
     796                 : void
     797               0 : nsXULPDGlobalObject::OnFinalize(JSObject* aObject)
     798                 : {
     799               0 :   mJSObject = NULL;
     800               0 : }
     801                 : 
     802                 : void
     803               0 : nsXULPDGlobalObject::SetScriptsEnabled(bool aEnabled, bool aFireTimeouts)
     804                 : {
     805                 :   // We don't care...
     806               0 : }
     807                 : 
     808                 : //----------------------------------------------------------------------
     809                 : //
     810                 : // nsIScriptObjectPrincipal methods
     811                 : //
     812                 : 
     813                 : nsIPrincipal*
     814               0 : nsXULPDGlobalObject::GetPrincipal()
     815                 : {
     816               0 :     if (!mGlobalObjectOwner) {
     817                 :         // See nsXULPrototypeDocument::NewXULPDGlobalObject, the comment
     818                 :         // about gSystemGlobal implying gSystemPrincipal.
     819               0 :         if (this == nsXULPrototypeDocument::gSystemGlobal) {
     820               0 :             return nsXULPrototypeDocument::gSystemPrincipal;
     821                 :         }
     822                 :         // Return the cached principal if it exists.
     823               0 :         return mCachedPrincipal;
     824                 :     }
     825                 : 
     826               0 :     return mGlobalObjectOwner->DocumentPrincipal();
     827            4188 : }

Generated by: LCOV version 1.7