Bug 676054 - part2: Provide AUTHOR_SHEET type for registering with nsIStyleSheetService. r=bz
authorGabor Krizsanits <gkrizsanits@mozilla.com>
Tue, 16 Oct 2012 21:45:50 +0200
changeset 110461 0ab2a9c94c911a07bb6333da4ec0503a579284f5
parent 110460 e5386e4e6f541c85b59a57c569102732ee0ce43f
child 110462 8c10557ef1b5078ce3af6d64b6157036a686d6ef
push idunknown
push userunknown
push dateunknown
reviewersbz
bugs676054
milestone19.0a1
Bug 676054 - part2: Provide AUTHOR_SHEET type for registering with nsIStyleSheetService. r=bz
content/base/src/Makefile.in
content/base/src/nsDocument.cpp
layout/base/nsIStyleSheetService.idl
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/base/nsStyleSheetService.cpp
layout/base/nsStyleSheetService.h
layout/style/nsStyleSet.cpp
layout/style/test/chrome/test_additional_sheets.html
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -182,16 +182,17 @@ LOCAL_INCLUDES += \
   -I$(topsrcdir)/content/xml/content/src \
   -I$(topsrcdir)/content/xml/document/src \
   -I$(topsrcdir)/content/xul/content/src \
   -I$(topsrcdir)/content/xul/document/src \
   -I$(topsrcdir)/dom/base \
   -I$(topsrcdir)/dom/ipc \
   -I$(topsrcdir)/image/src \
   -I$(topsrcdir)/js/xpconnect/src \
+  -I$(topsrcdir)/layout/base \
   -I$(topsrcdir)/layout/generic \
   -I$(topsrcdir)/layout/style \
   -I$(topsrcdir)/layout/svg \
   -I$(topsrcdir)/layout/xul/base/src \
   -I$(topsrcdir)/netwerk/base/src \
   $(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -67,16 +67,17 @@
 #include "nsIJSON.h"
 #include "nsThreadUtils.h"
 #include "nsNodeInfoManager.h"
 #include "nsIFileChannel.h"
 #include "nsIMultiPartChannel.h"
 #include "nsIRefreshURI.h"
 #include "nsIWebNavigation.h"
 #include "nsIScriptError.h"
+#include "nsStyleSheetService.h"
 
 #include "nsNetUtil.h"     // for NS_MakeAbsoluteURI
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIPrincipal.h"
 
 #include "nsIDOMWindow.h"
 #include "nsPIDOMWindow.h"
@@ -2313,42 +2314,61 @@ nsDocument::ResetStylesheetsToURI(nsIURI
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (shell) {
     FillStyleSet(shell->StyleSet());
   }
 
   return NS_OK;
 }
 
+static bool
+AppendAuthorSheet(nsIStyleSheet *aSheet, void *aData)
+{
+  nsStyleSet *styleSet = static_cast<nsStyleSet*>(aData);
+  styleSet->AppendStyleSheet(nsStyleSet::eDocSheet, aSheet);
+  return true;
+}
+
 void
 nsDocument::FillStyleSet(nsStyleSet* aStyleSet)
 {
   NS_PRECONDITION(aStyleSet, "Must have a style set");
   NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::ePresHintSheet) == 0,
                   "Style set already has a preshint sheet?");
   NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eDocSheet) == 0,
                   "Style set already has document sheets?");
   NS_PRECONDITION(aStyleSet->SheetCount(nsStyleSet::eStyleAttrSheet) == 0,
                   "Style set already has style attr sheets?");
   NS_PRECONDITION(mStyleAttrStyleSheet, "No style attr stylesheet?");
   NS_PRECONDITION(mAttrStyleSheet, "No attr stylesheet?");
 
