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-06-02 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            1464 :     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            1464 : 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_NSCOMPTR(mRoot)
     203               0 :     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mGlobalObject");
     204               0 :     cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObject*>(tmp->mGlobalObject));
     205               0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
     206                 :                                                     nsNodeInfoManager)
     207               0 :     for (PRUint32 i = 0; i < tmp->mPrototypeWaiters.Length(); ++i) {
     208               0 :         NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mPrototypeWaiters[i]");
     209               0 :         cb.NoteXPCOMChild(static_cast<nsINode*>(tmp->mPrototypeWaiters[i].get()));
     210                 :     }
     211               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     212                 : 
     213               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULPrototypeDocument)
     214               0 :     NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObjectOwner)
     215               0 :     NS_INTERFACE_MAP_ENTRY(nsISerializable)
     216               0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObjectOwner)
     217               0 : NS_INTERFACE_MAP_END
     218                 : 
     219               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULPrototypeDocument)
     220               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULPrototypeDocument)
     221                 : 
     222                 : NS_IMETHODIMP
     223               0 : NS_NewXULPrototypeDocument(nsXULPrototypeDocument** aResult)
     224                 : {
     225               0 :     *aResult = new nsXULPrototypeDocument();
     226               0 :     if (! *aResult)
     227               0 :         return NS_ERROR_OUT_OF_MEMORY;
     228                 : 
     229                 :     nsresult rv;
     230               0 :     rv = (*aResult)->Init();
     231               0 :     if (NS_FAILED(rv)) {
     232               0 :         delete *aResult;
     233               0 :         *aResult = nsnull;
     234               0 :         return rv;
     235                 :     }
     236                 : 
     237               0 :     NS_ADDREF(*aResult);
     238               0 :     return rv;
     239                 : }
     240                 : 
     241                 : // Helper method that shares a system global among all prototype documents
     242                 : // that have the system principal as their security principal.   Called by
     243                 : // nsXULPrototypeDocument::Read and
     244                 : // nsXULPrototypeDocument::GetScriptGlobalObject.
     245                 : // This method greatly reduces the number of nsXULPDGlobalObjects and their
     246                 : // nsIScriptContexts in apps that load many XUL documents via chrome: URLs.
     247                 : 
     248                 : nsXULPDGlobalObject *
     249               0 : nsXULPrototypeDocument::NewXULPDGlobalObject()
     250                 : {
     251                 :     // Now compare DocumentPrincipal() to gSystemPrincipal, in order to create
     252                 :     // gSystemGlobal if the two pointers are equal.  Thus, gSystemGlobal
     253                 :     // implies gSystemPrincipal.
     254                 :     nsXULPDGlobalObject *global;
     255               0 :     if (DocumentPrincipal() == gSystemPrincipal) {
     256               0 :         if (!gSystemGlobal) {
     257               0 :             gSystemGlobal = new nsXULPDGlobalObject(nsnull);
     258               0 :             if (! gSystemGlobal)
     259               0 :                 return nsnull;
     260               0 :             NS_ADDREF(gSystemGlobal);
     261                 :         }
     262               0 :         global = gSystemGlobal;
     263                 :     } else {
     264               0 :         global = new nsXULPDGlobalObject(this); // does not refcount
     265               0 :         if (! global)
     266               0 :             return nsnull;
     267                 :     }
     268               0 :     return global;
     269                 : }
     270                 : 
     271                 : //----------------------------------------------------------------------
     272                 : //
     273                 : // nsISerializable methods
     274                 : //
     275                 : 
     276                 : NS_IMETHODIMP
     277               0 : nsXULPrototypeDocument::Read(nsIObjectInputStream* aStream)
     278                 : {
     279                 :     NS_TIME_FUNCTION;
     280                 :     nsresult rv;
     281                 : 
     282               0 :     rv = aStream->ReadObject(true, getter_AddRefs(mURI));
     283                 : 
     284                 :     PRUint32 count, i;
     285               0 :     nsCOMPtr<nsIURI> styleOverlayURI;
     286                 : 
     287               0 :     rv |= aStream->Read32(&count);
     288               0 :     if (NS_FAILED(rv)) return rv;
     289                 : 
     290               0 :     for (i = 0; i < count; ++i) {
     291               0 :         rv |= aStream->ReadObject(true, getter_AddRefs(styleOverlayURI));
     292               0 :         mStyleSheetReferences.AppendObject(styleOverlayURI);
     293                 :     }
     294                 : 
     295                 : 
     296                 :     // nsIPrincipal mNodeInfoManager->mPrincipal
     297               0 :     nsCOMPtr<nsIPrincipal> principal;
     298               0 :     rv |= aStream->ReadObject(true, getter_AddRefs(principal));
     299                 :     // Better safe than sorry....
     300               0 :     mNodeInfoManager->SetDocumentPrincipal(principal);
     301                 : 
     302                 : 
     303                 :     // nsIScriptGlobalObject mGlobalObject
     304               0 :     mGlobalObject = NewXULPDGlobalObject();
     305               0 :     if (! mGlobalObject)
     306               0 :         return NS_ERROR_OUT_OF_MEMORY;
     307                 : 
     308               0 :     mRoot = new nsXULPrototypeElement();
     309               0 :     if (! mRoot)
     310               0 :        return NS_ERROR_OUT_OF_MEMORY;
     311                 : 
     312                 :     // nsINodeInfo table
     313               0 :     nsCOMArray<nsINodeInfo> nodeInfos;
     314                 : 
     315               0 :     rv |= aStream->Read32(&count);
     316               0 :     nsAutoString namespaceURI, prefixStr, localName;
     317                 :     bool prefixIsNull;
     318               0 :     nsCOMPtr<nsIAtom> prefix;
     319               0 :     for (i = 0; i < count; ++i) {
     320               0 :         rv |= aStream->ReadString(namespaceURI);
     321               0 :         rv |= aStream->ReadBoolean(&prefixIsNull);
     322               0 :         if (prefixIsNull) {
     323               0 :             prefix = nsnull;
     324                 :         } else {
     325               0 :             rv |= aStream->ReadString(prefixStr);
     326               0 :             prefix = do_GetAtom(prefixStr);
     327                 :         }
     328               0 :         rv |= aStream->ReadString(localName);
     329                 : 
     330               0 :         nsCOMPtr<nsINodeInfo> nodeInfo;
     331                 :         // Using PR_UINT16_MAX here as we don't know which nodeinfos will be
     332                 :         // used for attributes and which for elements. And that doesn't really
     333                 :         // matter.
     334                 :         rv |= mNodeInfoManager->GetNodeInfo(localName, prefix, namespaceURI,
     335                 :                                             PR_UINT16_MAX,
     336               0 :                                             getter_AddRefs(nodeInfo));
     337               0 :         if (!nodeInfos.AppendObject(nodeInfo))
     338               0 :             rv |= NS_ERROR_OUT_OF_MEMORY;
     339                 :     }
     340                 : 
     341                 :     // Document contents
     342                 :     PRUint32 type;
     343               0 :     while (NS_SUCCEEDED(rv)) {
     344               0 :         rv |= aStream->Read32(&type);
     345                 : 
     346               0 :         if ((nsXULPrototypeNode::Type)type == nsXULPrototypeNode::eType_PI) {
     347               0 :             nsRefPtr<nsXULPrototypePI> pi = new nsXULPrototypePI();
     348               0 :             if (! pi) {
     349               0 :                rv |= NS_ERROR_OUT_OF_MEMORY;
     350                 :                break;
     351                 :             }
     352                 : 
     353               0 :             rv |= pi->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
     354               0 :             rv |= AddProcessingInstruction(pi);
     355               0 :         } else if ((nsXULPrototypeNode::Type)type == nsXULPrototypeNode::eType_Element) {
     356               0 :             rv |= mRoot->Deserialize(aStream, mGlobalObject, mURI, &nodeInfos);
     357               0 :             break;
     358                 :         } else {
     359               0 :             NS_NOTREACHED("Unexpected prototype node type");
     360               0 :             rv |= NS_ERROR_FAILURE;
     361               0 :             break;
     362                 :         }
     363                 :     }
     364               0 :     rv |= NotifyLoadDone();
     365                 : 
     366               0 :     return rv;
     367                 : }
     368                 : 
     369                 : static nsresult
     370               0 : GetNodeInfos(nsXULPrototypeElement* aPrototype,
     371                 :              nsCOMArray<nsINodeInfo>& aArray)
     372                 : {
     373                 :     nsresult rv;
     374               0 :     if (aArray.IndexOf(aPrototype->mNodeInfo) < 0) {
     375               0 :         if (!aArray.AppendObject(aPrototype->mNodeInfo)) {
     376               0 :             return NS_ERROR_OUT_OF_MEMORY;
     377                 :         }
     378                 :     }
     379                 : 
     380                 :     // Search attributes
     381                 :     PRUint32 i;
     382               0 :     for (i = 0; i < aPrototype->mNumAttributes; ++i) {
     383               0 :         nsCOMPtr<nsINodeInfo> ni;
     384               0 :         nsAttrName* name = &aPrototype->mAttributes[i].mName;
     385               0 :         if (name->IsAtom()) {
     386                 :             ni = aPrototype->mNodeInfo->NodeInfoManager()->
     387                 :                 GetNodeInfo(name->Atom(), nsnull, kNameSpaceID_None,
     388               0 :                             nsIDOMNode::ATTRIBUTE_NODE);
     389               0 :             NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
     390                 :         }
     391                 :         else {
     392               0 :             ni = name->NodeInfo();
     393                 :         }
     394                 : 
     395               0 :         if (aArray.IndexOf(ni) < 0) {
     396               0 :             if (!aArray.AppendObject(ni)) {
     397               0 :                 return NS_ERROR_OUT_OF_MEMORY;
     398                 :             }
     399                 :         }
     400                 :     }
     401                 : 
     402                 :     // Search children
     403               0 :     for (i = 0; i < aPrototype->mChildren.Length(); ++i) {
     404               0 :         nsXULPrototypeNode* child = aPrototype->mChildren[i];
     405               0 :         if (child->mType == nsXULPrototypeNode::eType_Element) {
     406                 :             rv = GetNodeInfos(static_cast<nsXULPrototypeElement*>(child),
     407               0 :                               aArray);
     408               0 :             NS_ENSURE_SUCCESS(rv, rv);
     409                 :         }
     410                 :     }
     411                 : 
     412               0 :     return NS_OK;
     413                 : }
     414                 : 
     415                 : NS_IMETHODIMP
     416               0 : nsXULPrototypeDocument::Write(nsIObjectOutputStream* aStream)
     417                 : {
     418                 :     nsresult rv;
     419                 : 
     420               0 :     rv = aStream->WriteCompoundObject(mURI, NS_GET_IID(nsIURI), true);
     421                 :     
     422                 :     PRUint32 count;
     423                 : 
     424               0 :     count = mStyleSheetReferences.Count();
     425               0 :     rv |= aStream->Write32(count);
     426                 : 
     427                 :     PRUint32 i;
     428               0 :     for (i = 0; i < count; ++i) {
     429               0 :         rv |= aStream->WriteCompoundObject(mStyleSheetReferences[i],
     430               0 :                                            NS_GET_IID(nsIURI), true);
     431                 :     }
     432                 : 
     433                 :     // nsIPrincipal mNodeInfoManager->mPrincipal
     434               0 :     rv |= aStream->WriteObject(mNodeInfoManager->DocumentPrincipal(),
     435               0 :                                true);
     436                 :     
     437                 : #ifdef DEBUG
     438                 :     // XXX Worrisome if we're caching things without system principal.
     439               0 :     if (!nsContentUtils::IsSystemPrincipal(mNodeInfoManager->DocumentPrincipal())) {
     440               0 :         NS_WARNING("Serializing document without system principal");
     441                 :     }
     442                 : #endif
     443                 : 
     444                 :     // nsINodeInfo table
     445               0 :     nsCOMArray<nsINodeInfo> nodeInfos;
     446               0 :     if (mRoot)
     447               0 :         rv |= GetNodeInfos(mRoot, nodeInfos);
     448                 : 
     449               0 :     PRUint32 nodeInfoCount = nodeInfos.Count();
     450               0 :     rv |= aStream->Write32(nodeInfoCount);
     451               0 :     for (i = 0; i < nodeInfoCount; ++i) {
     452               0 :         nsINodeInfo *nodeInfo = nodeInfos[i];
     453               0 :         NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
     454                 : 
     455               0 :         nsAutoString namespaceURI;
     456               0 :         rv |= nodeInfo->GetNamespaceURI(namespaceURI);
     457               0 :         rv |= aStream->WriteWStringZ(namespaceURI.get());
     458                 : 
     459               0 :         nsAutoString prefix;
     460               0 :         nodeInfo->GetPrefix(prefix);
     461               0 :         bool nullPrefix = DOMStringIsNull(prefix);
     462               0 :         rv |= aStream->WriteBoolean(nullPrefix);
     463               0 :         if (!nullPrefix) {
     464               0 :             rv |= aStream->WriteWStringZ(prefix.get());
     465                 :         }
     466                 : 
     467               0 :         nsAutoString localName;
     468               0 :         nodeInfo->GetName(localName);
     469               0 :         rv |= aStream->WriteWStringZ(localName.get());
     470                 :     }
     471                 : 
     472                 :     // Now serialize the document contents
     473               0 :     nsIScriptGlobalObject* globalObject = GetScriptGlobalObject();
     474               0 :     NS_ENSURE_TRUE(globalObject, NS_ERROR_UNEXPECTED);
     475                 : 
     476               0 :     count = mProcessingInstructions.Length();
     477               0 :     for (i = 0; i < count; ++i) {
     478               0 :         nsXULPrototypePI* pi = mProcessingInstructions[i];
     479               0 :         rv |= pi->Serialize(aStream, globalObject, &nodeInfos);
     480                 :     }
     481                 : 
     482               0 :     if (mRoot)
     483               0 :         rv |= mRoot->Serialize(aStream, globalObject, &nodeInfos);
     484                 :  
     485               0 :     return rv;
     486                 : }
     487                 : 
     488                 : 
     489                 : //----------------------------------------------------------------------
     490                 : //
     491                 : 
     492                 : nsresult
     493               0 : nsXULPrototypeDocument::InitPrincipal(nsIURI* aURI, nsIPrincipal* aPrincipal)
     494                 : {
     495               0 :     NS_ENSURE_ARG_POINTER(aURI);
     496                 : 
     497               0 :     mURI = aURI;
     498               0 :     mNodeInfoManager->SetDocumentPrincipal(aPrincipal);
     499               0 :     return NS_OK;
     500                 : }
     501                 :     
     502                 : 
     503                 : nsIURI*
     504               0 : nsXULPrototypeDocument::GetURI()
     505                 : {
     506               0 :     NS_ASSERTION(mURI, "null URI");
     507               0 :     return mURI;
     508                 : }
     509                 : 
     510                 : 
     511                 : nsXULPrototypeElement*
     512               0 : nsXULPrototypeDocument::GetRootElement()
     513                 : {
     514               0 :     return mRoot;
     515                 : }
     516                 : 
     517                 : 
     518                 : void
     519               0 : nsXULPrototypeDocument::SetRootElement(nsXULPrototypeElement* aElement)
     520                 : {
     521               0 :     mRoot = aElement;
     522               0 : }
     523                 : 
     524                 : nsresult
     525               0 : nsXULPrototypeDocument::AddProcessingInstruction(nsXULPrototypePI* aPI)
     526                 : {
     527               0 :     NS_PRECONDITION(aPI, "null ptr");
     528               0 :     if (!mProcessingInstructions.AppendElement(aPI)) {
     529               0 :         return NS_ERROR_OUT_OF_MEMORY;
     530                 :     }
     531               0 :     return NS_OK;
     532                 : }
     533                 : 
     534                 : const nsTArray<nsRefPtr<nsXULPrototypePI> >&
     535               0 : nsXULPrototypeDocument::GetProcessingInstructions() const
     536                 : {
     537               0 :     return mProcessingInstructions;
     538                 : }
     539                 : 
     540                 : void
     541               0 : nsXULPrototypeDocument::AddStyleSheetReference(nsIURI* aURI)
     542                 : {
     543               0 :     NS_PRECONDITION(aURI, "null ptr");
     544               0 :     if (!mStyleSheetReferences.AppendObject(aURI)) {
     545                 :         NS_WARNING("mStyleSheetReferences->AppendElement() failed."
     546               0 :                    "Stylesheet overlay dropped.");
     547                 :     }
     548               0 : }
     549                 : 
     550                 : const nsCOMArray<nsIURI>&
     551               0 : nsXULPrototypeDocument::GetStyleSheetReferences() const
     552                 : {
     553               0 :     return mStyleSheetReferences;
     554                 : }
     555                 : 
     556                 : NS_IMETHODIMP
     557               0 : nsXULPrototypeDocument::GetHeaderData(nsIAtom* aField, nsAString& aData) const
     558                 : {
     559                 :     // XXX Not implemented
     560               0 :     aData.Truncate();
     561               0 :     return NS_OK;
     562                 : }
     563                 : 
     564                 : 
     565                 : NS_IMETHODIMP
     566               0 : nsXULPrototypeDocument::SetHeaderData(nsIAtom* aField, const nsAString& aData)
     567                 : {
     568                 :     // XXX Not implemented
     569               0 :     return NS_OK;
     570                 : }
     571                 : 
     572                 : 
     573                 : 
     574                 : nsIPrincipal*
     575               0 : nsXULPrototypeDocument::DocumentPrincipal()
     576                 : {
     577               0 :     NS_PRECONDITION(mNodeInfoManager, "missing nodeInfoManager");
     578               0 :     return mNodeInfoManager->DocumentPrincipal();
     579                 : }
     580                 : 
     581                 : void
     582               0 : nsXULPrototypeDocument::SetDocumentPrincipal(nsIPrincipal* aPrincipal)
     583                 : {
     584               0 :     mNodeInfoManager->SetDocumentPrincipal(aPrincipal);
     585               0 : }
     586                 : 
     587                 : nsNodeInfoManager*
     588               0 : nsXULPrototypeDocument::GetNodeInfoManager()
     589                 : {
     590               0 :     return mNodeInfoManager;
     591                 : }
     592                 : 
     593                 : 
     594                 : nsresult
     595               0 : nsXULPrototypeDocument::AwaitLoadDone(nsXULDocument* aDocument, bool* aResult)
     596                 : {
     597               0 :     nsresult rv = NS_OK;
     598                 : 
     599               0 :     *aResult = mLoaded;
     600                 : 
     601               0 :     if (!mLoaded) {
     602               0 :         rv = mPrototypeWaiters.AppendElement(aDocument)
     603               0 :               ? NS_OK : NS_ERROR_OUT_OF_MEMORY; // addrefs
     604                 :     }
     605                 : 
     606               0 :     return rv;
     607                 : }
     608                 : 
     609                 : 
     610                 : nsresult
     611               0 : nsXULPrototypeDocument::NotifyLoadDone()
     612                 : {
     613                 :     // Call back to each XUL document that raced to start the same
     614                 :     // prototype document load, lost the race, but hit the XUL
     615                 :     // prototype cache because the winner filled the cache with
     616                 :     // the not-yet-loaded prototype object.
     617                 : 
     618               0 :     nsresult rv = NS_OK;
     619                 : 
     620               0 :     mLoaded = true;
     621                 : 
     622               0 :     for (PRUint32 i = mPrototypeWaiters.Length(); i > 0; ) {
     623               0 :         --i;
     624                 :         // true means that OnPrototypeLoadDone will also
     625                 :         // call ResumeWalk().
     626               0 :         rv = mPrototypeWaiters[i]->OnPrototypeLoadDone(true);
     627               0 :         if (NS_FAILED(rv)) break;
     628                 :     }
     629               0 :     mPrototypeWaiters.Clear();
     630                 : 
     631               0 :     return rv;
     632                 : }
     633                 : 
     634                 : //----------------------------------------------------------------------
     635                 : //
     636                 : // nsIScriptGlobalObjectOwner methods
     637                 : //
     638                 : 
     639                 : nsIScriptGlobalObject*
     640               0 : nsXULPrototypeDocument::GetScriptGlobalObject()
     641                 : {
     642               0 :     if (!mGlobalObject)
     643               0 :         mGlobalObject = NewXULPDGlobalObject();
     644                 : 
     645               0 :     return mGlobalObject;
     646                 : }
     647                 : 
     648                 : //----------------------------------------------------------------------
     649                 : //
     650                 : // nsXULPDGlobalObject
     651                 : //
     652                 : 
     653               0 : nsXULPDGlobalObject::nsXULPDGlobalObject(nsXULPrototypeDocument* owner)
     654                 :   : mGlobalObjectOwner(owner)
     655               0 :   , mJSObject(NULL)
     656                 : {
     657               0 : }
     658                 : 
     659                 : 
     660               0 : nsXULPDGlobalObject::~nsXULPDGlobalObject()
     661                 : {
     662               0 : }
     663                 : 
     664            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULPDGlobalObject)
     665               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsXULPDGlobalObject)
     666               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULPDGlobalObject)
     667               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
     668               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     669                 : 
     670               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULPDGlobalObject)
     671               0 :   NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
     672               0 :   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
     673               0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObject)
     674               0 : NS_INTERFACE_MAP_END
     675                 : 
     676               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULPDGlobalObject)
     677               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULPDGlobalObject)
     678                 : 
     679                 : //----------------------------------------------------------------------
     680                 : //
     681                 : // nsIScriptGlobalObject methods
     682                 : //
     683                 : 
     684                 : nsresult
     685               0 : nsXULPDGlobalObject::SetScriptContext(PRUint32 lang_id, nsIScriptContext *aScriptContext)
     686                 : {
     687               0 :   NS_ABORT_IF_FALSE(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
     688                 :                     "We don't support this language ID");
     689                 :   // almost a clone of nsGlobalWindow
     690               0 :   if (!aScriptContext) {
     691               0 :     NS_WARNING("Possibly early removal of script object, see bug #41608");
     692                 :   } else {
     693                 :     // should probably assert the context is clean???
     694               0 :     aScriptContext->WillInitializeContext();
     695               0 :     nsresult rv = aScriptContext->InitContext();
     696               0 :     NS_ENSURE_SUCCESS(rv, rv);
     697                 :   }
     698                 : 
     699               0 :   NS_ASSERTION(!aScriptContext || !mContext, "Bad call to SetContext()!");
     700                 : 
     701               0 :   JSObject* global = NULL;
     702                 : 
     703               0 :   if (aScriptContext) {
     704               0 :     aScriptContext->SetGCOnDestruction(false);
     705               0 :     aScriptContext->DidInitializeContext();
     706               0 :     global = aScriptContext->GetNativeGlobal();
     707               0 :     NS_ASSERTION(global, "GetNativeGlobal returned NULL!");
     708                 :   }
     709               0 :   mContext = aScriptContext;
     710               0 :   mJSObject = global;
     711               0 :   return NS_OK;
     712                 : }
     713                 : 
     714                 : nsresult
     715               0 : nsXULPDGlobalObject::EnsureScriptEnvironment(PRUint32 lang_id)
     716                 : {
     717               0 :   NS_ABORT_IF_FALSE(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
     718                 :                     "We don't support this language ID");
     719               0 :   if (mContext) {
     720               0 :     return NS_OK;
     721                 :   }
     722               0 :   NS_ASSERTION(!mJSObject, "Have global without context?");
     723                 : 
     724               0 :   nsCOMPtr<nsIScriptRuntime> languageRuntime;
     725                 :   nsresult rv = NS_GetScriptRuntimeByID(nsIProgrammingLanguage::JAVASCRIPT,
     726               0 :                                         getter_AddRefs(languageRuntime));
     727               0 :   NS_ENSURE_SUCCESS(rv, NS_OK);
     728                 : 
     729               0 :   nsCOMPtr<nsIScriptContext> ctxNew = languageRuntime->CreateContext();
     730                 :   // We have to setup a special global object.  We do this then
     731                 :   // attach it as the global for this context.  Then, ::SetScriptContext
     732                 :   // will re-fetch the global and set it up in our language globals array.
     733                 :   {
     734               0 :     JSContext *cx = ctxNew->GetNativeContext();
     735               0 :     JSAutoRequest ar(cx);
     736                 : 
     737               0 :     nsIPrincipal *principal = GetPrincipal();
     738                 :     JSObject *newGlob;
     739                 :     JSCompartment *compartment;
     740                 : 
     741                 :     rv = xpc_CreateGlobalObject(cx, &gSharedGlobalClass, principal, nsnull,
     742               0 :                                 false, &newGlob, &compartment);
     743               0 :     NS_ENSURE_SUCCESS(rv, NS_OK);
     744                 : 
     745               0 :     ::JS_SetGlobalObject(cx, newGlob);
     746                 : 
     747                 :     // Add an owning reference from JS back to us. This'll be
     748                 :     // released when the JSObject is finalized.
     749               0 :     ::JS_SetPrivate(newGlob, this);
     750               0 :     NS_ADDREF(this);
     751                 :   }
     752                 : 
     753               0 :   NS_ENSURE_SUCCESS(rv, NS_OK);
     754               0 :   rv = SetScriptContext(lang_id, ctxNew);
     755               0 :   NS_ENSURE_SUCCESS(rv, NS_OK);
     756               0 :   return NS_OK;
     757                 : }
     758                 : 
     759                 : nsIScriptContext*
     760               0 : nsXULPDGlobalObject::GetScriptContext(PRUint32 lang_id)
     761                 : {
     762               0 :   NS_ABORT_IF_FALSE(lang_id == nsIProgrammingLanguage::JAVASCRIPT,
     763                 :                     "We don't support this language ID");
     764                 :   // This global object creates a context on demand - do that now.
     765               0 :   nsresult rv = EnsureScriptEnvironment(nsIProgrammingLanguage::JAVASCRIPT);
     766               0 :   if (NS_FAILED(rv)) {
     767               0 :     NS_ERROR("Failed to setup script language");
     768               0 :     return NULL;
     769                 :   }
     770                 :   // Note that EnsureScriptEnvironment has validated lang_id
     771               0 :   return mContext;
     772                 : }
     773                 : 
     774                 : JSObject*
     775               0 : nsXULPDGlobalObject::GetGlobalJSObject()
     776                 : {
     777               0 :   return mJSObject;
     778                 : }
     779                 : 
     780                 : 
     781                 : void
     782               0 : nsXULPDGlobalObject::ClearGlobalObjectOwner()
     783                 : {
     784               0 :   NS_ASSERTION(!mCachedPrincipal, "This shouldn't ever be set until now!");
     785                 : 
     786                 :   // Cache mGlobalObjectOwner's principal if possible.
     787               0 :   if (this != nsXULPrototypeDocument::gSystemGlobal)
     788               0 :     mCachedPrincipal = mGlobalObjectOwner->DocumentPrincipal();
     789                 : 
     790               0 :   mContext = NULL;
     791               0 :   mGlobalObjectOwner = NULL;
     792               0 : }
     793                 : 
     794                 : 
     795                 : void
     796               0 : nsXULPDGlobalObject::OnFinalize(JSObject* aObject)
     797                 : {
     798               0 :   mJSObject = NULL;
     799               0 : }
     800                 : 
     801                 : void
     802               0 : nsXULPDGlobalObject::SetScriptsEnabled(bool aEnabled, bool aFireTimeouts)
     803                 : {
     804                 :   // We don't care...
     805               0 : }
     806                 : 
     807                 : //----------------------------------------------------------------------
     808                 : //
     809                 : // nsIScriptObjectPrincipal methods
     810                 : //
     811                 : 
     812                 : nsIPrincipal*
     813               0 : nsXULPDGlobalObject::GetPrincipal()
     814                 : {
     815               0 :     if (!mGlobalObjectOwner) {
     816                 :         // See nsXULPrototypeDocument::NewXULPDGlobalObject, the comment
     817                 :         // about gSystemGlobal implying gSystemPrincipal.
     818               0 :         if (this == nsXULPrototypeDocument::gSystemGlobal) {
     819               0 :             return nsXULPrototypeDocument::gSystemPrincipal;
     820                 :         }
     821                 :         // Return the cached principal if it exists.
     822               0 :         return mCachedPrincipal;
     823                 :     }
     824                 : 
     825               0 :     return mGlobalObjectOwner->DocumentPrincipal();
     826            4392 : }

Generated by: LCOV version 1.7