Bug 185236 part 4. Pass along the owning element to all sheet load datas, assuming we have one at all. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 26 Sep 2011 17:27:00 -0400
changeset 77616 231da6eb82249cfc7fdccb858adcede1adc47ea7
parent 77615 2c05e937de5d8eb6002eb74e8b4a6f30cc303887
child 77617 c8e237c03adb5feb6a144c8f3bb55b13f773401e
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewerspeterv
bugs185236
milestone9.0a1
Bug 185236 part 4. Pass along the owning element to all sheet load datas, assuming we have one at all. r=peterv
layout/style/Loader.cpp
layout/style/Loader.h
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -219,17 +219,19 @@ public:
   // mIsCancelled is set to true when a sheet load is stopped by
   // Stop() or StopLoadingSheet() (which was removed in Bug 556446).
   // SheetLoadData::OnStreamComplete() checks this to avoid parsing
   // sheets that have been cancelled and such.
   PRPackedBool               mIsCancelled : 1;
 
   // mMustNotify is true if the load data is being loaded async and
   // the original function call that started the load has returned.
-  // XXXbz sort our relationship with load/error events!
+  // This applies only to observer notifications; load/error events
+  // are fired for any SheetLoadData that has a non-null
+  // mOwningElement.
   PRPackedBool               mMustNotify : 1;
 
   // mWasAlternate is true if the sheet was an alternate when the load data was
   // created.
   PRPackedBool               mWasAlternate : 1;
 
   // mAllowUnsafeRules is true if we should allow unsafe rules to be parsed
   // in the loaded sheet.
@@ -240,17 +242,17 @@ public:
   // loads.
   PRPackedBool               mUseSystemPrincipal : 1;
 
   // If true, this SheetLoadData is being used as a way to handle
   // async observer notification for an already-complete sheet.
   PRPackedBool               mSheetAlreadyComplete : 1;
 
   // This is the element that imported the sheet.  Needed to get the
-  // charset set on it.
+  // charset set on it and to fire load/error events.
   nsCOMPtr<nsIStyleSheetLinkingElement> mOwningElement;
 
   // The observer that wishes to be notified of load completion
   nsCOMPtr<nsICSSLoaderObserver>        mObserver;
 
   // The principal that identifies who started loading us.
   nsCOMPtr<nsIPrincipal>                mLoaderPrincipal;
 
@@ -1823,29 +1825,30 @@ Loader::LoadStyleLink(nsIContent* aEleme
                     aIsAlternate);
   NS_ENSURE_SUCCESS(rv, rv);
 
   LOG(("  Sheet is alternate: %d", *aIsAlternate));
 
   rv = InsertSheetInDoc(sheet, aElement, mDocument);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsCOMPtr<nsIStyleSheetLinkingElement> owningElement(do_QueryInterface(aElement));
+
   if (state == eSheetComplete) {
     LOG(("  Sheet already complete: 0x%p",
          static_cast<void*>(sheet.get())));
-    if (aObserver || !mObservers.IsEmpty()) {
-      rv = PostLoadEvent(aURL, sheet, aObserver, *aIsAlternate);
+    if (aObserver || !mObservers.IsEmpty() || owningElement) {
+      rv = PostLoadEvent(aURL, sheet, aObserver, *aIsAlternate,
+                         owningElement);
       return rv;
     }
 
     return NS_OK;
   }
 
-  nsCOMPtr<nsIStyleSheetLinkingElement> owningElement(do_QueryInterface(aElement));
-
   // Now we need to actually load it
   SheetLoadData* data = new SheetLoadData(this, aTitle, aURL, sheet,
                                           owningElement, *aIsAlternate,
                                           aObserver, principal);
   NS_ADDREF(data);
 
   // If we have to parse and it's an alternate non-inline, defer it
   if (aURL && state == eSheetNeedsParser && mLoadingDatas.Count() != 0 &&
@@ -2087,17 +2090,17 @@ Loader::InternalLoadNonDocumentSheet(nsI
 
   const nsSubstring& empty = EmptyString();
   rv = PrepareSheet(sheet, empty, empty, nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (state == eSheetComplete) {
     LOG(("  Sheet already complete"));
     if (aObserver || !mObservers.IsEmpty()) {
-      rv = PostLoadEvent(aURL, sheet, aObserver, PR_FALSE);
+      rv = PostLoadEvent(aURL, sheet, aObserver, PR_FALSE, nsnull);
     }
     if (aSheet) {
       sheet.swap(*aSheet);
     }
     return rv;
   }
 
   SheetLoadData* data =
@@ -2118,27 +2121,29 @@ Loader::InternalLoadNonDocumentSheet(nsI
 
   return rv;
 }
 
 nsresult
 Loader::PostLoadEvent(nsIURI* aURI,
                       nsCSSStyleSheet* aSheet,
                       nsICSSLoaderObserver* aObserver,
-                      PRBool aWasAlternate)
+                      PRBool aWasAlternate,
+                      nsIStyleSheetLinkingElement* aElement)
 {
   LOG(("css::Loader::PostLoadEvent"));
   NS_PRECONDITION(aSheet, "Must have sheet");
-  NS_PRECONDITION(aObserver || !mObservers.IsEmpty(), "Must have observer");
+  NS_PRECONDITION(aObserver || !mObservers.IsEmpty() || aElement,
+                  "Must have observer or element");
 
   nsRefPtr<SheetLoadData> evt =
     new SheetLoadData(this, EmptyString(), // title doesn't matter here
                       aURI,
                       aSheet,
-                      nsnull,  // owning element doesn't matter here
+                      aElement,
                       aWasAlternate,
                       aObserver,
                       nsnull);
   NS_ENSURE_TRUE(evt, NS_ERROR_OUT_OF_MEMORY);
 
   if (!mPostedEvents.AppendElement(evt)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
--- a/layout/style/Loader.h
+++ b/layout/style/Loader.h
@@ -53,16 +53,17 @@
 
 class nsIAtom;
 class nsICSSLoaderObserver;
 class nsCSSStyleSheet;
 class nsIContent;
 class nsIDocument;
 class nsCSSParser;
 class nsMediaList;
+class nsIStyleSheetLinkingElement;
 
 namespace mozilla {
 
 class URIAndPrincipalHashKey : public nsURIHashKey
 {
 public:
   typedef URIAndPrincipalHashKey* KeyType;
   typedef const URIAndPrincipalHashKey* KeyTypePointer;
@@ -417,21 +418,23 @@ private:
                                         nsCSSStyleSheet** aSheet,
                                         nsICSSLoaderObserver* aObserver);
 
   // Post a load event for aObserver to be notified about aSheet.  The
   // notification will be sent with status NS_OK unless the load event is
   // canceled at some point (in which case it will be sent with
   // NS_BINDING_ABORTED).  aWasAlternate indicates the state when the load was
   // initiated, not the state at some later time.  aURI should be the URI the
-  // sheet was loaded from (may be null for inline sheets).
+  // sheet was loaded from (may be null for inline sheets).  aElement is the
+  // owning element for this sheet.
   nsresult PostLoadEvent(nsIURI* aURI,
                          nsCSSStyleSheet* aSheet,
                          nsICSSLoaderObserver* aObserver,
-                         PRBool aWasAlternate);
+                         PRBool aWasAlternate,
+                         nsIStyleSheetLinkingElement* aElement);
 
   // Start the loads of all the sheets in mPendingDatas
   void StartAlternateLoads();
 
   // Handle an event posted by PostLoadEvent
   void HandleLoadEvent(SheetLoadData* aEvent);
 
   // Note: LoadSheet is responsible for releasing aLoadData and setting the