+  nsCOMPtr<nsIStyleSheetService> dummy =
+    do_GetService(NS_STYLESHEETSERVICE_CONTRACTID);
+
+  nsStyleSheetService *sheetService = nsStyleSheetService::gInstance;
+
+
   aStyleSet->AppendStyleSheet(nsStyleSet::ePresHintSheet, mAttrStyleSheet);
 
   aStyleSet->AppendStyleSheet(nsStyleSet::eStyleAttrSheet,
                               mStyleAttrStyleSheet);
 
   int32_t i;
   for (i = mStyleSheets.Count() - 1; i >= 0; --i) {
     nsIStyleSheet* sheet = mStyleSheets[i];
     if (sheet->IsApplicable()) {
       aStyleSet->AddDocStyleSheet(sheet, this);
     }
   }
 
+  if (sheetService) {
+    sheetService->AuthorStyleSheets()->EnumerateForwards(AppendAuthorSheet,
+                                                         aStyleSet);
+  }
+
   for (i = mCatalogSheets.Count() - 1; i >= 0; --i) {
     nsIStyleSheet* sheet = mCatalogSheets[i];
     if (sheet->IsApplicable()) {
       aStyleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet);
     }
   }
 
   for (int32_t i = mAdditionalSheets[eAgentSheet].Count() - 1; i >= 0; --i) {
--- a/layout/base/nsIStyleSheetService.idl
+++ b/layout/base/nsIStyleSheetService.idl
@@ -14,16 +14,17 @@ interface nsIURI;
  * built-in list of user or agent style sheets.
  */
 
 [scriptable, uuid(1f42a6a2-ab0a-45d4-8a96-396f58ea6c6d)]
 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
    * of user or agent style sheets.
    *
    * A user sheet loaded via this API will come before userContent.css and
    * userChrome.css in the cascade (so the rules in it will have lower
    * precedence than rules in those sheets).
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -875,18 +875,20 @@ PresShell::Init(nsIDocument* aDocument,
       Preferences::GetInt("layout.reflow.timeslice", NS_MAX_REFLOW_TIME);
   }
 
   {
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     if (os) {
       os->AddObserver(this, "agent-sheet-added", false);
       os->AddObserver(this, "user-sheet-added", false);
+      os->AddObserver(this, "author-sheet-added", false);
       os->AddObserver(this, "agent-sheet-removed", false);
       os->AddObserver(this, "user-sheet-removed", false);
+      os->AddObserver(this, "author-sheet-removed", false);
 #ifdef MOZ_XUL
       os->AddObserver(this, "chrome-flush-skin-caches", false);
 #endif
     }
   }
 
 #ifdef MOZ_REFLOW_PERF
     if (mReflowCountMgr) {
@@ -965,18 +967,20 @@ PresShell::Destroy()
     mPresContext->EventStateManager()->NotifyDestroyPresContext(mPresContext);
   }
 
   {
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     if (os) {
       os->RemoveObserver(this, "agent-sheet-added");
       os->RemoveObserver(this, "user-sheet-added");
+      os->RemoveObserver(this, "author-sheet-added");
       os->RemoveObserver(this, "agent-sheet-removed");
       os->RemoveObserver(this, "user-sheet-removed");
+      os->RemoveObserver(this, "author-sheet-removed");
 #ifdef MOZ_XUL
       os->RemoveObserver(this, "chrome-flush-skin-caches");
 #endif
     }
   }
 
   // If our paint suppression timer is still active, kill it.
   if (mPaintSuppressionTimer) {
@@ -1506,16 +1510,28 @@ PresShell::AddAgentSheet(nsISupports* aS
     return;
   }
 
   mStyleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, sheet);
   ReconstructStyleData();
 }
 
 void
