content/xul/document/src/XULDocument.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef mozilla_dom_XULDocument_h
     7 #define mozilla_dom_XULDocument_h
     9 #include "nsCOMPtr.h"
    10 #include "nsXULPrototypeDocument.h"
    11 #include "nsXULPrototypeCache.h"
    12 #include "nsTArray.h"
    14 #include "mozilla/dom/XMLDocument.h"
    15 #include "nsForwardReference.h"
    16 #include "nsIContent.h"
    17 #include "nsIDOMXULCommandDispatcher.h"
    18 #include "nsIDOMXULDocument.h"
    19 #include "nsCOMArray.h"
    20 #include "nsIURI.h"
    21 #include "nsIXULDocument.h"
    22 #include "nsScriptLoader.h"
    23 #include "nsIStreamListener.h"
    24 #include "nsICSSLoaderObserver.h"
    26 #include "mozilla/Attributes.h"
    28 #include "js/TracingAPI.h"
    29 #include "js/TypeDecls.h"
    31 class nsIRDFResource;
    32 class nsIRDFService;
    33 class nsPIWindowRoot;
    34 #if 0 // XXXbe save me, scc (need NSCAP_FORWARD_DECL(nsXULPrototypeScript))
    35 class nsIObjectInputStream;
    36 class nsIObjectOutputStream;
    37 class nsIXULPrototypeScript;
    38 #else
    39 #include "nsIObjectInputStream.h"
    40 #include "nsIObjectOutputStream.h"
    41 #include "nsXULElement.h"
    42 #endif
    43 #include "nsURIHashKey.h"
    44 #include "nsInterfaceHashtable.h"
    46 struct PRLogModuleInfo;
    48 class nsRefMapEntry : public nsStringHashKey
    49 {
    50 public:
    51   nsRefMapEntry(const nsAString& aKey) :
    52     nsStringHashKey(&aKey)
    53   {
    54   }
    55   nsRefMapEntry(const nsAString *aKey) :
    56     nsStringHashKey(aKey)
    57   {
    58   }
    59   nsRefMapEntry(const nsRefMapEntry& aOther) :
    60     nsStringHashKey(&aOther.GetKey())
    61   {
    62     NS_ERROR("Should never be called");
    63   }
    65   mozilla::dom::Element* GetFirstElement();
    66   void AppendAll(nsCOMArray<nsIContent>* aElements);
    67   /**
    68    * @return true if aElement was added, false if we failed due to OOM
    69    */
    70   bool AddElement(mozilla::dom::Element* aElement);
    71   /**
    72    * @return true if aElement was removed and it was the last content for
    73    * this ref, so this entry should be removed from the map
    74    */
    75   bool RemoveElement(mozilla::dom::Element* aElement);
    77 private:
    78   nsSmallVoidArray mRefContentList;
    79 };
    81 /**
    82  * The XUL document class
    83  */
    85 namespace mozilla {
    86 namespace dom {
    88 class XULDocument MOZ_FINAL : public XMLDocument,
    89                               public nsIXULDocument,
    90                               public nsIDOMXULDocument,
    91                               public nsIStreamLoaderObserver,
    92                               public nsICSSLoaderObserver,
    93                               public nsIOffThreadScriptReceiver
    94 {
    95 public:
    96     XULDocument();
    97     virtual ~XULDocument();
    99     // nsISupports interface
   100     NS_DECL_ISUPPORTS_INHERITED
   101     NS_DECL_NSISTREAMLOADEROBSERVER
   103     // nsIDocument interface
   104     virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) MOZ_OVERRIDE;
   105     virtual void ResetToURI(nsIURI *aURI, nsILoadGroup* aLoadGroup,
   106                             nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
   108     virtual nsresult StartDocumentLoad(const char* aCommand,
   109                                        nsIChannel *channel,
   110                                        nsILoadGroup* aLoadGroup,
   111                                        nsISupports* aContainer,
   112                                        nsIStreamListener **aDocListener,
   113                                        bool aReset = true,
   114                                        nsIContentSink* aSink = nullptr) MOZ_OVERRIDE;
   116     virtual void SetContentType(const nsAString& aContentType) MOZ_OVERRIDE;
   118     virtual void EndLoad() MOZ_OVERRIDE;
   120     // nsIMutationObserver interface
   121     NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   122     NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   123     NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
   124     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   125     NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
   127     // nsIXULDocument interface
   128     virtual void GetElementsForID(const nsAString& aID,
   129                                   nsCOMArray<nsIContent>& aElements) MOZ_OVERRIDE;
   131     NS_IMETHOD AddSubtreeToDocument(nsIContent* aContent) MOZ_OVERRIDE;
   132     NS_IMETHOD RemoveSubtreeFromDocument(nsIContent* aContent) MOZ_OVERRIDE;
   133     NS_IMETHOD SetTemplateBuilderFor(nsIContent* aContent,
   134                                      nsIXULTemplateBuilder* aBuilder) MOZ_OVERRIDE;
   135     NS_IMETHOD GetTemplateBuilderFor(nsIContent* aContent,
   136                                      nsIXULTemplateBuilder** aResult) MOZ_OVERRIDE;
   137     NS_IMETHOD OnPrototypeLoadDone(bool aResumeWalk) MOZ_OVERRIDE;
   138     bool OnDocumentParserError() MOZ_OVERRIDE;
   140     // nsINode interface overrides
   141     virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
   143     // nsIDOMNode interface
   144     NS_FORWARD_NSIDOMNODE_TO_NSINODE
   146     // nsIDOMDocument interface
   147     using nsDocument::CreateElement;
   148     using nsDocument::CreateElementNS;
   149     NS_FORWARD_NSIDOMDOCUMENT(XMLDocument::)
   150     // And explicitly import the things from nsDocument that we just shadowed
   151     using nsDocument::GetImplementation;
   152     using nsDocument::GetTitle;
   153     using nsDocument::SetTitle;
   154     using nsDocument::GetLastStyleSheetSet;
   155     using nsDocument::MozSetImageElement;
   156     using nsDocument::GetMozFullScreenElement;
   157     using nsIDocument::GetLocation;
   159     // nsDocument interface overrides
   160     virtual Element* GetElementById(const nsAString & elementId) MOZ_OVERRIDE;
   162     // nsIDOMXULDocument interface
   163     NS_DECL_NSIDOMXULDOCUMENT
   165     // nsICSSLoaderObserver
   166     NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet,
   167                                 bool aWasAlternate,
   168                                 nsresult aStatus) MOZ_OVERRIDE;
   170     virtual void EndUpdate(nsUpdateType aUpdateType) MOZ_OVERRIDE;
   172     virtual bool IsDocumentRightToLeft() MOZ_OVERRIDE;
   174     virtual void ResetDocumentDirection() MOZ_OVERRIDE;
   176     virtual int GetDocumentLWTheme() MOZ_OVERRIDE;
   178     virtual void ResetDocumentLWTheme() MOZ_OVERRIDE { mDocLWTheme = Doc_Theme_Uninitialized; }
   180     NS_IMETHOD OnScriptCompileComplete(JSScript* aScript, nsresult aStatus) MOZ_OVERRIDE;
   182     static bool
   183     MatchAttribute(nsIContent* aContent,
   184                    int32_t aNameSpaceID,
   185                    nsIAtom* aAttrName,
   186                    void* aData);
   188     NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULDocument, XMLDocument)
   190     void TraceProtos(JSTracer* aTrc, uint32_t aGCNumber);
   192     // WebIDL API
   193     already_AddRefed<nsINode> GetPopupNode();
   194     void SetPopupNode(nsINode* aNode);
   195     already_AddRefed<nsINode> GetPopupRangeParent(ErrorResult& aRv);
   196     int32_t GetPopupRangeOffset(ErrorResult& aRv);
   197     already_AddRefed<nsINode> GetTooltipNode();
   198     void SetTooltipNode(nsINode* aNode) { /* do nothing */ }
   199     nsIDOMXULCommandDispatcher* GetCommandDispatcher() const
   200     {
   201         return mCommandDispatcher;
   202     }
   203     int32_t GetWidth(ErrorResult& aRv);
   204     int32_t GetHeight(ErrorResult& aRv);
   205     already_AddRefed<nsINodeList>
   206       GetElementsByAttribute(const nsAString& aAttribute,
   207                              const nsAString& aValue);
   208     already_AddRefed<nsINodeList>
   209       GetElementsByAttributeNS(const nsAString& aNamespaceURI,
   210                                const nsAString& aAttribute,
   211                                const nsAString& aValue,
   212                                ErrorResult& aRv);
   213     void AddBroadcastListenerFor(Element& aBroadcaster, Element& aListener,
   214                                  const nsAString& aAttr, ErrorResult& aRv);
   215     void RemoveBroadcastListenerFor(Element& aBroadcaster, Element& aListener,
   216                                     const nsAString& aAttr);
   217     void Persist(const nsAString& aId, const nsAString& aAttr, ErrorResult& aRv)
   218     {
   219         aRv = Persist(aId, aAttr);
   220     }
   221     using nsDocument::GetBoxObjectFor;
   222     void LoadOverlay(const nsAString& aURL, nsIObserver* aObserver,
   223                      ErrorResult& aRv)
   224     {
   225         aRv = LoadOverlay(aURL, aObserver);
   226     }
   228 protected:
   229     // Implementation methods
   230     friend nsresult
   231     (::NS_NewXULDocument(nsIXULDocument** aResult));
   233     nsresult Init(void) MOZ_OVERRIDE;
   234     nsresult StartLayout(void);
   236     nsresult
   237     AddElementToRefMap(Element* aElement);
   238     void
   239     RemoveElementFromRefMap(Element* aElement);
   241     nsresult GetViewportSize(int32_t* aWidth, int32_t* aHeight);
   243     nsresult PrepareToLoad(nsISupports* aContainer,
   244                            const char* aCommand,
   245                            nsIChannel* aChannel,
   246                            nsILoadGroup* aLoadGroup,
   247                            nsIParser** aResult);
   249     nsresult
   250     PrepareToLoadPrototype(nsIURI* aURI,
   251                            const char* aCommand,
   252                            nsIPrincipal* aDocumentPrincipal,
   253                            nsIParser** aResult);
   255     nsresult 
   256     LoadOverlayInternal(nsIURI* aURI, bool aIsDynamic, bool* aShouldReturn,
   257                         bool* aFailureFromContent);
   259     nsresult ApplyPersistentAttributes();
   260     nsresult ApplyPersistentAttributesInternal();
   261     nsresult ApplyPersistentAttributesToElements(nsIRDFResource* aResource,
   262                                                  nsCOMArray<nsIContent>& aElements);
   264     nsresult
   265     AddElementToDocumentPre(Element* aElement);
   267     nsresult
   268     AddElementToDocumentPost(Element* aElement);
   270     nsresult
   271     ExecuteOnBroadcastHandlerFor(Element* aBroadcaster,
   272                                  Element* aListener,
   273                                  nsIAtom* aAttr);
   275     nsresult
   276     BroadcastAttributeChangeFromOverlay(nsIContent* aNode,
   277                                         int32_t aNameSpaceID,
   278                                         nsIAtom* aAttribute,
   279                                         nsIAtom* aPrefix,
   280                                         const nsAString& aValue);
   282     already_AddRefed<nsPIWindowRoot> GetWindowRoot();
   284     static NS_HIDDEN_(void) DirectionChanged(const char* aPrefName, void* aData);
   286     // pseudo constants
   287     static int32_t gRefCnt;
   289     static nsIAtom** kIdentityAttrs[];
   291     static nsIRDFService* gRDFService;
   292     static nsIRDFResource* kNC_persist;
   293     static nsIRDFResource* kNC_attribute;
   294     static nsIRDFResource* kNC_value;
   296     static PRLogModuleInfo* gXULLog;
   298     nsresult
   299     Persist(nsIContent* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute);
   301     virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
   303     // IMPORTANT: The ownership implicit in the following member
   304     // variables has been explicitly checked and set using nsCOMPtr
   305     // for owning pointers and raw COM interface pointers for weak
   306     // (ie, non owning) references. If you add any members to this
   307     // class, please make the ownership explicit (pinkerton, scc).
   308     // NOTE, THIS IS STILL IN PROGRESS, TALK TO PINK OR SCC BEFORE
   309     // CHANGING
   311     XULDocument*             mNextSrcLoadWaiter;  // [OWNER] but not COMPtr
   313     // Tracks elements with a 'ref' attribute, or an 'id' attribute where
   314     // the element's namespace has no registered ID attribute name.
   315     nsTHashtable<nsRefMapEntry> mRefMap;
   316     nsCOMPtr<nsIRDFDataSource> mLocalStore;
   317     bool                       mApplyingPersistedAttrs;
   318     bool                       mIsWritingFastLoad;
   319     bool                       mDocumentLoaded;
   320     /**
   321      * Since ResumeWalk is interruptible, it's possible that last
   322      * stylesheet finishes loading while the PD walk is still in
   323      * progress (waiting for an overlay to finish loading).
   324      * mStillWalking prevents DoneLoading (and StartLayout) from being
   325      * called in this situation.
   326      */
   327     bool                       mStillWalking;
   329     /**
   330      * These two values control where persistent attributes get applied.
   331      */
   332     bool                           mRestrictPersistence;
   333     nsTHashtable<nsStringHashKey>  mPersistenceIds;
   335     /**
   336      * An array of style sheets, that will be added (preserving order) to the
   337      * document after all of them are loaded (in DoneWalking).
   338      */
   339     nsTArray<nsRefPtr<nsCSSStyleSheet> > mOverlaySheets;
   341     nsCOMPtr<nsIDOMXULCommandDispatcher>     mCommandDispatcher; // [OWNER] of the focus tracker
   343     // Maintains the template builders that have been attached to
   344     // content elements
   345     typedef nsInterfaceHashtable<nsISupportsHashKey, nsIXULTemplateBuilder>
   346         BuilderTable;
   347     BuilderTable* mTemplateBuilderTable;
   349     uint32_t mPendingSheets;
   351     /**
   352      * document lightweight theme for use with :-moz-lwtheme, :-moz-lwtheme-brighttext
   353      * and :-moz-lwtheme-darktext
   354      */
   355     DocumentTheme                         mDocLWTheme;
   357     /**
   358      * Context stack, which maintains the state of the Builder and allows
   359      * it to be interrupted.
   360      */
   361     class ContextStack {
   362     protected:
   363         struct Entry {
   364             nsXULPrototypeElement* mPrototype;
   365             nsIContent*            mElement;
   366             int32_t                mIndex;
   367             Entry*                 mNext;
   368         };
   370         Entry* mTop;
   371         int32_t mDepth;
   373     public:
   374         ContextStack();
   375         ~ContextStack();
   377         int32_t Depth() { return mDepth; }
   379         nsresult Push(nsXULPrototypeElement* aPrototype, nsIContent* aElement);
   380         nsresult Pop();
   381         nsresult Peek(nsXULPrototypeElement** aPrototype, nsIContent** aElement, int32_t* aIndex);
   383         nsresult SetTopIndex(int32_t aIndex);
   384     };
   386     friend class ContextStack;
   387     ContextStack mContextStack;
   389     enum State { eState_Master, eState_Overlay };
   390     State mState;
   392     /**
   393      * An array of overlay nsIURIs that have yet to be resolved. The
   394      * order of the array is significant: overlays at the _end_ of the
   395      * array are resolved before overlays earlier in the array (i.e.,
   396      * it is a stack).
   397      *
   398      * In the current implementation the order the overlays are loaded
   399      * in is as follows: first overlays from xul-overlay PIs, in the
   400      * same order as in the document, then the overlays from the chrome
   401      * registry.
   402      */
   403     nsTArray<nsCOMPtr<nsIURI> > mUnloadedOverlays;
   405     /**
   406      * Load the transcluded script at the specified URI. If the
   407      * prototype construction must 'block' until the load has
   408      * completed, aBlock will be set to true.
   409      */
   410     nsresult LoadScript(nsXULPrototypeScript *aScriptProto, bool* aBlock);
   412     /**
   413      * Execute the precompiled script object scoped by this XUL document's
   414      * containing window object, and using its associated script context.
   415      */
   416     nsresult ExecuteScript(nsIScriptContext *aContext,
   417                            JS::Handle<JSScript*> aScriptObject);
   419     /**
   420      * Helper method for the above that uses aScript to find the appropriate
   421      * script context and object.
   422      */
   423     nsresult ExecuteScript(nsXULPrototypeScript *aScript);
   425     /**
   426      * Create a delegate content model element from a prototype.
   427      * Note that the resulting content node is not bound to any tree
   428      */
   429     nsresult CreateElementFromPrototype(nsXULPrototypeElement* aPrototype,
   430                                         Element** aResult,
   431                                         bool aIsRoot);
   433     /**
   434      * Create a hook-up element to which content nodes can be attached for
   435      * later resolution.
   436      */
   437     nsresult CreateOverlayElement(nsXULPrototypeElement* aPrototype,
   438                                   Element** aResult);
   440     /**
   441      * Add attributes from the prototype to the element.
   442      */
   443     nsresult AddAttributes(nsXULPrototypeElement* aPrototype, nsIContent* aElement);
   445     /**
   446      * The prototype-script of the current transcluded script that is being
   447      * loaded.  For document.write('<script src="nestedwrite.js"><\/script>')
   448      * to work, these need to be in a stack element type, and we need to hold
   449      * the top of stack here.
   450      */
   451     nsXULPrototypeScript* mCurrentScriptProto;
   453     /**
   454      * Whether the current transcluded script is being compiled off thread.
   455      * The load event is blocked while this is in progress.
   456      */
   457     bool mOffThreadCompiling;
   459     /**
   460      * If the current transcluded script is being compiled off thread, the
   461      * source for that script.
   462      */
   463     jschar* mOffThreadCompileStringBuf;
   464     size_t mOffThreadCompileStringLength;
   466     /**
   467      * Check if a XUL template builder has already been hooked up.
   468      */
   469     static nsresult
   470     CheckTemplateBuilderHookup(nsIContent* aElement, bool* aNeedsHookup);
   472     /**
   473      * Create a XUL template builder on the specified node.
   474      */
   475     static nsresult
   476     CreateTemplateBuilder(nsIContent* aElement);
   478     /**
   479      * Add the current prototype's style sheets (currently it's just
   480      * style overlays from the chrome registry) to the document.
   481      */
   482     nsresult AddPrototypeSheets();
   485 protected:
   486     /* Declarations related to forward references. 
   487      *
   488      * Forward references are declarations which are added to the temporary
   489      * list (mForwardReferences) during the document (or overlay) load and
   490      * are resolved later, when the document loading is almost complete.
   491      */
   493     /**
   494      * The list of different types of forward references to resolve. After
   495      * a reference is resolved, it is removed from this array (and
   496      * automatically deleted)
   497      */
   498     nsTArray<nsAutoPtr<nsForwardReference> > mForwardReferences;
   500     /** Indicates what kind of forward references are still to be processed. */
   501     nsForwardReference::Phase mResolutionPhase;
   503     /**
   504      * Adds aRef to the mForwardReferences array. Takes the ownership of aRef.
   505      */
   506     nsresult AddForwardReference(nsForwardReference* aRef);
   508     /**
   509      * Resolve all of the document's forward references.
   510      */
   511     nsresult ResolveForwardReferences();
   513     /**
   514      * Used to resolve broadcaster references
   515      */
   516     class BroadcasterHookup : public nsForwardReference
   517     {
   518     protected:
   519         XULDocument* mDocument;              // [WEAK]
   520         nsRefPtr<Element> mObservesElement; // [OWNER]
   521         bool mResolved;
   523     public:
   524         BroadcasterHookup(XULDocument* aDocument,
   525                           Element* aObservesElement)
   526             : mDocument(aDocument),
   527               mObservesElement(aObservesElement),
   528               mResolved(false)
   529         {
   530         }
   532         virtual ~BroadcasterHookup();
   534         virtual Phase GetPhase() MOZ_OVERRIDE { return eHookup; }
   535         virtual Result Resolve() MOZ_OVERRIDE;
   536     };
   538     friend class BroadcasterHookup;
   541     /**
   542      * Used to hook up overlays
   543      */
   544     class OverlayForwardReference : public nsForwardReference
   545     {
   546     protected:
   547         XULDocument* mDocument;      // [WEAK]
   548         nsCOMPtr<nsIContent> mOverlay; // [OWNER]
   549         bool mResolved;
   551         nsresult Merge(nsIContent* aTargetNode, nsIContent* aOverlayNode, bool aNotify);
   553     public:
   554         OverlayForwardReference(XULDocument* aDocument, nsIContent* aOverlay)
   555             : mDocument(aDocument), mOverlay(aOverlay), mResolved(false) {}
   557         virtual ~OverlayForwardReference();
   559         virtual Phase GetPhase() MOZ_OVERRIDE { return eConstruction; }
   560         virtual Result Resolve() MOZ_OVERRIDE;
   561     };
   563     friend class OverlayForwardReference;
   565     class TemplateBuilderHookup : public nsForwardReference
   566     {
   567     protected:
   568         nsCOMPtr<nsIContent> mElement; // [OWNER]
   570     public:
   571         TemplateBuilderHookup(nsIContent* aElement)
   572             : mElement(aElement) {}
   574         virtual Phase GetPhase() MOZ_OVERRIDE { return eHookup; }
   575         virtual Result Resolve() MOZ_OVERRIDE;
   576     };
   578     friend class TemplateBuilderHookup;
   580     // The out params of FindBroadcaster only have values that make sense when
   581     // the method returns NS_FINDBROADCASTER_FOUND.  In all other cases, the
   582     // values of the out params should not be relied on (though *aListener and
   583     // *aBroadcaster do need to be released if non-null, of course).
   584     nsresult
   585     FindBroadcaster(Element* aElement,
   586                     Element** aListener,
   587                     nsString& aBroadcasterID,
   588                     nsString& aAttribute,
   589                     Element** aBroadcaster);
   591     nsresult
   592     CheckBroadcasterHookup(Element* aElement,
   593                            bool* aNeedsHookup,
   594                            bool* aDidResolve);
   596     void
   597     SynchronizeBroadcastListener(Element *aBroadcaster,
   598                                  Element *aListener,
   599                                  const nsAString &aAttr);
   601     static
   602     nsresult
   603     InsertElement(nsINode* aParent, nsIContent* aChild, bool aNotify);
   605     static 
   606     nsresult
   607     RemoveElement(nsINode* aParent, nsINode* aChild);
   609     /**
   610      * The current prototype that we are walking to construct the
   611      * content model.
   612      */
   613     nsRefPtr<nsXULPrototypeDocument> mCurrentPrototype;
   615     /**
   616      * The master document (outermost, .xul) prototype, from which
   617      * all subdocuments get their security principals.
   618      */
   619     nsRefPtr<nsXULPrototypeDocument> mMasterPrototype;
   621     /**
   622      * Owning references to all of the prototype documents that were
   623      * used to construct this document.
   624      */
   625     nsTArray< nsRefPtr<nsXULPrototypeDocument> > mPrototypes;
   627     /**
   628      * Prepare to walk the current prototype.
   629      */
   630     nsresult PrepareToWalk();
   632     /**
   633      * Creates a processing instruction based on aProtoPI and inserts
   634      * it to the DOM (as the aIndex-th child of aParent).
   635      */
   636     nsresult
   637     CreateAndInsertPI(const nsXULPrototypePI* aProtoPI,
   638                       nsINode* aParent, uint32_t aIndex);
   640     /**
   641      * Inserts the passed <?xml-stylesheet ?> PI at the specified
   642      * index. Loads and applies the associated stylesheet
   643      * asynchronously.
   644      * The prototype document walk can happen before the stylesheets
   645      * are loaded, but the final steps in the load process (see
   646      * DoneWalking()) are not run before all the stylesheets are done
   647      * loading.
   648      */
   649     nsresult
   650     InsertXMLStylesheetPI(const nsXULPrototypePI* aProtoPI,
   651                           nsINode* aParent,
   652                           uint32_t aIndex,
   653                           nsIContent* aPINode);
   655     /**
   656      * Inserts the passed <?xul-overlay ?> PI at the specified index.
   657      * Schedules the referenced overlay URI for further processing.
   658      */
   659     nsresult
   660     InsertXULOverlayPI(const nsXULPrototypePI* aProtoPI,
   661                        nsINode* aParent,
   662                        uint32_t aIndex,
   663                        nsIContent* aPINode);
   665     /**
   666      * Add overlays from the chrome registry to the set of unprocessed
   667      * overlays still to do.
   668      */
   669     nsresult AddChromeOverlays();
   671     /**
   672      * Resume (or initiate) an interrupted (or newly prepared)
   673      * prototype walk.
   674      */
   675     nsresult ResumeWalk();
   677     /**
   678      * Called at the end of ResumeWalk() and from StyleSheetLoaded().
   679      * Expects that both the prototype document walk is complete and
   680      * all referenced stylesheets finished loading.
   681      */
   682     nsresult DoneWalking();
   684     /**
   685      * Report that an overlay failed to load
   686      * @param aURI the URI of the overlay that failed to load
   687      */
   688     void ReportMissingOverlay(nsIURI* aURI);
   690     class CachedChromeStreamListener : public nsIStreamListener {
   691     protected:
   692         XULDocument* mDocument;
   693         bool         mProtoLoaded;
   695         virtual ~CachedChromeStreamListener();
   697     public:
   698         CachedChromeStreamListener(XULDocument* aDocument,
   699                                    bool aProtoLoaded);
   701         NS_DECL_ISUPPORTS
   702         NS_DECL_NSIREQUESTOBSERVER
   703         NS_DECL_NSISTREAMLISTENER
   704     };
   706     friend class CachedChromeStreamListener;
   709     class ParserObserver : public nsIRequestObserver {
   710     protected:
   711         nsRefPtr<XULDocument> mDocument;
   712         nsRefPtr<nsXULPrototypeDocument> mPrototype;
   713         virtual ~ParserObserver();
   715     public:
   716         ParserObserver(XULDocument* aDocument,
   717                        nsXULPrototypeDocument* aPrototype);
   719         NS_DECL_ISUPPORTS
   720         NS_DECL_NSIREQUESTOBSERVER
   721     };
   723     friend class ParserObserver;
   725     /**
   726      * A map from a broadcaster element to a list of listener elements.
   727      */
   728     PLDHashTable* mBroadcasterMap;
   730     nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIObserver> > mOverlayLoadObservers;
   731     nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIObserver> > mPendingOverlayLoadNotifications;
   733     bool mInitialLayoutComplete;
   735     class nsDelayedBroadcastUpdate
   736     {
   737     public:
   738       nsDelayedBroadcastUpdate(Element* aBroadcaster,
   739                                Element* aListener,
   740                                const nsAString &aAttr)
   741       : mBroadcaster(aBroadcaster), mListener(aListener), mAttr(aAttr),
   742         mSetAttr(false), mNeedsAttrChange(false) {}
   744       nsDelayedBroadcastUpdate(Element* aBroadcaster,
   745                                Element* aListener,
   746                                nsIAtom* aAttrName,
   747                                const nsAString &aAttr,
   748                                bool aSetAttr,
   749                                bool aNeedsAttrChange)
   750       : mBroadcaster(aBroadcaster), mListener(aListener), mAttr(aAttr),
   751         mAttrName(aAttrName), mSetAttr(aSetAttr),
   752         mNeedsAttrChange(aNeedsAttrChange) {}
   754       nsDelayedBroadcastUpdate(const nsDelayedBroadcastUpdate& aOther)
   755       : mBroadcaster(aOther.mBroadcaster), mListener(aOther.mListener),
   756         mAttr(aOther.mAttr), mAttrName(aOther.mAttrName),
   757         mSetAttr(aOther.mSetAttr), mNeedsAttrChange(aOther.mNeedsAttrChange) {}
   759       nsCOMPtr<Element>       mBroadcaster;
   760       nsCOMPtr<Element>       mListener;
   761       // Note if mAttrName isn't used, this is the name of the attr, otherwise
   762       // this is the value of the attribute.
   763       nsString                mAttr;
   764       nsCOMPtr<nsIAtom>       mAttrName;
   765       bool                    mSetAttr;
   766       bool                    mNeedsAttrChange;
   768       class Comparator {
   769         public:
   770           static bool Equals(const nsDelayedBroadcastUpdate& a, const nsDelayedBroadcastUpdate& b) {
   771             return a.mBroadcaster == b.mBroadcaster && a.mListener == b.mListener && a.mAttrName == b.mAttrName;
   772           }
   773       };
   774     };
   776     nsTArray<nsDelayedBroadcastUpdate> mDelayedBroadcasters;
   777     nsTArray<nsDelayedBroadcastUpdate> mDelayedAttrChangeBroadcasts;
   778     bool                               mHandlingDelayedAttrChange;
   779     bool                               mHandlingDelayedBroadcasters;
   781     void MaybeBroadcast();
   782 private:
   783     // helpers
   785 };
   787 } // namespace dom
   788 } // namespace mozilla
   790 #endif // mozilla_dom_XULDocument_h

mercurial