Bug 1024707 - Add API to register style sheets but without loading them. r=bz
authorTom Schuster <evilpies@gmail.com>
Wed, 09 Jul 2014 11:43:33 +0200
changeset 193209 2a5d0b30705505a1aa74ede709d844ad62378987
parent 193208 f3b37ad2b42f039e11398c4b19ca658d585e29a3
child 193210 c0076344ffbb7bfbd55a1c9ea7f53ccacf7e9c89
push id27112
push usercbook@mozilla.com
push dateThu, 10 Jul 2014 12:47:23 +0000
treeherdermozilla-central@6e9f72bdd32e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1024707
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1024707 - Add API to register style sheets but without loading them. r=bz
CLOBBER
content/base/public/nsIDocument.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
dom/base/moz.build
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
layout/base/nsIStyleSheetService.idl
layout/base/nsStyleSheetService.cpp
layout/base/nsStyleSheetService.h
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,11 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Bug 1033481 - Use a .mozbuild file rather than a .mk in
-m/a/tests/background/junit3 -- doesn't clean the classes* directory
-when moving from in APK to in JAR building.
+Bug 1024707 - It seems like changing 3 uuids is just too much!
\ No newline at end of file
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -127,18 +127,18 @@ template<typename> class OwningNonNull;
 template<typename> class Sequence;
 
 template<typename, typename> class CallbackObjectHolder;
 typedef CallbackObjectHolder<NodeFilter, nsIDOMNodeFilter> NodeFilterHolder;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_IDOCUMENT_IID \
-{ 0xc9e11955, 0xaa55, 0x49a1, \
-  { 0x94, 0x29, 0x58, 0xe9, 0xbe, 0xf6, 0x79, 0x54 } }
+{ 0xa45ef8f0, 0x7c5b, 0x425d, \
+  { 0xa5, 0xe7, 0x11, 0x41, 0x5c, 0x41, 0x0c, 0x7a } }
 
 // Enum for requesting a particular type of document when creating a doc
 enum DocumentFlavor {
   DocumentFlavorLegacyGuess, // compat with old code until made HTML5-compliant
   DocumentFlavorHTML, // HTMLDocument with HTMLness bit set to true
   DocumentFlavorSVG, // SVGDocument
   DocumentFlavorPlain, // Just a Document
 };
@@ -846,16 +846,17 @@ public:
   enum additionalSheetType {
     eAgentSheet,
     eUserSheet,
     eAuthorSheet,
     SheetTypeCount
   };
 
   virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) = 0;
+  virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType, nsIStyleSheet* aSheet) = 0;
   virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) = 0;
   virtual nsIStyleSheet* FirstAdditionalAuthorSheet() = 0;
 
   /**
    * Get this document's CSSLoader.  This is guaranteed to not return null.
    */
   mozilla::css::Loader* CSSLoader() const {
     return mCSSLoader;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -4216,32 +4216,44 @@ nsDocument::LoadAdditionalStyleSheet(add
   // Loading the sheet sync.
   nsRefPtr<mozilla::css::Loader> loader = new mozilla::css::Loader();
 
   nsRefPtr<CSSStyleSheet> sheet;
   nsresult rv = loader->LoadSheetSync(aSheetURI, aType == eAgentSheet,
     true, getter_AddRefs(sheet));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mAdditionalSheets[aType].AppendObject(sheet);
   sheet->SetOwningDocument(this);
   MOZ_ASSERT(sheet->IsApplicable());
 
+  return AddAdditionalStyleSheet(aType, sheet);
+}
+
+nsresult
+nsDocument::AddAdditionalStyleSheet(additionalSheetType aType, nsIStyleSheet* aSheet)
+{
+  if (mAdditionalSheets[aType].Contains(aSheet))
+    return NS_ERROR_INVALID_ARG;
+
+  if (!aSheet->IsApplicable())
+    return NS_ERROR_INVALID_ARG;
+
+  mAdditionalSheets[aType].AppendObject(aSheet);
+
   BeginUpdate(UPDATE_STYLE);
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
     nsStyleSet::sheetType type = ConvertAdditionalSheetType(aType);
-    shell->StyleSet()->AppendStyleSheet(type, sheet);
+    shell->StyleSet()->AppendStyleSheet(type, aSheet);
   }
 
   // Passing false, so documet.styleSheets.length will not be affected by
   // these additional sheets.
-  NotifyStyleSheetAdded(sheet, false);
+  NotifyStyleSheetAdded(aSheet, false);
   EndUpdate(UPDATE_STYLE);
-
   return NS_OK;
 }
 
 void
 nsDocument::RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI)
 {
   MOZ_ASSERT(aSheetURI);
 
@@ -11870,16 +11882,20 @@ nsIDocument::DocAddSizeOfIncludingThis(n
   DocAddSizeOfExcludingThis(aWindowSizes);
 }
 
 static size_t
 SizeOfStyleSheetsElementIncludingThis(nsIStyleSheet* aStyleSheet,
                                       MallocSizeOf aMallocSizeOf,
                                       void* aData)
 {
+  if (!aStyleSheet->GetOwningDocument()) {
+    // Avoid over-reporting shared sheets.
+    return 0;
+  }
   return aStyleSheet->SizeOfIncludingThis(aMallocSizeOf);
 }
 
 size_t
 nsDocument::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   // This SizeOfExcludingThis() overrides the one from nsINode.  But
   // nsDocuments can only appear at the top of the DOM tree, and we use the
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -804,16 +804,17 @@ public:
   virtual void AddStyleSheetToStyleSets(nsIStyleSheet* aSheet);
   virtual void RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet);
 
   virtual void InsertStyleSheetAt(nsIStyleSheet* aSheet, int32_t aIndex) MOZ_OVERRIDE;
   virtual void SetStyleSheetApplicableState(nsIStyleSheet* aSheet,
                                             bool aApplicable) MOZ_OVERRIDE;
 
   virtual nsresult LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) MOZ_OVERRIDE;