+PresShell::AddAuthorSheet(nsISupports* aSheet)
+{
+  nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
+  if (!sheet) {
+    return;
+  }
+
+  mStyleSet->AppendStyleSheet(nsStyleSet::eDocSheet, sheet);
+  ReconstructStyleData();
+}
+
+void
 PresShell::RemoveSheet(nsStyleSet::sheetType aType, nsISupports* aSheet)
 {
   nsCOMPtr<nsIStyleSheet> sheet = do_QueryInterface(aSheet);
   if (!sheet) {
     return;
   }
 
   mStyleSet->RemoveStyleSheet(aType, sheet);
@@ -7747,26 +7763,36 @@ PresShell::Observe(nsISupports* aSubject
     return NS_OK;
   }
 
   if (!nsCRT::strcmp(aTopic, "user-sheet-added") && mStyleSet) {
     AddUserSheet(aSubject);
     return NS_OK;
   }
 
+  if (!nsCRT::strcmp(aTopic, "author-sheet-added") && mStyleSet) {
+    AddAuthorSheet(aSubject);
+    return NS_OK;
+  }
+
   if (!nsCRT::strcmp(aTopic, "agent-sheet-removed") && mStyleSet) {
     RemoveSheet(nsStyleSet::eAgentSheet, aSubject);
     return NS_OK;
   }
 
   if (!nsCRT::strcmp(aTopic, "user-sheet-removed") && mStyleSet) {
     RemoveSheet(nsStyleSet::eUserSheet, aSubject);
     return NS_OK;
   }
 
+  if (!nsCRT::strcmp(aTopic, "author-sheet-removed") && mStyleSet) {
+    RemoveSheet(nsStyleSet::eDocSheet, aSubject);
+    return NS_OK;
+  }
+
   NS_WARNING("unrecognized topic in PresShell::Observe");
   return NS_ERROR_FAILURE;
 }
 
 bool
 nsIPresShell::AddRefreshObserverInternal(nsARefreshObserver* aObserver,
                                          mozFlushType aFlushType)
 {
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -484,16 +484,17 @@ protected:
                       nsIntRect* aScreenRect);
 
   /**
    * Methods to handle changes to user and UA sheet lists that we get
    * notified about.
    */
   void AddUserSheet(nsISupports* aSheet);
   void AddAgentSheet(nsISupports* aSheet);
+  void AddAuthorSheet(nsISupports* aSheet);
   void RemoveSheet(nsStyleSet::sheetType aType, nsISupports* aSheet);
 
   // Hide a view if it is a popup
   void HideViewIfPopup(nsIView* aView);
 
   // Utility method to restore the root scrollframe state
   void RestoreRootScrollPosition();
 
--- a/layout/base/nsStyleSheetService.cpp
+++ b/layout/base/nsStyleSheetService.cpp
@@ -37,17 +37,17 @@ NS_MEMORY_REPORTER_IMPLEMENT(StyleSheetS
   nsIMemoryReporter::UNITS_BYTES,
   GetStyleSheetServiceSize,
   "Memory used for style sheets held by the style sheet service.")
 
 nsStyleSheetService *nsStyleSheetService::gInstance = nullptr;
 
 nsStyleSheetService::nsStyleSheetService()
 {
-  PR_STATIC_ASSERT(0 == AGENT_SHEET && 1 == USER_SHEET);
+  PR_STATIC_ASSERT(0 == AGENT_SHEET && 1 == USER_SHEET && 2 == AUTHOR_SHEET);
   NS_ASSERTION(!gInstance, "Someone is using CreateInstance instead of GetService");
   gInstance = this;
   nsLayoutStatics::AddRef();
 
   mReporter = new NS_MEMORY_REPORTER_NAME(StyleSheetService);
   (void)::NS_RegisterMemoryReporter(mReporter);
 }
 
@@ -124,44 +124,61 @@ nsStyleSheetService::Init()
 
   nsCOMPtr<nsISimpleEnumerator> sheets;
   catMan->EnumerateCategory("agent-style-sheets", getter_AddRefs(sheets));
   RegisterFromEnumerator(catMan, "agent-style-sheets", sheets, AGENT_SHEET);
 
   catMan->EnumerateCategory("user-style-sheets", getter_AddRefs(sheets));
   RegisterFromEnumerator(catMan, "user-style-sheets", sheets, USER_SHEET);
 
