content/xul/document/src/XULDocument.h

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:f9ab85f81675
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/. */
5
6 #ifndef mozilla_dom_XULDocument_h
7 #define mozilla_dom_XULDocument_h
8
9 #include "nsCOMPtr.h"
10 #include "nsXULPrototypeDocument.h"
11 #include "nsXULPrototypeCache.h"
12 #include "nsTArray.h"
13
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"
25
26 #include "mozilla/Attributes.h"
27
28 #include "js/TracingAPI.h"
29 #include "js/TypeDecls.h"
30
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"
45
46 struct PRLogModuleInfo;
47
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 }
64
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);
76
77 private:
78 nsSmallVoidArray mRefContentList;
79 };
80
81 /**
82 * The XUL document class
83 */
84
85 namespace mozilla {
86 namespace dom {
87
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();
98
99 // nsISupports interface
100 NS_DECL_ISUPPORTS_INHERITED
101 NS_DECL_NSISTREAMLOADEROBSERVER
102
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;
107
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;
115
116 virtual void SetContentType(const nsAString& aContentType) MOZ_OVERRIDE;
117
118 virtual void EndLoad() MOZ_OVERRIDE;
119
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
126
127 // nsIXULDocument interface
128 virtual void GetElementsForID(const nsAString& aID,
129 nsCOMArray<nsIContent>& aElements) MOZ_OVERRIDE;
130
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;
139
140 // nsINode interface overrides
141 virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
142
143 // nsIDOMNode interface
144 NS_FORWARD_NSIDOMNODE_TO_NSINODE
145
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;
158
159 // nsDocument interface overrides
160 virtual Element* GetElementById(const nsAString & elementId) MOZ_OVERRIDE;
161
162 // nsIDOMXULDocument interface
163 NS_DECL_NSIDOMXULDOCUMENT
164
165 // nsICSSLoaderObserver
166 NS_IMETHOD StyleSheetLoaded(nsCSSStyleSheet* aSheet,
167 bool aWasAlternate,
168 nsresult aStatus) MOZ_OVERRIDE;
169
170 virtual void EndUpdate(nsUpdateType aUpdateType) MOZ_OVERRIDE;
171
172 virtual bool IsDocumentRightToLeft() MOZ_OVERRIDE;
173
174 virtual void ResetDocumentDirection() MOZ_OVERRIDE;
175
176 virtual int GetDocumentLWTheme() MOZ_OVERRIDE;
177
178 virtual void ResetDocumentLWTheme() MOZ_OVERRIDE { mDocLWTheme = Doc_Theme_Uninitialized; }
179
180 NS_IMETHOD OnScriptCompileComplete(JSScript* aScript, nsresult aStatus) MOZ_OVERRIDE;
181
182 static bool
183 MatchAttribute(nsIContent* aContent,
184 int32_t aNameSpaceID,
185 nsIAtom* aAttrName,
186 void* aData);
187
188 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULDocument, XMLDocument)
189
190 void TraceProtos(JSTracer* aTrc, uint32_t aGCNumber);
191
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 }
227
228 protected:
229 // Implementation methods
230 friend nsresult
231 (::NS_NewXULDocument(nsIXULDocument** aResult));
232
233 nsresult Init(void) MOZ_OVERRIDE;
234 nsresult StartLayout(void);
235
236 nsresult
237 AddElementToRefMap(Element* aElement);
238 void
239 RemoveElementFromRefMap(Element* aElement);
240
241 nsresult GetViewportSize(int32_t* aWidth, int32_t* aHeight);
242
243 nsresult PrepareToLoad(nsISupports* aContainer,
244 const char* aCommand,
245 nsIChannel* aChannel,
246 nsILoadGroup* aLoadGroup,
247 nsIParser** aResult);
248
249 nsresult
250 PrepareToLoadPrototype(nsIURI* aURI,
251 const char* aCommand,
252 nsIPrincipal* aDocumentPrincipal,
253 nsIParser** aResult);
254
255 nsresult
256 LoadOverlayInternal(nsIURI* aURI, bool aIsDynamic, bool* aShouldReturn,
257 bool* aFailureFromContent);
258
259 nsresult ApplyPersistentAttributes();
260 nsresult ApplyPersistentAttributesInternal();
261 nsresult ApplyPersistentAttributesToElements(nsIRDFResource* aResource,
262 nsCOMArray<nsIContent>& aElements);
263
264 nsresult
265 AddElementToDocumentPre(Element* aElement);
266
267 nsresult
268 AddElementToDocumentPost(Element* aElement);
269
270 nsresult
271 ExecuteOnBroadcastHandlerFor(Element* aBroadcaster,
272 Element* aListener,
273 nsIAtom* aAttr);
274
275 nsresult
276 BroadcastAttributeChangeFromOverlay(nsIContent* aNode,
277 int32_t aNameSpaceID,
278 nsIAtom* aAttribute,
279 nsIAtom* aPrefix,
280 const nsAString& aValue);
281
282 already_AddRefed<nsPIWindowRoot> GetWindowRoot();
283
284 static NS_HIDDEN_(void) DirectionChanged(const char* aPrefName, void* aData);
285
286 // pseudo constants
287 static int32_t gRefCnt;
288
289 static nsIAtom** kIdentityAttrs[];
290
291 static nsIRDFService* gRDFService;
292 static nsIRDFResource* kNC_persist;
293 static nsIRDFResource* kNC_attribute;
294 static nsIRDFResource* kNC_value;
295
296 static PRLogModuleInfo* gXULLog;
297
298 nsresult
299 Persist(nsIContent* aElement, int32_t aNameSpaceID, nsIAtom* aAttribute);
300
301 virtual JSObject* WrapNode(JSContext *aCx) MOZ_OVERRIDE;
302
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
310
311 XULDocument* mNextSrcLoadWaiter; // [OWNER] but not COMPtr
312
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;
328
329 /**
330 * These two values control where persistent attributes get applied.
331 */
332 bool mRestrictPersistence;
333 nsTHashtable<nsStringHashKey> mPersistenceIds;
334
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;
340
341 nsCOMPtr<nsIDOMXULCommandDispatcher> mCommandDispatcher; // [OWNER] of the focus tracker
342
343 // Maintains the template builders that have been attached to
344 // content elements
345 typedef nsInterfaceHashtable<nsISupportsHashKey, nsIXULTemplateBuilder>
346 BuilderTable;
347 BuilderTable* mTemplateBuilderTable;
348
349 uint32_t mPendingSheets;
350
351 /**
352 * document lightweight theme for use with :-moz-lwtheme, :-moz-lwtheme-brighttext
353 * and :-moz-lwtheme-darktext
354 */
355 DocumentTheme mDocLWTheme;
356
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 };
369
370 Entry* mTop;
371 int32_t mDepth;
372
373 public:
374 ContextStack();
375 ~ContextStack();
376
377 int32_t Depth() { return mDepth; }
378
379 nsresult Push(nsXULPrototypeElement* aPrototype, nsIContent* aElement);
380 nsresult Pop();
381 nsresult Peek(nsXULPrototypeElement** aPrototype, nsIContent** aElement, int32_t* aIndex);
382
383 nsresult SetTopIndex(int32_t aIndex);
384 };
385
386 friend class ContextStack;
387 ContextStack mContextStack;
388
389 enum State { eState_Master, eState_Overlay };
390 State mState;
391
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;
404
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);
411
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);
418
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);
424
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);
432
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);
439
440 /**
441 * Add attributes from the prototype to the element.
442 */
443 nsresult AddAttributes(nsXULPrototypeElement* aPrototype, nsIContent* aElement);
444
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;
452
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;
458
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;
465
466 /**
467 * Check if a XUL template builder has already been hooked up.
468 */
469 static nsresult
470 CheckTemplateBuilderHookup(nsIContent* aElement, bool* aNeedsHookup);
471
472 /**
473 * Create a XUL template builder on the specified node.
474 */
475 static nsresult
476 CreateTemplateBuilder(nsIContent* aElement);
477
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();
483
484
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 */
492
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;
499
500 /** Indicates what kind of forward references are still to be processed. */
501 nsForwardReference::Phase mResolutionPhase;
502
503 /**
504 * Adds aRef to the mForwardReferences array. Takes the ownership of aRef.
505 */
506 nsresult AddForwardReference(nsForwardReference* aRef);
507
508 /**
509 * Resolve all of the document's forward references.
510 */
511 nsresult ResolveForwardReferences();
512
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;
522
523 public:
524 BroadcasterHookup(XULDocument* aDocument,
525 Element* aObservesElement)
526 : mDocument(aDocument),
527 mObservesElement(aObservesElement),
528 mResolved(false)
529 {
530 }
531
532 virtual ~BroadcasterHookup();
533
534 virtual Phase GetPhase() MOZ_OVERRIDE { return eHookup; }
535 virtual Result Resolve() MOZ_OVERRIDE;
536 };
537
538 friend class BroadcasterHookup;
539
540
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;
550
551 nsresult Merge(nsIContent* aTargetNode, nsIContent* aOverlayNode, bool aNotify);
552
553 public:
554 OverlayForwardReference(XULDocument* aDocument, nsIContent* aOverlay)
555 : mDocument(aDocument), mOverlay(aOverlay), mResolved(false) {}
556
557 virtual ~OverlayForwardReference();
558
559 virtual Phase GetPhase() MOZ_OVERRIDE { return eConstruction; }
560 virtual Result Resolve() MOZ_OVERRIDE;
561 };
562
563 friend class OverlayForwardReference;
564
565 class TemplateBuilderHookup : public nsForwardReference
566 {
567 protected:
568 nsCOMPtr<nsIContent> mElement; // [OWNER]
569
570 public:
571 TemplateBuilderHookup(nsIContent* aElement)
572 : mElement(aElement) {}
573
574 virtual Phase GetPhase() MOZ_OVERRIDE { return eHookup; }
575 virtual Result Resolve() MOZ_OVERRIDE;
576 };
577
578 friend class TemplateBuilderHookup;
579
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);
590
591 nsresult
592 CheckBroadcasterHookup(Element* aElement,
593 bool* aNeedsHookup,
594 bool* aDidResolve);
595
596 void
597 SynchronizeBroadcastListener(Element *aBroadcaster,
598 Element *aListener,
599 const nsAString &aAttr);
600
601 static
602 nsresult
603 InsertElement(nsINode* aParent, nsIContent* aChild, bool aNotify);
604
605 static
606 nsresult
607 RemoveElement(nsINode* aParent, nsINode* aChild);
608
609 /**
610 * The current prototype that we are walking to construct the
611 * content model.
612 */
613 nsRefPtr<nsXULPrototypeDocument> mCurrentPrototype;
614
615 /**
616 * The master document (outermost, .xul) prototype, from which
617 * all subdocuments get their security principals.
618 */
619 nsRefPtr<nsXULPrototypeDocument> mMasterPrototype;
620
621 /**
622 * Owning references to all of the prototype documents that were
623 * used to construct this document.
624 */
625 nsTArray< nsRefPtr<nsXULPrototypeDocument> > mPrototypes;
626
627 /**
628 * Prepare to walk the current prototype.
629 */
630 nsresult PrepareToWalk();
631
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);
639
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);
654
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);
664
665 /**
666 * Add overlays from the chrome registry to the set of unprocessed
667 * overlays still to do.
668 */
669 nsresult AddChromeOverlays();
670
671 /**
672 * Resume (or initiate) an interrupted (or newly prepared)
673 * prototype walk.
674 */
675 nsresult ResumeWalk();
676
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();
683
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);
689
690 class CachedChromeStreamListener : public nsIStreamListener {
691 protected:
692 XULDocument* mDocument;
693 bool mProtoLoaded;
694
695 virtual ~CachedChromeStreamListener();
696
697 public:
698 CachedChromeStreamListener(XULDocument* aDocument,
699 bool aProtoLoaded);
700
701 NS_DECL_ISUPPORTS
702 NS_DECL_NSIREQUESTOBSERVER
703 NS_DECL_NSISTREAMLISTENER
704 };
705
706 friend class CachedChromeStreamListener;
707
708
709 class ParserObserver : public nsIRequestObserver {
710 protected:
711 nsRefPtr<XULDocument> mDocument;
712 nsRefPtr<nsXULPrototypeDocument> mPrototype;
713 virtual ~ParserObserver();
714
715 public:
716 ParserObserver(XULDocument* aDocument,
717 nsXULPrototypeDocument* aPrototype);
718
719 NS_DECL_ISUPPORTS
720 NS_DECL_NSIREQUESTOBSERVER
721 };
722
723 friend class ParserObserver;
724
725 /**
726 * A map from a broadcaster element to a list of listener elements.
727 */
728 PLDHashTable* mBroadcasterMap;
729
730 nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIObserver> > mOverlayLoadObservers;
731 nsAutoPtr<nsInterfaceHashtable<nsURIHashKey,nsIObserver> > mPendingOverlayLoadNotifications;
732
733 bool mInitialLayoutComplete;
734
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) {}
743
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) {}
753
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) {}
758
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;
767
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 };
775
776 nsTArray<nsDelayedBroadcastUpdate> mDelayedBroadcasters;
777 nsTArray<nsDelayedBroadcastUpdate> mDelayedAttrChangeBroadcasts;
778 bool mHandlingDelayedAttrChange;
779 bool mHandlingDelayedBroadcasters;
780
781 void MaybeBroadcast();
782 private:
783 // helpers
784
785 };
786
787 } // namespace dom
788 } // namespace mozilla
789
790 #endif // mozilla_dom_XULDocument_h

mercurial