Bug 544112 part 1: Make speculative and chrome style sheet loads go through the document object. Rearrange some C++ unit tests so they'll still link after part 2. r=bzbarsky sr=dbaron
authorZack Weinberg <zweinberg@mozilla.com>
Tue, 02 Mar 2010 13:00:39 -0800
changeset 38850 83a2cfa9ac46750c2d226bee5749cef9e5932075
parent 38849 f6beeb3157479d22e6abc3c2789f4a0606446fdc
child 38851 a1f9b5d1ccad1d31a46612f6883b3226158db663
push idunknown
push userunknown
push dateunknown
reviewersbzbarsky, dbaron
bugs544112
milestone1.9.3a3pre
Bug 544112 part 1: Make speculative and chrome style sheet loads go through the document object. Rearrange some C++ unit tests so they'll still link after part 2. r=bzbarsky sr=dbaron
chrome/src/nsChromeRegistry.cpp
chrome/src/nsChromeRegistry.h
content/base/public/nsIDocument.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
layout/Makefile.in
layout/html/tests/Makefile.in
layout/html/tests/ParseCSS.cpp
layout/html/tests/TestCSSPropertyLookup.cpp
layout/style/Makefile.in
layout/style/test/Makefile.in
layout/style/test/ParseCSS.cpp
layout/style/test/TestCSSPropertyLookup.cpp
parser/html/nsHtml5SpeculativeLoader.cpp
parser/htmlparser/src/nsParser.cpp
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -71,17 +71,16 @@
 #include "nsWidgetsCID.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsXPIDLString.h"
 #include "nsXULAppAPI.h"
 #include "nsTextFormatter.h"
 
 #include "nsIAtom.h"
 #include "nsICommandLine.h"
-#include "nsICSSLoader.h"
 #include "nsICSSStyleSheet.h"
 #include "nsIConsoleService.h"
 #include "nsIDirectoryService.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDocShell.h"
 #include "nsIDocumentObserver.h"
 #include "nsIDOMElement.h"
@@ -860,20 +859,16 @@ static void FlushSkinBindingsForWindow(n
 
   // Annihilate all XBL bindings.
   document->FlushSkinBindings();
 }
 
 // XXXbsmedberg: move this to nsIWindowMediator
 NS_IMETHODIMP nsChromeRegistry::RefreshSkins()
 {
-  nsCOMPtr<nsICSSLoader> cssLoader(do_CreateInstance(kCSSLoaderCID));
-  if (!cssLoader)
-    return NS_OK;
-
   nsCOMPtr<nsIWindowMediator> windowMediator
     (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
   if (!windowMediator)
     return NS_OK;
 
   nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
   windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
   PRBool more;
@@ -885,26 +880,26 @@ NS_IMETHODIMP nsChromeRegistry::RefreshS
       nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(protoWindow);
       if (domWindow)
         FlushSkinBindingsForWindow(domWindow);
     }
     windowEnumerator->HasMoreElements(&more);
   }
 
   FlushSkinCaches();
-  
+
   windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
   windowEnumerator->HasMoreElements(&more);
   while (more) {
     nsCOMPtr<nsISupports> protoWindow;
     windowEnumerator->GetNext(getter_AddRefs(protoWindow));
     if (protoWindow) {
       nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(protoWindow);
       if (domWindow)
-        RefreshWindow(domWindow, cssLoader);
+        RefreshWindow(domWindow);
     }
     windowEnumerator->HasMoreElements(&more);
   }
    
   return NS_OK;
 }
 
 void
@@ -922,30 +917,29 @@ static PRBool IsChromeURI(nsIURI* aURI)
 {
     PRBool isChrome=PR_FALSE;
     if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome)
         return PR_TRUE;
     return PR_FALSE;
 }
 
 // XXXbsmedberg: move this to windowmediator
-nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow,
-                                         nsICSSLoader* aCSSLoader)
+nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
 {
   // Deal with our subframes first.
   nsCOMPtr<nsIDOMWindowCollection> frames;
   aWindow->GetFrames(getter_AddRefs(frames));
   PRUint32 length;
   frames->GetLength(&length);
   PRUint32 j;
   for (j = 0; j < length; j++) {
     nsCOMPtr<nsIDOMWindow> childWin;
     frames->Item(j, getter_AddRefs(childWin));
     nsCOMPtr<nsIDOMWindowInternal> childInt(do_QueryInterface(childWin));
-    RefreshWindow(childInt, aCSSLoader);
+    RefreshWindow(childInt);
   }
 
   nsresult rv;
   // Get the DOM document.
   nsCOMPtr<nsIDOMDocument> domDocument;
   aWindow->GetDocument(getter_AddRefs(domDocument));
   if (!domDocument)
     return NS_OK;
@@ -968,18 +962,18 @@ nsresult nsChromeRegistry::RefreshWindow
 
       nsCOMPtr<nsIURI> uri;
       rv = sheet->GetSheetURI(getter_AddRefs(uri));
       if (NS_FAILED(rv)) return rv;
 
       if (IsChromeURI(uri)) {
         // Reload the sheet.
         nsCOMPtr<nsICSSStyleSheet> newSheet;
-        rv = aCSSLoader->LoadSheetSync(uri, PR_TRUE, PR_TRUE,
-                                       getter_AddRefs(newSheet));
+        rv = document->LoadChromeSheetSync(uri, PR_TRUE,
+                                           getter_AddRefs(newSheet));
         if (NS_FAILED(rv)) return rv;
         if (newSheet) {
           rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;
           if (NS_FAILED(rv)) return rv;
         }
       }
       else {  // Just use the same sheet.
         rv = newAgentSheets.AppendObject(sheet) ? NS_OK : NS_ERROR_FAILURE;
@@ -997,35 +991,34 @@ nsresult nsChromeRegistry::RefreshWindow
 
   PRInt32 count = document->GetNumberOfStyleSheets();
 
   // Iterate over the style sheets.
   PRInt32 i;
   for (i = 0; i < count; i++) {
     // Get the style sheet
     nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i);
-    
+
     if (!oldSheets.AppendObject(styleSheet)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
-  // Iterate over our old sheets and kick off a sync load of the new 
+  // Iterate over our old sheets and kick off a sync load of the new
   // sheet if and only if it's a chrome URL.
   for (i = 0; i < count; i++) {
     nsCOMPtr<nsICSSStyleSheet> sheet = do_QueryInterface(oldSheets[i]);
     nsIURI* uri = sheet ? sheet->GetOriginalURI() : nsnull;
 
     if (uri && IsChromeURI(uri)) {
       // Reload the sheet.
       nsCOMPtr<nsICSSStyleSheet> newSheet;
       // XXX what about chrome sheets that have a title or are disabled?  This
       // only works by sheer dumb luck.
-      // XXXbz this should really use the document's CSSLoader!
-      aCSSLoader->LoadSheetSync(uri, getter_AddRefs(newSheet));
+      document->LoadChromeSheetSync(uri, PR_FALSE, getter_AddRefs(newSheet));
       // Even if it's null, we put in in there.
       newSheets.AppendObject(newSheet);
     }
     else {
       // Just use the same sheet.
       newSheets.AppendObject(sheet);
     }
   }
--- a/chrome/src/nsChromeRegistry.h
+++ b/chrome/src/nsChromeRegistry.h
@@ -53,18 +53,16 @@
 #include "nsTHashtable.h"
 #include "nsURIHashKey.h"
 #include "nsVoidArray.h"
 #include "nsTArray.h"
 #include "nsInterfaceHashtable.h"
 
 struct PRFileDesc;
 class nsIAtom;
-class nsICSSLoader;
-class nsICSSStyleSheet;
 class nsIDOMWindowInternal;
 class nsILocalFile;
 class nsIPrefBranch;
 class nsIRDFDataSource;
 class nsIRDFResource;
 class nsIRDFService;
 class nsISimpleEnumerator;
 class nsIURL;
@@ -114,18 +112,17 @@ protected:
   nsresult LoadProfileDataSource();
 
   void FlushSkinCaches();
   void FlushAllCaches();
 
 private:
   nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
 
-  static nsresult RefreshWindow(nsIDOMWindowInternal* aWindow,
-                                nsICSSLoader* aCSSLoader);
+  static nsresult RefreshWindow(nsIDOMWindowInternal* aWindow);
   static nsresult GetProviderAndPath(nsIURL* aChromeURL,
                                      nsACString& aProvider, nsACString& aPath);
 
 #ifdef MOZ_XUL
   NS_HIDDEN_(void) ProcessProvider(PRFileDesc *fd, nsIRDFService* aRDFs,
                                    nsIRDFDataSource* ds, nsIRDFResource* aRoot,
                                    PRBool aIsLocale, const nsACString& aBaseURL);
   NS_HIDDEN_(void) ProcessOverlays(PRFileDesc *fd, nsIRDFDataSource* ds,
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -64,16 +64,17 @@ class nsSMILAnimationController;
 
 class nsIContent;
 class nsPresContext;
 class nsIPresShell;
 class nsIDocShell;
 class nsStyleSet;
 class nsIStyleSheet;
 class nsIStyleRule;
+class nsICSSStyleSheet;
 class nsIViewManager;
 class nsIScriptGlobalObject;
 class nsPIDOMWindow;
 class nsIDOMEvent;
 class nsIDOMEventTarget;
 class nsIDeviceContext;
 class nsIParser;
 class nsIDOMNode;
@@ -105,20 +106,20 @@ class nsFrameLoader;
 class nsIBoxObject;
 
 namespace mozilla {
 namespace dom {
 class Link;
 } // namespace dom
 } // namespace mozilla
 
-// IID for the nsIDocument interface
+// 0bce8f8b-8e27-44e6-92bc-65d0805b7fb4
 #define NS_IDOCUMENT_IID      \
-  { 0xd7978655, 0x9b7d, 0x41e6, \
-    { 0xad, 0x48, 0xdf, 0x32, 0x0b, 0x06, 0xb4, 0xda } }
+{ 0x0bce8f8b, 0x8e27, 0x44e6, \
+  { 0x92, 0xbc, 0x65, 0xd0, 0x80, 0x5b, 0x7f, 0xb4 } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 //----------------------------------------------------------------------
 
 // Document interface.  This is implemented by all document objects in
 // Gecko.
@@ -1204,16 +1205,33 @@ public:
   /**
    * Called by nsParser to preload images. Can be removed and code moved
    * to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
    * parser-module is linked with gklayout-module.
    */
   virtual void MaybePreLoadImage(nsIURI* uri) = 0;
 
   /**
+   * Called by nsParser to preload style sheets.  Can also be merged into
+   * the parser if and when the parser is merged with libgklayout.
+   */
+  virtual void PreloadStyle(nsIURI* aURI, const nsAString& aCharset) = 0;
+
+  /**
+   * Called by the chrome registry to load style sheets.  Can be put
+   * back there if and when when that module is merged with libgklayout.
+   *
+   * This always does a synchronous load.  If aIsAgentSheet is true,
+   * it also uses the system principal and enables unsafe rules.
+   * DO NOT USE FOR UNTRUSTED CONTENT.
+   */
+  virtual nsresult LoadChromeSheetSync(nsIURI* aURI, PRBool aIsAgentSheet,
+                                       nsICSSStyleSheet** aSheet) = 0;
+
+  /**
    * Returns true if the locale used for the document specifies a direction of
    * right to left. For chrome documents, this comes from the chrome registry.
    * This is used to determine the current state for the :-moz-locale-dir pseudoclass
    * so once can know whether a document is expected to be rendered left-to-right
    * or right-to-left.
    */
   virtual PRBool IsDocumentRightToLeft() { return PR_FALSE; }
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -7613,16 +7613,54 @@ nsDocument::MaybePreLoadImage(nsIURI* ur
   // Pin image-reference to avoid evicting it from the img-cache before
   // the "real" load occurs. Unpinned in DispatchContentLoadedEvents and
   // unlink
   if (NS_SUCCEEDED(rv)) {
     mPreloadingImages.AppendObject(request);
   }
 }
 
+namespace {
+
+/**
+ * Stub for LoadSheet(), since all we want is to get the sheet into
+ * the CSSLoader's style cache
+ */
+class StubCSSLoaderObserver : public nsICSSLoaderObserver {
+public:
+  NS_IMETHOD
+  StyleSheetLoaded(nsICSSStyleSheet*, PRBool, nsresult)
+  {
+    return NS_OK;
+  }
+  NS_DECL_ISUPPORTS
+};
+NS_IMPL_ISUPPORTS1(StubCSSLoaderObserver, nsICSSLoaderObserver)
+
+}
+
+void
+nsDocument::PreloadStyle(nsIURI* uri, const nsAString& charset)
+{
+  // The CSSLoader will retain this object after we return.
+  nsCOMPtr<nsICSSLoaderObserver> obs = new StubCSSLoaderObserver();
+
+  // Charset names are always ASCII.
+  CSSLoader()->LoadSheet(uri, NodePrincipal(),
+                         NS_LossyConvertUTF16toASCII(charset),
+                         obs);
+}
+
+nsresult
+nsDocument::LoadChromeSheetSync(nsIURI* uri, PRBool isAgentSheet,
+                                nsICSSStyleSheet** sheet)
+{
+  return CSSLoader()->LoadSheetSync(uri, isAgentSheet, isAgentSheet, sheet);
+}
+
 class nsDelayedEventDispatcher : public nsRunnable
 {
 public:
   nsDelayedEventDispatcher(nsTArray<nsCOMPtr<nsIDocument> >& aDocuments)
   {
     mDocuments.SwapElements(aDocuments);
   }
   virtual ~nsDelayedEventDispatcher() {}
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -928,16 +928,21 @@ public:
   nsresult CloneDocHelper(nsDocument* clone) const;
 
   void MaybeInitializeFinalizeFrameLoaders();
 
   void MaybeEndOutermostXBLUpdate();
 
   virtual void MaybePreLoadImage(nsIURI* uri);
 
+  virtual void PreloadStyle(nsIURI* uri, const nsAString& charset);
+
+  virtual nsresult LoadChromeSheetSync(nsIURI* uri, PRBool isAgentSheet,
+                                       nsICSSStyleSheet** sheet);
+
   virtual nsISupports* GetCurrentContentSink();
 
 protected:
   friend class nsNodeUtils;
   void RegisterNamedItems(nsIContent *aContent);
   void UnregisterNamedItems(nsIContent *aContent);
   void UpdateNameTableEntry(nsIContent *aContent);
   void UpdateIdTableEntry(nsIContent *aContent);
--- a/layout/Makefile.in
+++ b/layout/Makefile.in
@@ -78,17 +78,13 @@ endif
 DIRS           += build
 
 ifdef ENABLE_TESTS
 PARALLEL_DIRS += \
   xul/test \
   xul/base/test \
   $(NULL)
 
-TOOL_DIRS      += tools/reftest
+TOOL_DIRS      += tools/reftest reftests/fonts reftests/fonts/mplus
 DIRS           += tools/pageloader
-ifndef MOZ_ENABLE_LIBXUL
-TOOL_DIRS	+= html/tests
-endif
-TOOL_DIRS	+= reftests/fonts reftests/fonts/mplus
 endif
 
 include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/layout/html/tests/Makefile.in
+++ /dev/null
@@ -1,80 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of the GNU General Public License Version 2 or later (the "GPL"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH		= ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MOZILLA_INTERNAL_API = 1
-
-
-SIMPLE_PROGRAMS	= $(CPPSRCS:.cpp=$(BIN_SUFFIX))
-
-CPPSRCS		= \
-		ParseCSS.cpp \
-		TestCSSPropertyLookup.cpp \
-		$(NULL)
-
-LIBS		= \
-	$(LIBS_DIR) \
-	$(DEPTH)/content/html/content/src/$(LIB_PREFIX)gkconhtmlcon_s.$(LIB_SUFFIX) \
-	$(DEPTH)/content/html/document/src/$(LIB_PREFIX)gkconhtmldoc_s.$(LIB_SUFFIX) \
-	../../forms/$(LIB_PREFIX)gkforms_s.$(LIB_SUFFIX) \
-	../../style/$(LIB_PREFIX)gkstyle_s.$(LIB_SUFFIX) \
-	../../tables/$(LIB_PREFIX)gktable_s.$(LIB_SUFFIX) \
-	../../base/$(LIB_PREFIX)gkbase_s.$(LIB_SUFFIX) \
-	../../generic/$(LIB_PREFIX)gkgeneric_s.$(LIB_SUFFIX) \
-	$(DEPTH)/content/base/src/$(LIB_PREFIX)gkconbase_s.$(LIB_SUFFIX) \
-	$(DEPTH)/content/events/src/$(LIB_PREFIX)gkconevents_s.$(LIB_SUFFIX) \
-	$(DEPTH)/content/xml/content/src/$(LIB_PREFIX)gkconxmlcon_s.$(LIB_SUFFIX) \
-	$(DEPTH)/content/xml/document/src/$(LIB_PREFIX)gkconxmldoc_s.$(LIB_SUFFIX) \
-	../../xul/base/src/$(LIB_PREFIX)gkxulbase_s.$(LIB_SUFFIX) \
-	$(MOZ_JS_LIBS) \
-	$(call EXPAND_LIBNAME_PATH,gkgfx,$(DEPTH)/gfx/src) \
-	$(TK_LIBS) \
-	$(MOZ_UNICHARUTIL_LIBS) \
-	$(MOZ_COMPONENT_LIBS) \
-	$(NULL)
-
-include $(topsrcdir)/config/config.mk
-
-include $(topsrcdir)/config/rules.mk
-
-DEFINES += -D_IMPL_NS_LAYOUT
--- a/layout/style/Makefile.in
+++ b/layout/style/Makefile.in
@@ -36,20 +36,20 @@
 
 DEPTH		= ../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
-DIRS = xbl-marquee
+DIRS		= xbl-marquee
 
 ifdef ENABLE_TESTS
-DIRS		+= test
+TOOL_DIRS	= test
 endif
 
 MODULE		= layout
 LIBRARY_NAME	= gkstyle_s
 LIBXUL_LIBRARY	= 1
 
 
 EXPORTS		= \
--- a/layout/style/test/Makefile.in
+++ b/layout/style/test/Makefile.in
@@ -57,28 +57,46 @@ HOST_CXXFLAGS	+= -DMOZ_SVG=1
 endif
 
 HOST_CPPSRCS	= \
 		ListCSSProperties.cpp \
 		$(NULL)
 
 HOST_SIMPLE_PROGRAMS	= $(addprefix host_, $(HOST_CPPSRCS:.cpp=$(HOST_BIN_SUFFIX)))
 
+
+# ParseCSS.cpp used to be built as a test program, but it was not
+# being used for anything, and recent changes to the CSS loader have
+# made it fail to link.  Further changes are planned which should make
+# it buildable again.
+#
+# TestCSSPropertyLookup.cpp needs the internal XPCOM APIs and so cannot
+# be built with libxul enabled.
+
+ifndef MOZ_ENABLE_LIBXUL
+CPP_UNIT_TESTS = TestCSSPropertyLookup.cpp
+LIBS += ../nsCSSKeywords.o ../nsCSSProps.o $(XPCOM_LIBS)
+endif
+
 include $(topsrcdir)/config/rules.mk
 
+DEFINES += -DMOZILLA_INTERNAL_API -D_IMPL_NS_LAYOUT
+
 # FIXME: We don't seem to do auto-generated dependencies here.
 host_ListCSSProperties.$(OBJ_SUFFIX): $(srcdir)/../nsCSSPropList.h
+TestCSSPropertyLookup.$(OBJ_SUFFIX): $(srcdir)/../nsCSSProps.h $(srcdir)/../nsCSSKeywords.h
 
 css_properties.js: host_ListCSSProperties$(HOST_BIN_SUFFIX) css_properties_like_longhand.js Makefile
 	$(RM) $@
 	./host_ListCSSProperties$(HOST_BIN_SUFFIX) > $@
 	cat $(srcdir)/css_properties_like_longhand.js >> $@
 
 GARBAGE += css_properties.js
 
+
 _TEST_FILES =	test_acid3_test46.html \
 		test_at_rule_parse_serialize.html \
 		test_bug73586.html \
 		test_bug74880.html \
 		test_bug98997.html \
 		test_bug160403.html \
 		test_bug221428.html \
 		test_bug229915.html \
rename from layout/html/tests/ParseCSS.cpp
rename to layout/style/test/ParseCSS.cpp
rename from layout/html/tests/TestCSSPropertyLookup.cpp
rename to layout/style/test/TestCSSPropertyLookup.cpp
--- a/layout/html/tests/TestCSSPropertyLookup.cpp
+++ b/layout/style/test/TestCSSPropertyLookup.cpp
@@ -34,28 +34,31 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include <stdio.h>
 #include "plstr.h"
 #include "nsCSSProps.h"
 #include "nsCSSKeywords.h"
 #include "nsString.h"
+#include "nsXPCOM.h"
 
 static const char* const kJunkNames[] = {
   nsnull,
   "",
   "123",
   "backgroundz",
   "zzzzzz",
   "#@$&@#*@*$@$#"
 };
 
-int TestProps() {
-  int rv = 0;
+static bool
+TestProps()
+{
+  bool success = true;
   nsCSSProperty id;
   nsCSSProperty index;
 
   // Everything appears to assert if we don't do this first...
   nsCSSProps::AddRefTable();
 
   // First make sure we can find all of the tags that are supposed to
   // be in the table. Futz with the case to make sure any case will
@@ -67,57 +70,59 @@ int TestProps() {
   while (et < end) {
     char tagName[100];
     PL_strcpy(tagName, *et);
     index = nsCSSProperty(PRInt32(index) + 1);
 
     id = nsCSSProps::LookupProperty(nsCString(tagName));
     if (id == eCSSProperty_UNKNOWN) {
       printf("bug: can't find '%s'\n", tagName);
-      rv = -1;
+      success = false;
     }
     if (id != index) {
       printf("bug: name='%s' id=%d index=%d\n", tagName, id, index);
-      rv = -1;
+      success = false;
     }
 
     // fiddle with the case to make sure we can still find it
     if (('a' <= tagName[0]) && (tagName[0] <= 'z')) {
       tagName[0] = tagName[0] - 32;
     }
     id = nsCSSProps::LookupProperty(NS_ConvertASCIItoUTF16(tagName));
     if (id < 0) {
       printf("bug: can't find '%s'\n", tagName);
-      rv = -1;
+      success = false;
     }
     if (index != id) {
       printf("bug: name='%s' id=%d index=%d\n", tagName, id, index);
-      rv = -1;
+      success = false;
     }
     et++;
   }
 
   // Now make sure we don't find some garbage
   for (int i = 0; i < (int) (sizeof(kJunkNames) / sizeof(const char*)); i++) {
     const char* const tag = kJunkNames[i];
     id = nsCSSProps::LookupProperty(nsCAutoString(tag));
     if (id >= 0) {
       printf("bug: found '%s'\n", tag ? tag : "(null)");
-      rv = -1;
+      success = false;
     }
   }
 
   nsCSSProps::ReleaseTable();
-  return rv;
+  return success;
 }
 
-int TestKeywords() {
+bool
+TestKeywords()
+{
   nsCSSKeywords::AddRefTable();
 
-  int rv = 0;
+  bool success = true;
   nsCSSKeyword id;
   nsCSSKeyword index;
 
   extern const char* const kCSSRawKeywords[];
 
   // First make sure we can find all of the tags that are supposed to
   // be in the table. Futz with the case to make sure any case will
   // work
@@ -135,51 +140,60 @@ int TestKeywords() {
       }
       underscore++;
     }
     index = nsCSSKeyword(PRInt32(index) + 1);
 
     id = nsCSSKeywords::LookupKeyword(nsCString(tagName));
     if (id <= eCSSKeyword_UNKNOWN) {
       printf("bug: can't find '%s'\n", tagName);
-      rv = -1;
+      success = false;
     }
     if (id != index) {
       printf("bug: name='%s' id=%d index=%d\n", tagName, id, index);
-      rv = -1;
+      success = false;
     }
 
     // fiddle with the case to make sure we can still find it
     if (('a' <= tagName[0]) && (tagName[0] <= 'z')) {
       tagName[0] = tagName[0] - 32;
     }
     id = nsCSSKeywords::LookupKeyword(nsCString(tagName));
     if (id <= eCSSKeyword_UNKNOWN) {
       printf("bug: can't find '%s'\n", tagName);
-      rv = -1;
+      success = false;
     }
     if (id != index) {
       printf("bug: name='%s' id=%d index=%d\n", tagName, id, index);
-      rv = -1;
+      success = false;
     }
     et++;
   }
 
   // Now make sure we don't find some garbage
   for (int i = 0; i < (int) (sizeof(kJunkNames) / sizeof(const char*)); i++) {
     const char* const tag = kJunkNames[i];
     id = nsCSSKeywords::LookupKeyword(nsCAutoString(tag));
     if (eCSSKeyword_UNKNOWN < id) {
       printf("bug: found '%s'\n", tag ? tag : "(null)");
-      rv = -1;
+      success = false;
     }
   }
 
   nsCSSKeywords::ReleaseTable();
-  return rv;
+  return success;
 }
 
-int main(int argc, char** argv)
+int
+main(void)
 {
-  TestProps();
-  TestKeywords();
-  return 0;
+  nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
+  NS_ENSURE_SUCCESS(rv, 2);
+
+  bool testOK = true;
+  testOK &= TestProps();
+  testOK &= TestKeywords();
+
+  rv = NS_ShutdownXPCOM(nsnull);
+  NS_ENSURE_SUCCESS(rv, 2);
+
+  return testOK ? 0 : 1;
 }
--- a/parser/html/nsHtml5SpeculativeLoader.cpp
+++ b/parser/html/nsHtml5SpeculativeLoader.cpp
@@ -34,38 +34,22 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHtml5SpeculativeLoader.h"
-#include "nsICSSLoader.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
-#include "nsICSSLoaderObserver.h"
 #include "nsIDocument.h"
 
-/**
- * Used if we need to pass an nsICSSLoaderObserver as parameter,
- * but don't really need its services
- */
-class nsHtml5DummyCSSLoaderObserver : public nsICSSLoaderObserver {
-public:
-  NS_IMETHOD
-  StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aWasAlternate, nsresult aStatus) {
-      return NS_OK;
-  }
-  NS_DECL_ISUPPORTS
-};
-
-NS_IMPL_ISUPPORTS1(nsHtml5DummyCSSLoaderObserver, nsICSSLoaderObserver)
-
-nsHtml5SpeculativeLoader::nsHtml5SpeculativeLoader(nsHtml5TreeOpExecutor* aExecutor)
+nsHtml5SpeculativeLoader::
+nsHtml5SpeculativeLoader(nsHtml5TreeOpExecutor* aExecutor)
   : mExecutor(aExecutor)
 {
   MOZ_COUNT_CTOR(nsHtml5SpeculativeLoader);
   mPreloadedURLs.Init(23); // Mean # of preloadable resources per page on dmoz
 }
 
 nsHtml5SpeculativeLoader::~nsHtml5SpeculativeLoader()
 {
@@ -120,23 +104,19 @@ nsHtml5SpeculativeLoader::PreloadScript(
 void
 nsHtml5SpeculativeLoader::PreloadStyle(const nsAString& aURL,
                                        const nsAString& aCharset)
 {
   nsCOMPtr<nsIURI> uri = ConvertIfNotPreloadedYet(aURL);
   if (!uri) {
     return;
   }
-  nsCOMPtr<nsICSSLoaderObserver> obs = new nsHtml5DummyCSSLoaderObserver();
   nsIDocument* doc = mExecutor->GetDocument();
   if (doc) {
-    doc->CSSLoader()->LoadSheet(uri, 
-                                doc->NodePrincipal(),
-                                NS_LossyConvertUTF16toASCII(aCharset),
-                                obs);
+    doc->PreloadStyle(uri, aCharset);
   }
 }
 
 void
 nsHtml5SpeculativeLoader::PreloadImage(const nsAString& aURL)
 {
   nsCOMPtr<nsIURI> uri = ConvertIfNotPreloadedYet(aURL);
   if (!uri) {
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -67,18 +67,16 @@
 #include "nsHTMLTokenizer.h"
 #include "nsIDocument.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
 #include "nsDataHashtable.h"
 #include "nsIThreadPool.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsICSSStyleSheet.h"
-#include "nsICSSLoaderObserver.h"
-#include "nsICSSLoader.h"
 #include "nsMimeTypes.h"
 
 #ifdef MOZ_VIEW_SOURCE
 #include "nsViewSourceHTML.h"
 #endif
 
 #define NS_PARSER_FLAG_PARSER_ENABLED         0x00000002
 #define NS_PARSER_FLAG_OBSERVERS_ENABLED      0x00000004
@@ -290,31 +288,16 @@ private:
 
   // These members are only accessed on the main thread.
   nsCOMPtr<nsIDocument> mDocument;
   CParserContext *mContext;
   PreloadedType mPreloadedURIs;
   PRBool mTerminated;
 };
 
-/**
- * Used if we need to pass an nsICSSLoaderObserver as parameter,
- * but don't really need its services
- */
-class nsDummyCSSLoaderObserver : public nsICSSLoaderObserver {
-public:
-  NS_IMETHOD
-  StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aWasAlternate, nsresult aStatus) {
-      return NS_OK;
-  }
-  NS_DECL_ISUPPORTS
-};
-
-NS_IMPL_ISUPPORTS1(nsDummyCSSLoaderObserver, nsICSSLoaderObserver)
-
 class nsPreloadURIs : public nsIRunnable {
 public:
   nsPreloadURIs(nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> &aURIs,
                 nsSpeculativeScriptThread *aScriptThread)
     : mURIs(aURIs),
       mScriptThread(aScriptThread) {
   }
 
@@ -381,23 +364,19 @@ nsPreloadURIs::PreloadURIs(const nsAutoT
 
     switch (pe.type) {
       case nsSpeculativeScriptThread::SCRIPT:
         doc->ScriptLoader()->PreloadURI(uri, pe.charset, pe.elementType);
         break;
       case nsSpeculativeScriptThread::IMAGE:
         doc->MaybePreLoadImage(uri);
         break;
-      case nsSpeculativeScriptThread::STYLESHEET: {
-        nsCOMPtr<nsICSSLoaderObserver> obs = new nsDummyCSSLoaderObserver();
-        doc->CSSLoader()->LoadSheet(uri, doc->NodePrincipal(),
-                                    NS_LossyConvertUTF16toASCII(pe.charset),
-                                    obs);
+      case nsSpeculativeScriptThread::STYLESHEET:
+        doc->PreloadStyle(uri, pe.charset);
         break;
-      }
       case nsSpeculativeScriptThread::NONE:
         NS_NOTREACHED("Uninitialized preload entry?");
         break;
     }
   }
 }
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsSpeculativeScriptThread, nsIRunnable)