+  catMan->EnumerateCategory("author-style-sheets", getter_AddRefs(sheets));
+  RegisterFromEnumerator(catMan, "author-style-sheets", sheets, AUTHOR_SHEET);
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStyleSheetService::LoadAndRegisterSheet(nsIURI *aSheetURI,
                                           uint32_t aSheetType)
 {
   nsresult rv = LoadAndRegisterSheetInternal(aSheetURI, aSheetType);
   if (NS_SUCCEEDED(rv)) {
-    const char* message = (aSheetType == AGENT_SHEET) ?
-      "agent-sheet-added" : "user-sheet-added";
+    const char* message;
+    switch (aSheetType) {
+      case AGENT_SHEET:
+        message = "agent-sheet-added";
+        break;
+      case USER_SHEET:
+        message = "user-sheet-added";
+        break;
+      case AUTHOR_SHEET:
+        message = "author-sheet-added";
+        break;
+      default:
+        return NS_ERROR_INVALID_ARG;
+    }
     nsCOMPtr<nsIObserverService> serv =
       mozilla::services::GetObserverService();
     if (serv) {
       // We're guaranteed that the new sheet is the last sheet in
       // mSheets[aSheetType]
       const nsCOMArray<nsIStyleSheet> & sheets = mSheets[aSheetType];
       serv->NotifyObservers(sheets[sheets.Count() - 1], message, nullptr);
     }
   }
   return rv;
 }
 
 nsresult
 nsStyleSheetService::LoadAndRegisterSheetInternal(nsIURI *aSheetURI,
                                                   uint32_t aSheetType)
 {
-  NS_ENSURE_ARG(aSheetType == AGENT_SHEET || aSheetType == USER_SHEET);
+  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
+                aSheetType == USER_SHEET ||
+                aSheetType == AUTHOR_SHEET);
   NS_ENSURE_ARG_POINTER(aSheetURI);
 
   nsRefPtr<mozilla::css::Loader> loader = new mozilla::css::Loader();
 
   nsRefPtr<nsCSSStyleSheet> sheet;
   // Allow UA sheets, but not user sheets, to use unsafe rules
   nsresult rv = loader->LoadSheetSync(aSheetURI, aSheetType == AGENT_SHEET,
                                       true, getter_AddRefs(sheet));
@@ -173,38 +190,53 @@ nsStyleSheetService::LoadAndRegisterShee
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsStyleSheetService::SheetRegistered(nsIURI *sheetURI,
                                      uint32_t aSheetType, bool *_retval)
 {
-  NS_ENSURE_ARG(aSheetType == AGENT_SHEET || aSheetType == USER_SHEET);
+  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
+                aSheetType == USER_SHEET ||
+                aSheetType == AUTHOR_SHEET);
   NS_ENSURE_ARG_POINTER(sheetURI);
   NS_PRECONDITION(_retval, "Null out param");
 
   *_retval = (FindSheetByURI(mSheets[aSheetType], sheetURI) >= 0);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsStyleSheetService::UnregisterSheet(nsIURI *sheetURI, uint32_t aSheetType)
 {
-  NS_ENSURE_ARG(aSheetType == AGENT_SHEET || aSheetType == USER_SHEET);
+  NS_ENSURE_ARG(aSheetType == AGENT_SHEET ||
+                aSheetType == USER_SHEET ||
+                aSheetType == AUTHOR_SHEET);
   NS_ENSURE_ARG_POINTER(sheetURI);
 
   int32_t foundIndex = FindSheetByURI(mSheets[aSheetType], sheetURI);
   NS_ENSURE_TRUE(foundIndex >= 0, NS_ERROR_INVALID_ARG);
   nsCOMPtr<nsIStyleSheet> sheet = mSheets[aSheetType][foundIndex];
   mSheets[aSheetType].RemoveObjectAt(foundIndex);
 
-  const char* message = (aSheetType == AGENT_SHEET) ?
-      "agent-sheet-removed" : "user-sheet-removed";
+  const char* message;
+  switch (aSheetType) {
+    case AGENT_SHEET:
+      message = "agent-sheet-removed";
+      break;
+    case USER_SHEET:
+      message = "user-sheet-removed";
+      break;
+    case AUTHOR_SHEET:
+      message = "author-sheet-removed";
+      break;
+  }
+
   nsCOMPtr<nsIObserverService> serv =
     mozilla::services::GetObserverService();
   if (serv)
     serv->NotifyObservers(sheet, message, nullptr);
 
   return NS_OK;
 }
 
