From 82d9392c4fa965042648d1e9da71bbd891deb1f2 Mon Sep 17 00:00:00 2001 From: "bryner%brianryner.com" Date: Sat, 15 Jan 2005 00:10:19 +0000 Subject: [PATCH] Add a mechansim to extend the list of agent or user stylesheets. Bug 179006, r+sr=bzbarsky. git-svn-id: svn://10.0.0.236/trunk@167752 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/Makefile.in | 2 + mozilla/layout/base/nsDocumentViewer.cpp | 28 ++++ mozilla/layout/base/nsIStyleSheetService.idl | 59 ++++++++ mozilla/layout/base/nsStyleSheetService.cpp | 140 +++++++++++++++++++ mozilla/layout/base/nsStyleSheetService.h | 82 +++++++++++ mozilla/layout/build/nsLayoutModule.cpp | 10 +- 6 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 mozilla/layout/base/nsIStyleSheetService.idl create mode 100644 mozilla/layout/base/nsStyleSheetService.cpp create mode 100644 mozilla/layout/base/nsStyleSheetService.h diff --git a/mozilla/layout/base/Makefile.in b/mozilla/layout/base/Makefile.in index 9190eb8c0ea..43cd8afaadf 100644 --- a/mozilla/layout/base/Makefile.in +++ b/mozilla/layout/base/Makefile.in @@ -79,6 +79,7 @@ REQUIRES = xpcom \ XPIDLSRCS = \ nsIChromeEventHandler.idl \ nsISelectionImageService.idl \ + nsIStyleSheetService.idl \ $(NULL) EXPORTS = \ @@ -134,6 +135,7 @@ CPPSRCS = \ nsPresState.cpp \ nsQuoteList.cpp \ nsStyleChangeList.cpp \ + nsStyleSheetService.cpp \ $(NULL) ifdef IBMBIDI diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index 49f2687da61..48fd86de235 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -124,6 +124,7 @@ #include "nsIHTMLDocument.h" #include "nsITimelineService.h" #include "nsGfxCIID.h" +#include "nsStyleSheetService.h" // Printing #include "nsIWebBrowserPrint.h" @@ -1714,6 +1715,22 @@ DocumentViewerImpl::ForceRefresh() NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID); +PR_STATIC_CALLBACK(PRBool) +AppendAgentSheet(nsIStyleSheet *aSheet, void *aData) +{ + nsStyleSet *styleSet = NS_STATIC_CAST(nsStyleSet*, aData); + styleSet->AppendStyleSheet(nsStyleSet::eAgentSheet, aSheet); + return PR_TRUE; +} + +PR_STATIC_CALLBACK(PRBool) +AppendUserSheet(nsIStyleSheet *aSheet, void *aData) +{ + nsStyleSet *styleSet = NS_STATIC_CAST(nsStyleSet*, aData); + styleSet->AppendStyleSheet(nsStyleSet::eUserSheet, aSheet); + return PR_TRUE; +} + nsresult DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, nsStyleSet** aStyleSet) @@ -1801,6 +1818,17 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument, styleSet->PrependStyleSheet(nsStyleSet::eAgentSheet, mUAStyleSheet); } + nsCOMPtr dummy = + do_GetService(NS_STYLESHEETSERVICE_CONTRACTID); + + nsStyleSheetService *sheetService = nsStyleSheetService::gInstance; + if (sheetService) { + sheetService->AgentStyleSheets()->EnumerateForwards(AppendAgentSheet, + styleSet); + sheetService->UserStyleSheets()->EnumerateForwards(AppendUserSheet, + styleSet); + } + // Caller will handle calling EndUpdate, per contract. *aStyleSet = styleSet; return NS_OK; diff --git a/mozilla/layout/base/nsIStyleSheetService.idl b/mozilla/layout/base/nsIStyleSheetService.idl new file mode 100644 index 00000000000..637dba68816 --- /dev/null +++ b/mozilla/layout/base/nsIStyleSheetService.idl @@ -0,0 +1,59 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** 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. + * + * The Initial Developer of the Original Code is + * IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brian Ryner + * + * Alternatively, the contents of this file may be used under the terms of + * either 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 ***** */ + +#include "nsISupports.idl" + +interface nsIURI; + +/* + * nsIStyleSheetService allows extensions or embeddors to add to the + * built-in list of user or agent style sheets. + */ + +[scriptable, uuid(c0f35b2d-de8f-4dab-9538-ff079bda74dc)] +interface nsIStyleSheetService : nsISupports +{ + const unsigned long AGENT_SHEET = 0; + const unsigned long USER_SHEET = 1; + + /** + * Synchrnously loads a style sheet from |sheetURI| and adds it to the list + * of user or agent style sheets. + */ + void loadAndRegisterSheet(in nsIURI sheetURI, in unsigned long type); +}; diff --git a/mozilla/layout/base/nsStyleSheetService.cpp b/mozilla/layout/base/nsStyleSheetService.cpp new file mode 100644 index 00000000000..8e0c1fb80c3 --- /dev/null +++ b/mozilla/layout/base/nsStyleSheetService.cpp @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** 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. + * + * The Initial Developer of the Original Code is + * IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brian Ryner + * + * Alternatively, the contents of this file may be used under the terms of + * either 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 ***** */ + +#include "nsStyleSheetService.h" +#include "nsICSSLoader.h" +#include "nsICSSStyleSheet.h" +#include "nsContentCID.h" +#include "nsCOMPtr.h" +#include "nsIServiceManager.h" +#include "nsICategoryManager.h" +#include "nsISupportsPrimitives.h" +#include "nsNetUtil.h" + +static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID); + +nsStyleSheetService *nsStyleSheetService::gInstance = nsnull; + +nsStyleSheetService::nsStyleSheetService() +{ + NS_ASSERTION(!gInstance, "Someone is using CreateInstance instead of GetService"); + gInstance = this; +} + +nsStyleSheetService::~nsStyleSheetService() +{ + gInstance = nsnull; +} + +NS_IMPL_ISUPPORTS1(nsStyleSheetService, nsIStyleSheetService) + +void +nsStyleSheetService::RegisterFromEnumerator(nsICategoryManager *aManager, + const char *aCategory, + nsISimpleEnumerator *aEnumerator, + PRUint32 aSheetType) +{ + if (!aEnumerator) + return; + + PRBool hasMore; + while (NS_SUCCEEDED(aEnumerator->HasMoreElements(&hasMore)) && hasMore) { + nsCOMPtr element; + if (NS_FAILED(aEnumerator->GetNext(getter_AddRefs(element)))) + break; + + nsCOMPtr icStr = do_QueryInterface(element); + NS_ASSERTION(icStr, + "category manager entries must be nsISupportsCStrings"); + + nsCAutoString name; + icStr->GetData(name); + + nsXPIDLCString spec; + aManager->GetCategoryEntry(aCategory, name.get(), getter_Copies(spec)); + + nsCOMPtr uri; + NS_NewURI(getter_AddRefs(uri), spec); + if (uri) + LoadAndRegisterSheet(uri, aSheetType); + } +} + +nsresult +nsStyleSheetService::Init() +{ + // Enumerate all of the style sheet URIs registered in the category + // manager and load them. + + nsCOMPtr catMan = + do_GetService(NS_CATEGORYMANAGER_CONTRACTID); + + NS_ENSURE_TRUE(catMan, NS_ERROR_OUT_OF_MEMORY); + + nsCOMPtr 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); + + return NS_OK; +} + +NS_IMETHODIMP +nsStyleSheetService::LoadAndRegisterSheet(nsIURI *aSheetURI, + PRUint32 aSheetType) +{ + nsCOMPtr loader = do_CreateInstance(kCSSLoaderCID); + nsCOMPtr sheet; + nsresult rv = loader->LoadAgentSheet(aSheetURI, getter_AddRefs(sheet)); + NS_ENSURE_SUCCESS(rv, rv); + + switch (aSheetType) { + case AGENT_SHEET: + mAgentSheets.AppendObject(sheet); + break; + case USER_SHEET: + mUserSheets.AppendObject(sheet); + break; + default: + NS_ERROR("Unknown sheet type"); + } + + return NS_OK; +} diff --git a/mozilla/layout/base/nsStyleSheetService.h b/mozilla/layout/base/nsStyleSheetService.h new file mode 100644 index 00000000000..6d8122bc2c6 --- /dev/null +++ b/mozilla/layout/base/nsStyleSheetService.h @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** 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. + * + * The Initial Developer of the Original Code is + * IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brian Ryner + * + * Alternatively, the contents of this file may be used under the terms of + * either 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 ***** */ + +#ifndef nsStyleSheetService_h_ +#define nsStyleSheetService_h_ + +#include "nsIStyleSheetService.h" +#include "nsCOMArray.h" +#include "nsIStyleSheet.h" + +class nsISimpleEnumerator; +class nsICategoryManager; + +#define NS_STYLESHEETSERVICE_CID \ +{0xfcca6f83, 0x9f7d, 0x44e4, {0xa7, 0x4b, 0xb5, 0x94, 0x33, 0xe6, 0xc8, 0xc3}} + +#define NS_STYLESHEETSERVICE_CONTRACTID \ + "@mozilla.org/content/style-sheet-service;1" + +class nsStyleSheetService : public nsIStyleSheetService +{ + public: + nsStyleSheetService() NS_HIDDEN; + ~nsStyleSheetService() NS_HIDDEN; + + NS_DECL_ISUPPORTS + NS_DECL_NSISTYLESHEETSERVICE + + NS_HIDDEN_(nsresult) Init(); + + nsCOMArray* AgentStyleSheets() { return &mAgentSheets; } + nsCOMArray* UserStyleSheets() { return &mUserSheets; } + + static nsStyleSheetService *gInstance; + + private: + + NS_HIDDEN_(void) RegisterFromEnumerator(nsICategoryManager *aManager, + const char *aCategory, + nsISimpleEnumerator *aEnumerator, + PRUint32 aSheetType); + + nsCOMArray mAgentSheets; + nsCOMArray mUserSheets; +}; + +#endif diff --git a/mozilla/layout/build/nsLayoutModule.cpp b/mozilla/layout/build/nsLayoutModule.cpp index 02196ee77d9..d3bbb0a7895 100644 --- a/mozilla/layout/build/nsLayoutModule.cpp +++ b/mozilla/layout/build/nsLayoutModule.cpp @@ -129,6 +129,7 @@ #include "nsImageFrame.h" #include "nsILanguageAtomService.h" #include "nsTextControlFrame.h" +#include "nsStyleSheetService.h" // view stuff #include "nsViewsCID.h" @@ -609,6 +610,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsContentAreaDragDrop) MAKE_CTOR(CreateSyncLoadDOMService, nsISyncLoadDOMService, NS_NewSyncLoadDOMService) MAKE_CTOR(CreatePluginDocument, nsIDocument, NS_NewPluginDocument) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStyleSheetService, Init) + // views are not refcounted, so this is the same as // NS_GENERIC_FACTORY_CONSTRUCTOR without the NS_ADDREF/NS_RELEASE #define NS_GENERIC_FACTORY_CONSTRUCTOR_NOREFS(_InstanceClass) \ @@ -1310,7 +1313,12 @@ static const nsModuleComponentInfo gComponents[] = { { "Plugin Document", NS_PLUGINDOCUMENT_CID, nsnull, - CreatePluginDocument } + CreatePluginDocument }, + + { "Style sheet service", + NS_STYLESHEETSERVICE_CID, + NS_STYLESHEETSERVICE_CONTRACTID, + nsStyleSheetServiceConstructor } }; NS_IMPL_NSGETMODULE_WITH_CTOR(nsLayoutModule, gComponents, Initialize)