Remove nsINameSpace and replace with a simple array-based list of namespace mappings for CSS. Bug 281728, r+sr=bzbarsky.

This commit is contained in:
bryner%brianryner.com 2005-02-18 19:18:37 +00:00
parent 48a9ab5e12
commit 58396e7490
12 changed files with 369 additions and 358 deletions

View File

@ -56,7 +56,7 @@ nsContentUtils.h \
nsIDocument.h \
nsIDocumentEncoder.h \
nsIDocumentObserver.h \
nsINameSpace.h \
nsNameSpaceMap.h \
nsINameSpaceManager.h \
nsINodeInfo.h \
nsIRangeUtils.h \

View File

@ -1,78 +0,0 @@
/* -*- 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 Communicator client 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 ***** */
#ifndef nsINameSpace_h___
#define nsINameSpace_h___
#include "nsISupports.h"
class nsIAtom;
#define NS_INAMESPACE_IID \
{ 0x72022492, 0x0fdf, 0x11d9, \
{ 0xa3, 0x76, 0x00, 0x0a, 0x95, 0xdc, 0x23, 0x4c } }
/**
* A nsINameSpace registers the NameSpace URI with the NameSpaceManager
* (creating or finding an ID), and manages the relationship between
* the NameSpace ID and the (optional) Prefix.
*
* New NameSpaces are created as a child of an existing NameSpace. Searches
* for NameSpaces based on prefix search up the chain of nested NameSpaces
*
* Each NameSpace keeps a live reference on its parent.
*
*/
class nsINameSpace : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_INAMESPACE_IID)
// Get data of this name space
NS_IMETHOD GetNameSpaceID(PRInt32* aID) const = 0;
// Find name space within self and parents (not children)
NS_IMETHOD FindNameSpace(nsIAtom* aPrefix, nsINameSpace** aNameSpace) const = 0;
NS_IMETHOD FindNameSpaceID(nsIAtom* aPrefix, PRInt32* aNameSpaceID) const = 0;
NS_IMETHOD FindNameSpacePrefix(PRInt32 aNameSpaceID, nsIAtom** aPrefix) const = 0;
// Create new child name space
NS_IMETHOD CreateChildNameSpace(nsIAtom* aPrefix,
const nsAString& aURI,
nsINameSpace** aChildNameSpace) = 0;
};
#endif // nsINameSpace_h___

View File

@ -43,7 +43,6 @@
class nsIAtom;
class nsString;
class nsINameSpace;
#define kNameSpaceID_Unknown -1
// 0 is special at C++, so use a static const PRInt32 for
@ -68,8 +67,8 @@ static const PRInt32 kNameSpaceID_None = 0;
#define NS_NAMESPACEMANAGER_CONTRACTID "@mozilla.org/content/namespacemanager;1"
#define NS_INAMESPACEMANAGER_IID \
{ 0x409cd4de, 0xb3ca, 0x11d8, \
{ 0xb2, 0x67, 0x00, 0x0a, 0x95, 0xdc, 0x23, 0x4c } }
{ 0x30977ca5, 0xc6af, 0x4687, \
{ 0x88, 0x43, 0xa9, 0x7d, 0x0f, 0x95, 0x00, 0x17 } }
/**
* The Name Space Manager tracks the associtation between a NameSpace
@ -83,9 +82,6 @@ static const PRInt32 kNameSpaceID_None = 0;
* The nsINameSpaceManager needs to have a live reference for as long as
* the NameSpace IDs are needed.
*
* To create a stack of NameSpaces, call CreateRootNameSpace, and then create
* child NameSpaces from the root.
*
*/
class nsINameSpaceManager : public nsISupports
@ -93,8 +89,6 @@ class nsINameSpaceManager : public nsISupports
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_INAMESPACEMANAGER_IID)
NS_IMETHOD CreateRootNameSpace(nsINameSpace** aRootNameSpace) = 0;
NS_IMETHOD RegisterNameSpace(const nsAString& aURI,
PRInt32& aNameSpaceID) = 0;

View File

