LCOV - app.info - content/xul/document/src/nsXULPrototypeDocument.cpp

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