@@ -229,12 +261,14 @@ SizeOfElementIncludingThis(nsIStyleSheet
 size_t
 nsStyleSheetService::SizeOfIncludingThisHelper(nsMallocSizeOfFun aMallocSizeOf) const
 {
   size_t n = aMallocSizeOf(this);
   n += mSheets[AGENT_SHEET].SizeOfExcludingThis(SizeOfElementIncludingThis,
                                                 aMallocSizeOf);
   n += mSheets[USER_SHEET].SizeOfExcludingThis(SizeOfElementIncludingThis,
                                                aMallocSizeOf);
+  n += mSheets[AUTHOR_SHEET].SizeOfExcludingThis(SizeOfElementIncludingThis,
+                                                 aMallocSizeOf);
   return n;
 }
 
 
--- a/layout/base/nsStyleSheetService.h
+++ b/layout/base/nsStyleSheetService.h
@@ -32,16 +32,17 @@ class nsStyleSheetService MOZ_FINAL : pu
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTYLESHEETSERVICE
 
   NS_HIDDEN_(nsresult) Init();
 
   nsCOMArray<nsIStyleSheet>* AgentStyleSheets() { return &mSheets[AGENT_SHEET]; }
   nsCOMArray<nsIStyleSheet>* UserStyleSheets() { return &mSheets[USER_SHEET]; }
+  nsCOMArray<nsIStyleSheet>* AuthorStyleSheets() { return &mSheets[AUTHOR_SHEET]; }
 
   static size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf);
 
   static nsStyleSheetService *gInstance;
 
  private:
 
   NS_HIDDEN_(void) RegisterFromEnumerator(nsICategoryManager  *aManager,
@@ -54,14 +55,14 @@ class nsStyleSheetService MOZ_FINAL : pu
 
   // Like LoadAndRegisterSheet, but doesn't notify.  If successful, the
   // new sheet will be the last sheet in mSheets[aSheetType].
   NS_HIDDEN_(nsresult) LoadAndRegisterSheetInternal(nsIURI *aSheetURI,
                                                     uint32_t aSheetType);
 
   size_t SizeOfIncludingThisHelper(nsMallocSizeOfFun aMallocSizeOf) const;
 
-  nsCOMArray<nsIStyleSheet> mSheets[2];
+  nsCOMArray<nsIStyleSheet> mSheets[3];
 
   nsIMemoryReporter* mReporter;
 };
 
 #endif
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -22,16 +22,17 @@
 #include "nsCSSPseudoElements.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsIContent.h"
 #include "nsRuleData.h"
 #include "nsRuleProcessorData.h"
 #include "nsTransitionManager.h"
 #include "nsAnimationManager.h"
 #include "nsEventStates.h"
+#include "nsStyleSheetService.h"
 #include "mozilla/dom/Element.h"
 #include "sampler.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_ISUPPORTS1(nsEmptyStyleRule, nsIStyleRule)
 