@ -0,0 +1,100 @@
/* -*- 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 Communicator client code.
*
* 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 <bryner@brianryner.com>
*
* 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 ***** */
#ifndef nsNameSpaceMap_h_
#define nsNameSpaceMap_h_
#include "nsVoidArray.h"
class nsIAtom;
/**
* nsNameSpaceMap contains a set of prefixes which are mapped onto namespaces.
* It allows the set to be searched by prefix or by namespace ID.
*/
class nsNameSpaceMap
{
public:
/**
* Allocates a new nsNameSpaceMap (with new()) and initializes it with the
* xmlns and xml namespaces.
*/
static NS_HIDDEN_(nsNameSpaceMap*) Create();
/**
* Add a prefix and its corresponding namespace ID to the map.
* Passing a null |aPrefix| corresponds to the default namespace, which may
* be set to something other than kNameSpaceID_None.
*/
NS_HIDDEN_(nsresult) AddPrefix(nsIAtom *aPrefix, PRInt32 aNameSpaceID);
/**
* Add a prefix and a namespace URI to the map. The URI will be converted
* to its corresponding namespace ID.
*/
NS_HIDDEN_(nsresult) AddPrefix(nsIAtom *aPrefix, nsString &aURI);
/* Remove a prefix from the map. */
NS_HIDDEN_(void) RemovePrefix(nsIAtom *aPrefix);
/*
* Returns the namespace ID for the given prefix, if it is in the map.
* If |aPrefix| is null and is not in the map, then a null namespace
* (kNameSpaceID_None) is returned. If |aPrefix| is non-null and is not in
* the map, then kNameSpaceID_Unknown is returned.
*/
NS_HIDDEN_(PRInt32) FindNameSpaceID(nsIAtom *aPrefix) const;
/**
* If the given namespace ID is in the map, then the first prefix which
* maps to that namespace is returned. Otherwise, null is returned.
*/
NS_HIDDEN_(nsIAtom*) FindPrefix(PRInt32 aNameSpaceID) const;
/* Removes all prefix mappings. */
NS_HIDDEN_(void) Clear();
~nsNameSpaceMap() { Clear(); }
private:
nsNameSpaceMap() NS_HIDDEN; // use Create() to create new instances
nsVoidArray mNameSpaces;
};
#endif

View File

@ -111,6 +111,7 @@ CPPSRCS = \
nsImageLoadingContent.cpp \
nsMappedAttributes.cpp \
nsNameSpaceManager.cpp \
nsNameSpaceMap.cpp \
nsNodeInfo.cpp \
nsNodeInfoManager.cpp \
nsParserUtils.cpp \

View File