+  virtual nsresult AddAdditionalStyleSheet(additionalSheetType aType, nsIStyleSheet* aSheet) MOZ_OVERRIDE;
   virtual void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI) MOZ_OVERRIDE;
   virtual nsIStyleSheet* FirstAdditionalAuthorSheet() MOZ_OVERRIDE;
 
   virtual nsIChannel* GetChannel() const MOZ_OVERRIDE {
     return mChannel;
   }
 
   virtual nsIChannel* GetFailedChannel() const MOZ_OVERRIDE {
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -156,16 +156,17 @@ LOCAL_INCLUDES += [
     '../src/geolocation',
     '../src/storage',
     '../time',
     '../workers',
     '../xbl',
     '/content/base/src',
     '/content/html/document/src',
     '/content/xul/document/src',
+    '/layout/base',
     '/layout/generic',
     '/layout/style',
     '/layout/xul',
     '/widget/shared',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
     LOCAL_INCLUDES += [
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -85,16 +85,18 @@
 #include "nsDisplayList.h"
 #include "nsROCSSPrimitiveValue.h"
 #include "nsIBaseWindow.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "GeckoProfiler.h"
 #include "mozilla/Preferences.h"
 #include "nsIContentIterator.h"
+#include "nsIDOMStyleSheet.h"
+#include "nsIStyleSheet.h"
 #include "nsContentPermissionHelper.h"
 
 #ifdef XP_WIN
 #undef GetClassName
 #endif
 
 using namespace mozilla;
 using namespace mozilla::dom;
@@ -3363,16 +3365,38 @@ nsDOMWindowUtils::LoadSheet(nsIURI *aShe
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
 
   return doc->LoadAdditionalStyleSheet(type, aSheetURI);
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::AddSheet(nsIDOMStyleSheet *aSheet, uint32_t aSheetType)
+{
+  MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
+
+  NS_ENSURE_ARG_POINTER(aSheet);
+  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
+                aSheetType == USER_SHEET ||
+                aSheetType == AUTHOR_SHEET);
+
+  nsCOMPtr<nsIDocument> doc = GetDocument();
+  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
+
+  nsIDocument::additionalSheetType type = convertSheetType(aSheetType);
+  nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
+  NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
+  if (sheet->GetOwningDocument()) {
+    return NS_ERROR_INVALID_ARG;
+  }
+  return doc->AddAdditionalStyleSheet(type, sheet);
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::RemoveSheet(nsIURI *aSheetURI, uint32_t aSheetType)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   NS_ENSURE_ARG_POINTER(aSheetURI);
   NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
                 aSheetType == USER_SHEET ||
                 aSheetType == AUTHOR_SHEET);
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -30,32 +30,33 @@ native nscolor(nscolor);
 typedef unsigned long long nsViewID;
 
 interface nsICycleCollectorListener;
 interface nsIDOMNode;
 interface nsIDOMNodeList;
 interface nsIDOMElement;
 interface nsIDOMHTMLCanvasElement;
 interface nsIDOMEvent;
+interface nsIDOMStyleSheet;
 interface nsITransferable;
 interface nsIQueryContentEventResult;
 interface nsIDOMWindow;
 interface nsIDOMBlob;
 interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMClientRect;
 interface nsIURI;
 interface nsIDOMEventTarget;
 interface nsIRunnable;
 interface nsICompositionStringSynthesizer;
 interface nsITranslationNodeList;
 interface nsIJSRAIIHelper;
 interface nsIContentPermissionRequest;
 
-[scriptable, uuid(ca202fa7-7b8f-4814-acc3-a8545f67320b)]
+[scriptable, uuid(0ef9e8bb-b934-4f6b-ae05-e98774d8d3d3)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -1558,25 +1559,32 @@ interface nsIDOMWindowUtils : nsISupport
    * of additional style sheets of the document.
    *
    * These additional style sheets are very much like user/agent sheets loaded 
    * with loadAndRegisterSheet. The only difference is that they are applied only
    * on the document owned by this window.
    *
    * Sheets added via this API take effect immediately on the document.
    */
-  void loadSheet(in nsIURI sheetURI,
-                           in unsigned long type);
+  void loadSheet(in nsIURI sheetURI, in unsigned long type);
+
+  /**
+   * Adds a style sheet to the list of additional style sheets of the document.
+   *
+   * Style sheets can be preloaded with nsIStyleSheetService.preloadSheet.
+   *
+   * Sheets added via this API take effect immediately on the document.
+   */
+  void addSheet(in nsIDOMStyleSheet sheet, in unsigned long type);
 
   /**
    * Remove the document style sheet at |sheetURI| from the list of additional 
    * style sheets of the document.  The removal takes effect immediately.
    */
-  void removeSheet(in nsIURI sheetURI,
-                                in unsigned long type);
+  void removeSheet(in nsIURI sheetURI, in unsigned long type);
 
   /**
    * Returns true if a user input is being handled.
    *
    * This calls EventStateManager::IsHandlingUserInput().
    */
   readonly attribute boolean isHandlingUserInput;
 
--- a/layout/base/nsIStyleSheetService.idl
+++ b/layout/base/nsIStyleSheetService.idl
@@ -3,23 +3,24 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* interface for managing user and user-agent style sheets */
 
 #include "nsISupports.idl"
 
 interface nsIURI;
+interface nsIDOMStyleSheet;
 
 /*
  * nsIStyleSheetService allows extensions or embeddors to add to the
  * built-in list of user or agent style sheets.
  */
 
-[scriptable, uuid(1f42a6a2-ab0a-45d4-8a96-396f58ea6c6d)]
+[scriptable, uuid(4de68896-e8eb-41de-8237-a797b570ac4a)]
 interface nsIStyleSheetService : nsISupports
 {
   const unsigned long AGENT_SHEET = 0;
   const unsigned long USER_SHEET = 1;
   const unsigned long AUTHOR_SHEET = 2;
 
   /**
    * Synchronously loads a style sheet from |sheetURI| and adds it to the list
@@ -42,14 +43,20 @@ interface nsIStyleSheetService : nsISupp
 
   /**
    * Returns true if a style sheet at |sheetURI| has previously been
    * added to the list of style sheets specified by |type|.
    */
   boolean sheetRegistered(in nsIURI sheetURI, in unsigned long type);
 
   /**
+   * Synchronously loads a style sheet from |sheetURI| and returns the
+   * new style sheet object. Can be used with nsIDOMWindowUtils.addSheet.
+   */
+  nsIDOMStyleSheet preloadSheet(in nsIURI sheetURI, in unsigned long type);
+
+  /**
    * Remove the style sheet at |sheetURI| from the list of style sheets
    * specified by |type|.  The removal takes effect immediately, even for
    * already-loaded documents.
    */
   void unregisterSheet(in nsIURI sheetURI, in unsigned long type);
 };
--- a/layout/base/nsStyleSheetService.cpp
+++ b/layout/base/nsStyleSheetService.cpp
@@ -210,16 +210,37 @@ nsStyleSheetService::SheetRegistered(nsI
   NS_PRECONDITION(_retval, "Null out param");
 
   *_retval = (FindSheetByURI(mSheets[aSheetType], sheetURI) >= 0);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsStyleSheetService::PreloadSheet(nsIURI *aSheetURI, uint32_t aSheetType,
+                                  nsIDOMStyleSheet **aSheet)
+{
+  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
+                aSheetType == USER_SHEET ||
+                aSheetType == AUTHOR_SHEET);
+  NS_ENSURE_ARG_POINTER(aSheetURI);
+  NS_PRECONDITION(aSheet, "Null out param");
+
+  nsRefPtr<css::Loader> loader = new css::Loader();
+
+  // Allow UA sheets, but not user sheets, to use unsafe rules
+  nsRefPtr<CSSStyleSheet> sheet;
+  nsresult rv = loader->LoadSheetSync(aSheetURI, aSheetType == AGENT_SHEET,
+                                      true, getter_AddRefs(sheet));
+  NS_ENSURE_SUCCESS(rv, rv);
+  sheet.forget(aSheet);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsStyleSheetService::UnregisterSheet(nsIURI *aSheetURI, uint32_t aSheetType)
 {
   NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
                 aSheetType == USER_SHEET ||
                 aSheetType == AUTHOR_SHEET);
   NS_ENSURE_ARG_POINTER(aSheetURI);
 
   int32_t foundIndex = FindSheetByURI(mSheets[aSheetType], aSheetURI);
--- a/layout/base/nsStyleSheetService.h
+++ b/layout/base/nsStyleSheetService.h
@@ -58,14 +58,14 @@ class nsStyleSheetService MOZ_FINAL
                                           uint32_t             aSheetType);
 
   int32_t FindSheetByURI(const nsCOMArray<nsIStyleSheet> &sheets,
                                      nsIURI *sheetURI);
 
   // Like LoadAndRegisterSheet, but doesn't notify.  If successful, the
   // new sheet will be the last sheet in mSheets[aSheetType].
   nsresult LoadAndRegisterSheetInternal(nsIURI *aSheetURI,
-                                                    uint32_t aSheetType);
+                                        uint32_t aSheetType);
 
   nsCOMArray<nsIStyleSheet> mSheets[3];
 };
 
 #endif