@@ -357,25 +358,36 @@ nsStyleSet::AddDocStyleSheet(nsIStyleShe
 {
   NS_PRECONDITION(aSheet && aDocument, "null arg");
   NS_ASSERTION(aSheet->IsApplicable(),
                "Inapplicable sheet being placed in style set");
 
   nsCOMArray<nsIStyleSheet>& docSheets = mSheets[eDocSheet];
 
   docSheets.RemoveObject(aSheet);
+  nsStyleSheetService *sheetService = nsStyleSheetService::gInstance;
+
   // lowest index first
   int32_t newDocIndex = aDocument->GetIndexOfStyleSheet(aSheet);
+
   int32_t count = docSheets.Count();
   int32_t index;
   for (index = 0; index < count; index++) {
     nsIStyleSheet* sheet = docSheets.ObjectAt(index);
     int32_t sheetDocIndex = aDocument->GetIndexOfStyleSheet(sheet);
     if (sheetDocIndex > newDocIndex)
       break;
+
+    // If the sheet is not owned by the document it can be an author
+    // sheet registered at nsStyleSheetService, which means the new 
+    // doc sheet should end up before it.
+    if (sheetDocIndex < 0 &&
+        sheetService &&
+        sheetService->AuthorStyleSheets()->IndexOf(sheet) >= 0)
+        break;
   }
   if (!docSheets.InsertObjectAt(aSheet, index))
     return NS_ERROR_OUT_OF_MEMORY;
   if (!mBatching)
     return GatherRuleProcessors(eDocSheet);
 
   mDirty |= 1 << eDocSheet;
   return NS_OK;
--- a/layout/style/test/chrome/test_additional_sheets.html
+++ b/layout/style/test/chrome/test_additional_sheets.html
@@ -69,26 +69,36 @@ function loadAndRegisterUserSheet(win, s
   loadAndRegisterSheet(win, style, "USER_SHEET");
 }
 
 function loadAndRegisterAgentSheet(win, style)
 {
   loadAndRegisterSheet(win, style, "AGENT_SHEET");
 }
 
+function loadAndRegisterAuthorSheet(win, style)
+{
+  loadAndRegisterSheet(win, style, "AUTHOR_SHEET");
+}
+
 function unregisterUserSheet(win, style)
 {
   unregisterSheet(win, style, "USER_SHEET");
 }
 
 function unregisterAgentSheet(win, style)
 {
   unregisterSheet(win, style, "AGENT_SHEET");
 }
 
+function unregisterAuthorSheet(win, style)
+{
+  unregisterSheet(win, style, "AUTHOR_SHEET");
+}
+
 function loadAndRegisterSheet(win, style, type)
 {
   var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]
     .getService(Components.interfaces.nsIStyleSheetService);
   var ios = Components.classes["@mozilla.org/network/io-service;1"]
     .getService(Components.interfaces.nsIIOService);
   uri = ios.newURI(getUri(style), null, null);
   sss.loadAndRegisterSheet(uri, sss[type]);
@@ -154,16 +164,23 @@ var additionalUser = {
 
 var author = {
   type: 'author',
   color: 'rgb(0, 255, 255)',
   addRules: setDocSheet,
   removeRules: removeDocSheet
 };
 
+var authorFromManager = {
+  type: 'authorFromManager',
+  color: 'rgb(255, 0, 255)',
+  addRules: loadAndRegisterAuthorSheet,
+  removeRules: unregisterAuthorSheet
+};
+
 function loadAndCheck(win, firstType, secondType, swap, result1, result2)
 {
   var firstStyle = getStyle(firstType.color, false);
   var secondStyle = getStyle(secondType.color, swap);
 
   firstType.addRules(win, firstStyle);
   secondType.addRules(win, secondStyle);
 
@@ -235,16 +252,25 @@ function run()
 
   testStyleVsStyle(win, additionalAgent, author,
                    {AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
 
 
   testStyleVsStyle(win, additionalAgent, additionalUser,
                    {AB:{rr:1, ii:0, ri:1, ir:0}, BA:{rr:1, ii:0, ri:1, ir:0}});
 
+  testStyleVsStyle(win, authorFromManager, author,
+                   {AB:{rr:0, ii:0, ri:1, ir:0}, BA:{rr:0, ii:0, ri:1, ir:0}});
+
+  testStyleVsStyle(win, authorFromManager, user,
+                   {AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
+
+  testStyleVsStyle(win, authorFromManager, additionalUser,
+                   {AB:{rr:0, ii:1, ri:1, ir:0}, BA:{rr:0, ii:1, ri:1, ir:0}});
+
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </pre>