@ -36,7 +36,6 @@
* ***** END LICENSE BLOCK ***** */
#include "nscore.h"
#include "nsINameSpaceManager.h"
#include "nsINameSpace.h"
#include "nsAutoPtr.h"
#include "nsINodeInfo.h"
#include "nsCOMArray.h"
@ -67,37 +66,6 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#define kRolesWAIUnofficialNameSpaceURI "http://www.w3.org/2005/01/wai-rdf/GUIRoleTaxonomy#" // Will eventually change
#define kStatesWAIUnofficialNameSpaceURI "http://www.w3.org/2005/01/wai-rdf/GUIStateTaxonomy#" // Will eventually change
//-----------------------------------------------------------
// Name Space
class NameSpaceImpl : public nsINameSpace {
public:
NameSpaceImpl(NameSpaceImpl* aParent,
nsIAtom* aPrefix,
PRInt32 aNameSpaceID);
virtual ~NameSpaceImpl();
NS_DECL_ISUPPORTS
NS_IMETHOD GetNameSpaceID(PRInt32* aID) const;
NS_IMETHOD FindNameSpace(nsIAtom* aPrefix, nsINameSpace** aNameSpace) const;
NS_IMETHOD FindNameSpaceID(nsIAtom* aPrefix, PRInt32* aNameSpaceID) const;
NS_IMETHOD FindNameSpacePrefix(PRInt32 aNameSpaceID, nsIAtom** aPrefix) const;
NS_IMETHOD CreateChildNameSpace(nsIAtom* aPrefix, const nsAString& aURI,
nsINameSpace** aChildNameSpace);
private:
// These are not supported and are not implemented!
NameSpaceImpl(const NameSpaceImpl& aCopy);
NameSpaceImpl& operator=(const NameSpaceImpl& aCopy);
nsRefPtr<NameSpaceImpl> mParent;
nsCOMPtr<nsIAtom> mPrefix;
PRInt32 mID;
};
class nsNameSpaceEntry : public PLDHashEntryHdr
{
public:
@ -151,8 +119,6 @@ public:
nsresult Init();
NS_IMETHOD CreateRootNameSpace(nsINameSpace** aRootNameSpace);
NS_IMETHOD RegisterNameSpace(const nsAString& aURI,
PRInt32& aNameSpaceID);
@ -178,113 +144,6 @@ private:
static NameSpaceManagerImpl* gNameSpaceManager = nsnull;
NameSpaceImpl::NameSpaceImpl(NameSpaceImpl* aParent,
nsIAtom* aPrefix,
PRInt32 aNameSpaceID)
: mParent(aParent),
mPrefix(aPrefix),
mID(aNameSpaceID)
{
}
NameSpaceImpl::~NameSpaceImpl()
{
}
NS_IMPL_ISUPPORTS1(NameSpaceImpl, nsINameSpace)
NS_IMETHODIMP
NameSpaceImpl::GetNameSpaceID(PRInt32* aID) const
{
*aID = mID;
return NS_OK;
}
NS_IMETHODIMP
NameSpaceImpl::FindNameSpace(nsIAtom* aPrefix, nsINameSpace** aNameSpace) const
{
const NameSpaceImpl* nameSpace = this;
do {
if (aPrefix == nameSpace->mPrefix) {
*aNameSpace = (nsINameSpace*)nameSpace;
NS_ADDREF(*aNameSpace);
return NS_OK;
}
nameSpace = nameSpace->mParent;
} while (nameSpace);
*aNameSpace = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceImpl::FindNameSpaceID(nsIAtom* aPrefix, PRInt32* aNameSpaceID) const
{
const NameSpaceImpl* nameSpace = this;
do {
if (aPrefix == nameSpace->mPrefix) {
*aNameSpaceID = nameSpace->mID;
return NS_OK;
}
nameSpace = nameSpace->mParent;
} while (nameSpace);
if (!aPrefix) {
*aNameSpaceID = kNameSpaceID_None;
}
else {
*aNameSpaceID = kNameSpaceID_Unknown;
}
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceImpl::FindNameSpacePrefix(PRInt32 aNameSpaceID,
nsIAtom** aPrefix) const
{
const NameSpaceImpl* nameSpace = this;
do {
if (aNameSpaceID == nameSpace->mID) {
NS_IF_ADDREF(*aPrefix = nameSpace->mPrefix);
return NS_OK;
}
nameSpace = nameSpace->mParent;
} while (nameSpace);
*aPrefix = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceImpl::CreateChildNameSpace(nsIAtom* aPrefix, const nsAString& aURI,
nsINameSpace** aChildNameSpace)
{
*aChildNameSpace = nsnull;
PRInt32 id;
nsresult rv = gNameSpaceManager->RegisterNameSpace(aURI, id);
NS_ENSURE_SUCCESS(rv, rv);
*aChildNameSpace = new NameSpaceImpl(this, aPrefix, id);
if (!*aChildNameSpace) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(*aChildNameSpace);
return NS_OK;
}
NameSpaceManagerImpl::NameSpaceManagerImpl()
{
}
@ -319,30 +178,6 @@ nsresult NameSpaceManagerImpl::Init()
return NS_OK;
}
NS_IMETHODIMP
NameSpaceManagerImpl::CreateRootNameSpace(nsINameSpace** aRootNameSpace)
{
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
*aRootNameSpace = nsnull;
NameSpaceImpl* xmlns = new NameSpaceImpl(nsnull,
nsLayoutAtoms::xmlnsNameSpace,
kNameSpaceID_XMLNS);
if (xmlns) {
NameSpaceImpl* xml = new NameSpaceImpl(xmlns,
nsLayoutAtoms::xmlNameSpace,
kNameSpaceID_XML);
if (xml) {
rv = CallQueryInterface(xml, aRootNameSpace);
}
else {
delete xmlns;
}
}
return rv;
}
NS_IMETHODIMP
NameSpaceManagerImpl::RegisterNameSpace(const nsAString& aURI,
PRInt32& aNameSpaceID)

View File

@ -0,0 +1,191 @@
/* -*- 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 Communicator client code.
*
* 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 <bryner@brianryner.com>
*
* 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 ***** */
#include "nsNameSpaceMap.h"
#include "nsIAtom.h"
#include "nsCOMPtr.h"
#include "nsINameSpaceManager.h"
#include "nsContentUtils.h"
#include "nsLayoutAtoms.h"
struct nsNameSpaceEntry
{
nsNameSpaceEntry(nsIAtom *aPrefix)
: prefix(aPrefix) {}
nsCOMPtr<nsIAtom> prefix;
PRInt32 nameSpaceID;
};
/* static */ nsNameSpaceMap*
nsNameSpaceMap::Create()
{
nsNameSpaceMap *map = new nsNameSpaceMap();
NS_ENSURE_TRUE(map, nsnull);
nsresult rv = map->AddPrefix(nsLayoutAtoms::xmlnsNameSpace,
kNameSpaceID_XMLNS);
rv |= map->AddPrefix(nsLayoutAtoms::xmlNameSpace, kNameSpaceID_XML);
if (NS_FAILED(rv)) {
delete map;
map = nsnull;
}
return map;
}
nsNameSpaceMap::nsNameSpaceMap()
: mNameSpaces(4)
{
}
nsresult
nsNameSpaceMap::AddPrefix(nsIAtom *aPrefix, PRInt32 aNameSpaceID)
{
PRInt32 count = mNameSpaces.Count();
nsNameSpaceEntry *foundEntry = nsnull;
for (PRInt32 i = 0; i < count; ++i) {
nsNameSpaceEntry *entry = NS_STATIC_CAST(nsNameSpaceEntry*,
mNameSpaces.FastElementAt(i));
NS_ASSERTION(entry, "null entry in namespace map!");
if (entry->prefix == aPrefix) {
foundEntry = entry;
break;
}
}
if (!foundEntry) {
foundEntry = new nsNameSpaceEntry(aPrefix);
NS_ENSURE_TRUE(foundEntry, NS_ERROR_OUT_OF_MEMORY);
if (!mNameSpaces.AppendElement(foundEntry)) {
delete foundEntry;
return NS_ERROR_OUT_OF_MEMORY;
}
}
foundEntry->nameSpaceID = aNameSpaceID;
return NS_OK;
}
nsresult
nsNameSpaceMap::AddPrefix(nsIAtom *aPrefix, nsString &aURI)
{
PRInt32 id;
nsresult rv = nsContentUtils::GetNSManagerWeakRef()->RegisterNameSpace(aURI,
id);
NS_ENSURE_SUCCESS(rv, rv);
return AddPrefix(aPrefix, id);
}
void
nsNameSpaceMap::RemovePrefix(nsIAtom *aPrefix)
{
PRInt32 count = mNameSpaces.Count();
for (PRInt32 i = 0; i < count; ++i) {
nsNameSpaceEntry *entry = NS_STATIC_CAST(nsNameSpaceEntry*,
mNameSpaces.FastElementAt(i));
NS_ASSERTION(entry, "null entry in namespace map!");
if (entry->prefix == aPrefix) {
mNameSpaces.RemoveElementAt(i);
return;
}
}
}
PRInt32
nsNameSpaceMap::FindNameSpaceID(nsIAtom *aPrefix) const
{
PRInt32 count = mNameSpaces.Count();
for (PRInt32 i = 0; i < count; ++i) {
nsNameSpaceEntry *entry = NS_STATIC_CAST(nsNameSpaceEntry*,
mNameSpaces.FastElementAt(i));
NS_ASSERTION(entry, "null entry in namespace map!");
if (entry->prefix == aPrefix) {
return entry->nameSpaceID;
}
}
// The default mapping for no prefix is no namespace. If a non-null prefix
// was specified and we didn't find it, we return an error.
return aPrefix ? kNameSpaceID_Unknown : kNameSpaceID_None;
}
nsIAtom*
nsNameSpaceMap::FindPrefix(PRInt32 aNameSpaceID) const
{
PRInt32 count = mNameSpaces.Count();
for (PRInt32 i = 0; i < count; ++i) {
nsNameSpaceEntry *entry = NS_STATIC_CAST(nsNameSpaceEntry*,
mNameSpaces.FastElementAt(i));
NS_ASSERTION(entry, "null entry in namespace map!");
if (entry->nameSpaceID == aNameSpaceID) {
return entry->prefix;
}
}
return nsnull;
}
PR_STATIC_CALLBACK(PRBool) DeleteEntry(void *aElement, void *aData)
{
delete NS_STATIC_CAST(nsNameSpaceEntry*, aElement);
return PR_TRUE;
}
void
nsNameSpaceMap::Clear()
{
mNameSpaces.EnumerateForwards(DeleteEntry, nsnull);
}

View File

@ -68,7 +68,7 @@
#include "nsCSSPseudoElements.h"
#include "nsCSSAnonBoxes.h"
#include "nsINameSpaceManager.h"
#include "nsINameSpace.h"
#include "nsNameSpaceMap.h"
#include "nsThemeConstants.h"
#include "nsContentErrors.h"
#include "nsUnitConversion.h"
@ -367,7 +367,7 @@ protected:
};
nsCSSSection mSection;
nsCOMPtr<nsINameSpace> mNameSpace;
nsNameSpaceMap *mNameSpaceMap; // weak, mSheet owns it
// After an UngetToken is done this flag is true. The next call to
// GetToken clears the flag.
@ -472,6 +472,7 @@ CSSParserImpl::CSSParserImpl()
mScanner(),
mChildLoader(nsnull),
mSection(eCSSSection_Charset),
mNameSpaceMap(nsnull),
mHavePushBack(PR_FALSE),
mNavQuirkMode(PR_FALSE),
#ifdef MOZ_SVG
@ -505,7 +506,7 @@ CSSParserImpl::SetStyleSheet(nsICSSStyleSheet* aSheet)
// Switch to using the new sheet
mGroupStack.Clear();
mSheet = aSheet;
mSheet->GetNameSpace(*getter_AddRefs(mNameSpace));
mNameSpaceMap = mSheet->GetNameSpaceMap();
}
return NS_OK;
@ -582,7 +583,10 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput,
if (! mSheet) {
NS_NewCSSStyleSheet(getter_AddRefs(mSheet));
NS_ENSURE_TRUE(mSheet, NS_ERROR_OUT_OF_MEMORY);
mSheet->SetURIs(aSheetURI, aBaseURI);
mNameSpaceMap = nsnull;
}
#ifdef DEBUG
else {
@ -594,10 +598,6 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput,
}
#endif
if (! mSheet) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult errorCode = NS_OK;
nsresult result = InitScanner(aInput, aSheetURI, aLineNumber, aBaseURI);
@ -1429,7 +1429,12 @@ PRBool CSSParserImpl::ProcessNameSpace(nsresult& aErrorCode, const nsString& aPr
NS_NewCSSNameSpaceRule(getter_AddRefs(rule), prefix, aURLSpec);
if (rule) {
(*aAppendFunc)(rule, aData);
mSheet->GetNameSpace(*getter_AddRefs(mNameSpace));
// If this was the first namespace rule encountered, it will trigger
// creation of a namespace map.
if (!mNameSpaceMap) {
mNameSpaceMap = mSheet->GetNameSpaceMap();
}
}
return result;
@ -1903,12 +1908,9 @@ CSSParserImpl::ParseTypeOrUniversalSelector(PRInt32& aDataMask,
}
else { // was universal element selector
aSelector.SetNameSpace(kNameSpaceID_Unknown); // wildcard
if (mNameSpace) { // look for default namespace
nsCOMPtr<nsINameSpace> defaultNameSpace;
mNameSpace->FindNameSpace(nsnull, getter_AddRefs(defaultNameSpace));
if (defaultNameSpace) {
PRInt32 defaultID;
defaultNameSpace->GetNameSpaceID(&defaultID);
if (mNameSpaceMap) { // look for default namespace
PRInt32 defaultID = mNameSpaceMap->FindNameSpaceID(nsnull);
if (defaultID != kNameSpaceID_None) {
aSelector.SetNameSpace(defaultID);
}
}
@ -1925,10 +1927,10 @@ CSSParserImpl::ParseTypeOrUniversalSelector(PRInt32& aDataMask,
if (ExpectSymbol(aErrorCode, '|', PR_FALSE)) { // was namespace
aDataMask |= SEL_MASK_NSPACE;
PRInt32 nameSpaceID = kNameSpaceID_Unknown;
if (mNameSpace) {
if (mNameSpaceMap) {
ToLowerCase(buffer); // always case insensitive, since stays within CSS
nsCOMPtr<nsIAtom> prefix = do_GetAtom(buffer);
mNameSpace->FindNameSpaceID(prefix, &nameSpaceID);
nameSpaceID = mNameSpaceMap->FindNameSpaceID(prefix);
} // else, no declared namespaces
if (kNameSpaceID_Unknown == nameSpaceID) { // unknown prefix, dump it
const PRUnichar *params[] = {
@ -1965,12 +1967,9 @@ CSSParserImpl::ParseTypeOrUniversalSelector(PRInt32& aDataMask,
}
else { // was element name
aSelector.SetNameSpace(kNameSpaceID_Unknown); // wildcard
if (mNameSpace) { // look for default namespace
nsCOMPtr<nsINameSpace> defaultNameSpace;
mNameSpace->FindNameSpace(nsnull, getter_AddRefs(defaultNameSpace));
if (defaultNameSpace) {
PRInt32 defaultID;
defaultNameSpace->GetNameSpaceID(&defaultID);
if (mNameSpaceMap) { // look for default namespace
PRInt32 defaultID = mNameSpaceMap->FindNameSpaceID(nsnull);
if (defaultID != kNameSpaceID_None) {
aSelector.SetNameSpace(defaultID);
}
}
@ -2023,12 +2022,9 @@ CSSParserImpl::ParseTypeOrUniversalSelector(PRInt32& aDataMask,
// no tag or namespace: implied universal selector
// set namespace to unknown since it is not specified
aSelector.SetNameSpace(kNameSpaceID_Unknown); // wildcard
if (mNameSpace) { // look for default namespace
nsCOMPtr<nsINameSpace> defaultNameSpace;
mNameSpace->FindNameSpace(nsnull, getter_AddRefs(defaultNameSpace));
if (defaultNameSpace) {
PRInt32 defaultID;
defaultNameSpace->GetNameSpaceID(&defaultID);
if (mNameSpaceMap) { // look for default namespace
PRInt32 defaultID = mNameSpaceMap->FindNameSpaceID(nsnull);
if (defaultID != kNameSpaceID_None) {
aSelector.SetNameSpace(defaultID);
}
}
@ -2096,10 +2092,10 @@ CSSParserImpl::ParseAttributeSelector(PRInt32& aDataMask,
attr = mToken.mIdent; // hang on to it
if (ExpectSymbol(aErrorCode, '|', PR_FALSE)) { // was a namespace
nameSpaceID = kNameSpaceID_Unknown;
if (mNameSpace) {
if (mNameSpaceMap) {
ToLowerCase(attr); // always case insensitive, since stays within CSS
nsCOMPtr<nsIAtom> prefix = do_GetAtom(attr);
mNameSpace->FindNameSpaceID(prefix, &nameSpaceID);
nameSpaceID = mNameSpaceMap->FindNameSpaceID(prefix);
} // else, no declared namespaces
if (kNameSpaceID_Unknown == nameSpaceID) { // unknown prefix, dump it
const PRUnichar *params[] = {
@ -3636,10 +3632,10 @@ PRBool CSSParserImpl::ParseAttr(nsresult& aErrorCode, nsCSSValue& aValue)
nsAutoString holdIdent(mToken.mIdent);
if (ExpectSymbol(aErrorCode, '|', PR_FALSE)) { // namespace
PRInt32 nameSpaceID = kNameSpaceID_Unknown;
if (mNameSpace) {
if (mNameSpaceMap) {
ToLowerCase(holdIdent); // always case insensitive, since stays within CSS
nsCOMPtr<nsIAtom> prefix = do_GetAtom(holdIdent);
mNameSpace->FindNameSpaceID(prefix, &nameSpaceID);
nameSpaceID = mNameSpaceMap->FindNameSpaceID(prefix);
} // else, no declared namespaces
if (kNameSpaceID_Unknown == nameSpaceID) { // unknown prefix, dump it
const PRUnichar *params[] = {

View File

@ -61,7 +61,7 @@
#include "nsIDOMCSSStyleDeclaration.h"
#include "nsDOMCSSDeclaration.h"
#include "nsINameSpaceManager.h"
#include "nsINameSpace.h"
#include "nsNameSpaceMap.h"
#include "nsILookAndFeel.h"
#include "nsRuleNode.h"
#include "nsUnicharUtils.h"
@ -580,8 +580,7 @@ void nsCSSSelector::ToStringInternal(nsAString& aString,
// before it.
aString.Append(PRUnichar('|'));
} else {
nsCOMPtr<nsINameSpace> sheetNS;
aSheet->GetNameSpace(*getter_AddRefs(sheetNS));
nsNameSpaceMap *sheetNS = aSheet->GetNameSpaceMap();
// sheetNS is non-null if and only if we had an @namespace rule. If it's
// null, that means that the only namespaces we could have are the
@ -589,11 +588,11 @@ void nsCSSSelector::ToStringInternal(nsAString& aString,
// namespace, which we handled above. So no need to output anything when
// sheetNS is null.
if (sheetNS) {
nsCOMPtr<nsIAtom> prefixAtom;
nsIAtom *prefixAtom = nsnull;
// prefixAtom is non-null if and only if we have a prefix other than
// '*'
if (mNameSpace != kNameSpaceID_Unknown) {
sheetNS->FindNameSpacePrefix(mNameSpace, getter_AddRefs(prefixAtom));
prefixAtom = sheetNS->FindPrefix(mNameSpace);
}
if (prefixAtom) {
nsAutoString prefix;
@ -603,8 +602,7 @@ void nsCSSSelector::ToStringInternal(nsAString& aString,
} else if (mNameSpace == kNameSpaceID_Unknown) {
// explicit *| or only non-default namespace rules and we're not
// using any of those namespaces
aString.Append(PRUnichar('*'));
aString.Append(PRUnichar('|'));
aString.AppendLiteral("*|");
}
// else we are in the default namespace and don't need to output
// anything
@ -671,12 +669,9 @@ void nsCSSSelector::ToStringInternal(nsAString& aString,
aString.Append(PRUnichar('['));
// Append the namespace prefix
if (list->mNameSpace > 0) {
nsCOMPtr<nsINameSpace> sheetNS;
aSheet->GetNameSpace(*getter_AddRefs(sheetNS));
nsCOMPtr<nsIAtom> prefixAtom;
nsNameSpaceMap *sheetNS = aSheet->GetNameSpaceMap();
// will return null if namespace was the default
sheetNS->FindNameSpacePrefix(list->mNameSpace,
getter_AddRefs(prefixAtom));
nsIAtom *prefixAtom = sheetNS->FindPrefix(list->mNameSpace);
if (prefixAtom) {
nsAutoString prefix;
prefixAtom->ToString(prefix);

View File

@ -86,7 +86,7 @@
#include "nsRuleWalker.h"
#include "nsCSSPseudoClasses.h"
#include "nsINameSpaceManager.h"
#include "nsINameSpace.h"
#include "nsNameSpaceMap.h"
#include "nsITextContent.h"
#include "prlog.h"
#include "nsCOMPtr.h"
@ -1225,7 +1225,6 @@ static PRBool SetStyleSheetReference(nsISupports* aElement, void* aSheet)
nsCSSStyleSheetInner::nsCSSStyleSheetInner(nsICSSStyleSheet* aParentSheet)
: mSheets(),
mOrderedRules(nsnull),
mNameSpace(nsnull),
mComplete(PR_FALSE)
{
MOZ_COUNT_CTOR(nsCSSStyleSheetInner);
@ -1251,7 +1250,6 @@ nsCSSStyleSheetInner::nsCSSStyleSheetInner(nsCSSStyleSheetInner& aCopy,
: mSheets(),
mSheetURI(aCopy.mSheetURI),
mBaseURI(aCopy.mBaseURI),
mNameSpace(nsnull),
mComplete(aCopy.mComplete)
{
MOZ_COUNT_CTOR(nsCSSStyleSheetInner);
@ -1319,21 +1317,15 @@ CreateNameSpace(nsISupports* aRule, void* aNameSpacePtr)
rule->GetType(type);
if (nsICSSRule::NAMESPACE_RULE == type) {
nsICSSNameSpaceRule* nameSpaceRule = (nsICSSNameSpaceRule*)rule;
nsINameSpace** nameSpacePtr = (nsINameSpace**)aNameSpacePtr;
nsINameSpace* lastNameSpace = *nameSpacePtr;
nsINameSpace* newNameSpace;
nsNameSpaceMap *nameSpaceMap =
NS_STATIC_CAST(nsNameSpaceMap*, aNameSpacePtr);
nsIAtom* prefix = nsnull;
nsAutoString urlSpec;
nameSpaceRule->GetPrefix(prefix);
nameSpaceRule->GetURLSpec(urlSpec);
lastNameSpace->CreateChildNameSpace(prefix, urlSpec, &newNameSpace);
NS_IF_RELEASE(prefix);
if (newNameSpace) {
NS_RELEASE(lastNameSpace);
(*nameSpacePtr) = newNameSpace; // takes ref
}
nameSpaceMap->AddPrefix(prefix, urlSpec);
return PR_TRUE;
}
// stop if not namespace, import or charset because namespace can't follow anything else
@ -1344,11 +1336,17 @@ CreateNameSpace(nsISupports* aRule, void* aNameSpacePtr)
void
nsCSSStyleSheetInner::RebuildNameSpaces()
{
nsContentUtils::GetNSManagerWeakRef()->
CreateRootNameSpace(getter_AddRefs(mNameSpace));
if (mNameSpaceMap) {
mNameSpaceMap->Clear();
} else {
mNameSpaceMap = nsNameSpaceMap::Create();
if (!mNameSpaceMap) {
return; // out of memory
}
}
if (mOrderedRules) {
mOrderedRules->EnumerateForwards(CreateNameSpace, address_of(mNameSpace));
mOrderedRules->EnumerateForwards(CreateNameSpace, mNameSpaceMap);
}
}
@ -1871,28 +1869,20 @@ nsCSSStyleSheet::AppendStyleRule(nsICSSRule* aRule)
PRInt32 type = nsICSSRule::UNKNOWN_RULE;
aRule->GetType(type);
if (nsICSSRule::NAMESPACE_RULE == type) {
if (! mInner->mNameSpace) {
nsContentUtils::GetNSManagerWeakRef()->
CreateRootNameSpace(getter_AddRefs(mInner->mNameSpace));
if (!mInner->mNameSpaceMap) {
mInner->mNameSpaceMap = nsNameSpaceMap::Create();
NS_ENSURE_TRUE(mInner->mNameSpaceMap, NS_ERROR_OUT_OF_MEMORY);
}
if (mInner->mNameSpace) {
nsCOMPtr<nsICSSNameSpaceRule> nameSpaceRule(do_QueryInterface(aRule));
nsCOMPtr<nsINameSpace> newNameSpace;
nsCOMPtr<nsICSSNameSpaceRule> nameSpaceRule(do_QueryInterface(aRule));
nsCOMPtr<nsIAtom> prefix;
nsAutoString urlSpec;
nameSpaceRule->GetPrefix(*getter_AddRefs(prefix));
nameSpaceRule->GetURLSpec(urlSpec);
mInner->mNameSpace->
CreateChildNameSpace(prefix, urlSpec,
getter_AddRefs(newNameSpace));
if (newNameSpace) {
mInner->mNameSpace = newNameSpace;
}
}
nsCOMPtr<nsIAtom> prefix;
nsAutoString urlSpec;
nameSpaceRule->GetPrefix(*getter_AddRefs(prefix));
nameSpaceRule->GetURLSpec(urlSpec);
mInner->mNameSpaceMap->AddPrefix(prefix, urlSpec);
}
}
}
return NS_OK;
@ -1956,17 +1946,10 @@ nsCSSStyleSheet::GetStyleRuleAt(PRInt32 aIndex, nsICSSRule*& aRule) const
return result;
}
NS_IMETHODIMP
nsCSSStyleSheet::GetNameSpace(nsINameSpace*& aNameSpace) const
nsNameSpaceMap*
nsCSSStyleSheet::GetNameSpaceMap() const
{
if (mInner) {
aNameSpace = mInner->mNameSpace;
NS_IF_ADDREF(aNameSpace);
}
else {
aNameSpace = nsnull;
}
return NS_OK;
return mInner ? mInner->mNameSpaceMap : nsnull;
}
NS_IMETHODIMP
@ -2499,25 +2482,19 @@ nsCSSStyleSheet::InsertRule(const nsAString& aRule,
PRInt32 type = nsICSSRule::UNKNOWN_RULE;
cssRule->GetType(type);
if (type == nsICSSRule::NAMESPACE_RULE) {
if (! mInner->mNameSpace) {
nsContentUtils::GetNSManagerWeakRef()->
CreateRootNameSpace(getter_AddRefs(mInner->mNameSpace));
if (!mInner->mNameSpaceMap) {
mInner->mNameSpaceMap = nsNameSpaceMap::Create();
NS_ENSURE_TRUE(mInner->mNameSpaceMap, NS_ERROR_OUT_OF_MEMORY);
}
NS_ENSURE_TRUE(mInner->mNameSpace, NS_ERROR_FAILURE);
nsCOMPtr<nsICSSNameSpaceRule> nameSpaceRule(do_QueryInterface(cssRule));
nsCOMPtr<nsINameSpace> newNameSpace;
nsCOMPtr<nsIAtom> prefix;
nsAutoString urlSpec;
nameSpaceRule->GetPrefix(*getter_AddRefs(prefix));
nameSpaceRule->GetURLSpec(urlSpec);
mInner->mNameSpace->CreateChildNameSpace(prefix, urlSpec,
getter_AddRefs(newNameSpace));
if (newNameSpace) {
mInner->mNameSpace = newNameSpace;
}
mInner->mNameSpaceMap->AddPrefix(prefix, urlSpec);
}
// We don't notify immediately for @import rules, but rather when

View File

@ -44,13 +44,13 @@
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsICSSStyleSheet.h"
#include "nsIDOMCSSStyleSheet.h"
#include "nsICSSLoaderObserver.h"
#include "nsVoidArray.h"
class nsIURI;
class nsINameSpace;
class nsISupportsArray;
// -------------------------------
@ -73,7 +73,7 @@ public:
nsCOMPtr<nsIURI> mSheetURI; // for error reports, etc.
nsCOMPtr<nsIURI> mBaseURI; // for resolving relative URIs
nsISupportsArray* mOrderedRules;
nsCOMPtr<nsINameSpace> mNameSpace;
nsAutoPtr<nsNameSpaceMap> mNameSpaceMap;
PRPackedBool mComplete;
};
@ -138,7 +138,7 @@ public:
NS_IMETHOD SetOwningNode(nsIDOMNode* aOwningNode);
NS_IMETHOD SetOwnerRule(nsICSSImportRule* aOwnerRule);
NS_IMETHOD GetOwnerRule(nsICSSImportRule** aOwnerRule);
NS_IMETHOD GetNameSpace(nsINameSpace*& aNameSpace) const;
virtual NS_HIDDEN_(nsNameSpaceMap*) GetNameSpaceMap() const;
NS_IMETHOD Clone(nsICSSStyleSheet* aCloneParent,
nsICSSImportRule* aCloneOwnerRule,
nsIDocument* aCloneDocument,

View File

@ -42,16 +42,16 @@
class nsICSSRule;
class nsIDOMNode;
class nsINameSpace;
class nsNameSpaceMap;
class nsCSSRuleProcessor;
class nsIMediaList;
class nsICSSGroupRule;
class nsICSSImportRule;
// IID for the nsICSSStyleSheet interface
// d148e93e-7f1d-4f95-853f-ac356eba3d70
// 37f9b0f0-5d00-4abc-9246-35473031ffd7
#define NS_ICSS_STYLE_SHEET_IID \
{0xd148e93e, 0x7f1d, 0x4f95, {0x85, 0x3f, 0xac, 0x35, 0x6e, 0xba, 0x3d, 0x70}}
{0x37f9b0f0, 0x5d00, 0x4abc, {0x92, 0x46, 0x35, 0x47, 0x30, 0x31, 0xff, 0xd7}}
class nsICSSStyleSheet : public nsIStyleSheet {
public:
@ -91,8 +91,8 @@ public:
NS_IMETHOD SetOwnerRule(nsICSSImportRule* aOwnerRule) = 0;
NS_IMETHOD GetOwnerRule(nsICSSImportRule** aOwnerRule) = 0;
// get head of namespace chain for sheet
NS_IMETHOD GetNameSpace(nsINameSpace*& aNameSpace) const = 0;
// get namespace map for sheet
virtual NS_HIDDEN_(nsNameSpaceMap*) GetNameSpaceMap() const = 0;
NS_IMETHOD Clone(nsICSSStyleSheet* aCloneParent,
nsICSSImportRule* aCloneOwnerRule,