1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/src/nsNameSpaceManager.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,199 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * A class for managing namespace IDs and mapping back and forth 1.11 + * between namespace IDs and namespace URIs. 1.12 + */ 1.13 + 1.14 +#include "nsNameSpaceManager.h" 1.15 + 1.16 +#include "nscore.h" 1.17 +#include "nsAutoPtr.h" 1.18 +#include "nsINodeInfo.h" 1.19 +#include "nsCOMArray.h" 1.20 +#include "nsContentCreatorFunctions.h" 1.21 +#include "nsString.h" 1.22 +#include "nsINodeInfo.h" 1.23 +#include "mozilla/ClearOnShutdown.h" 1.24 +#include "mozilla/dom/XBLChildrenElement.h" 1.25 +#include "mozilla/dom/Element.h" 1.26 + 1.27 +using namespace mozilla; 1.28 +using namespace mozilla::dom; 1.29 + 1.30 +#define kXMLNSNameSpaceURI "http://www.w3.org/2000/xmlns/" 1.31 +#define kXMLNameSpaceURI "http://www.w3.org/XML/1998/namespace" 1.32 +#define kXHTMLNameSpaceURI "http://www.w3.org/1999/xhtml" 1.33 +#define kXLinkNameSpaceURI "http://www.w3.org/1999/xlink" 1.34 +#define kXSLTNameSpaceURI "http://www.w3.org/1999/XSL/Transform" 1.35 +#define kXBLNameSpaceURI "http://www.mozilla.org/xbl" 1.36 +#define kMathMLNameSpaceURI "http://www.w3.org/1998/Math/MathML" 1.37 +#define kRDFNameSpaceURI "http://www.w3.org/1999/02/22-rdf-syntax-ns#" 1.38 +#define kXULNameSpaceURI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" 1.39 +#define kSVGNameSpaceURI "http://www.w3.org/2000/svg" 1.40 + 1.41 +StaticAutoPtr<nsNameSpaceManager> nsNameSpaceManager::sInstance; 1.42 + 1.43 +/* static */ nsNameSpaceManager* 1.44 +nsNameSpaceManager::GetInstance() { 1.45 + if (!sInstance) { 1.46 + sInstance = new nsNameSpaceManager(); 1.47 + if (sInstance->Init()) { 1.48 + ClearOnShutdown(&sInstance); 1.49 + } else { 1.50 + delete sInstance; 1.51 + sInstance = nullptr; 1.52 + } 1.53 + } 1.54 + 1.55 + return sInstance; 1.56 +} 1.57 + 1.58 +bool nsNameSpaceManager::Init() 1.59 +{ 1.60 + nsresult rv; 1.61 +#define REGISTER_NAMESPACE(uri, id) \ 1.62 + rv = AddNameSpace(NS_LITERAL_STRING(uri), id); \ 1.63 + NS_ENSURE_SUCCESS(rv, false) 1.64 + 1.65 + // Need to be ordered according to ID. 1.66 + REGISTER_NAMESPACE(kXMLNSNameSpaceURI, kNameSpaceID_XMLNS); 1.67 + REGISTER_NAMESPACE(kXMLNameSpaceURI, kNameSpaceID_XML); 1.68 + REGISTER_NAMESPACE(kXHTMLNameSpaceURI, kNameSpaceID_XHTML); 1.69 + REGISTER_NAMESPACE(kXLinkNameSpaceURI, kNameSpaceID_XLink); 1.70 + REGISTER_NAMESPACE(kXSLTNameSpaceURI, kNameSpaceID_XSLT); 1.71 + REGISTER_NAMESPACE(kXBLNameSpaceURI, kNameSpaceID_XBL); 1.72 + REGISTER_NAMESPACE(kMathMLNameSpaceURI, kNameSpaceID_MathML); 1.73 + REGISTER_NAMESPACE(kRDFNameSpaceURI, kNameSpaceID_RDF); 1.74 + REGISTER_NAMESPACE(kXULNameSpaceURI, kNameSpaceID_XUL); 1.75 + REGISTER_NAMESPACE(kSVGNameSpaceURI, kNameSpaceID_SVG); 1.76 + 1.77 +#undef REGISTER_NAMESPACE 1.78 + 1.79 + return true; 1.80 +} 1.81 + 1.82 +nsresult 1.83 +nsNameSpaceManager::RegisterNameSpace(const nsAString& aURI, 1.84 + int32_t& aNameSpaceID) 1.85 +{ 1.86 + if (aURI.IsEmpty()) { 1.87 + aNameSpaceID = kNameSpaceID_None; // xmlns="", see bug 75700 for details 1.88 + 1.89 + return NS_OK; 1.90 + } 1.91 + 1.92 + nsresult rv = NS_OK; 1.93 + if (!mURIToIDTable.Get(&aURI, &aNameSpaceID)) { 1.94 + aNameSpaceID = mURIArray.Length() + 1; // id is index + 1 1.95 + 1.96 + rv = AddNameSpace(aURI, aNameSpaceID); 1.97 + if (NS_FAILED(rv)) { 1.98 + aNameSpaceID = kNameSpaceID_Unknown; 1.99 + } 1.100 + } 1.101 + 1.102 + NS_POSTCONDITION(aNameSpaceID >= -1, "Bogus namespace ID"); 1.103 + 1.104 + return rv; 1.105 +} 1.106 + 1.107 +nsresult 1.108 +nsNameSpaceManager::GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI) 1.109 +{ 1.110 + NS_PRECONDITION(aNameSpaceID >= 0, "Bogus namespace ID"); 1.111 + 1.112 + int32_t index = aNameSpaceID - 1; // id is index + 1 1.113 + if (index < 0 || index >= int32_t(mURIArray.Length())) { 1.114 + aURI.Truncate(); 1.115 + 1.116 + return NS_ERROR_ILLEGAL_VALUE; 1.117 + } 1.118 + 1.119 + aURI = *mURIArray.ElementAt(index); 1.120 + 1.121 + return NS_OK; 1.122 +} 1.123 + 1.124 +int32_t 1.125 +nsNameSpaceManager::GetNameSpaceID(const nsAString& aURI) 1.126 +{ 1.127 + if (aURI.IsEmpty()) { 1.128 + return kNameSpaceID_None; // xmlns="", see bug 75700 for details 1.129 + } 1.130 + 1.131 + int32_t nameSpaceID; 1.132 + 1.133 + if (mURIToIDTable.Get(&aURI, &nameSpaceID)) { 1.134 + NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID"); 1.135 + return nameSpaceID; 1.136 + } 1.137 + 1.138 + return kNameSpaceID_Unknown; 1.139 +} 1.140 + 1.141 +nsresult 1.142 +NS_NewElement(Element** aResult, 1.143 + already_AddRefed<nsINodeInfo>&& aNodeInfo, 1.144 + FromParser aFromParser) 1.145 +{ 1.146 + nsCOMPtr<nsINodeInfo> ni = aNodeInfo; 1.147 + int32_t ns = ni->NamespaceID(); 1.148 + if (ns == kNameSpaceID_XHTML) { 1.149 + return NS_NewHTMLElement(aResult, ni.forget(), aFromParser); 1.150 + } 1.151 +#ifdef MOZ_XUL 1.152 + if (ns == kNameSpaceID_XUL) { 1.153 + return NS_NewXULElement(aResult, ni.forget()); 1.154 + } 1.155 +#endif 1.156 + if (ns == kNameSpaceID_MathML) { 1.157 + return NS_NewMathMLElement(aResult, ni.forget()); 1.158 + } 1.159 + if (ns == kNameSpaceID_SVG) { 1.160 + return NS_NewSVGElement(aResult, ni.forget(), aFromParser); 1.161 + } 1.162 + if (ns == kNameSpaceID_XBL && ni->Equals(nsGkAtoms::children)) { 1.163 + NS_ADDREF(*aResult = new XBLChildrenElement(ni.forget())); 1.164 + return NS_OK; 1.165 + } 1.166 + 1.167 + return NS_NewXMLElement(aResult, ni.forget()); 1.168 +} 1.169 + 1.170 +bool 1.171 +nsNameSpaceManager::HasElementCreator(int32_t aNameSpaceID) 1.172 +{ 1.173 + return aNameSpaceID == kNameSpaceID_XHTML || 1.174 +#ifdef MOZ_XUL 1.175 + aNameSpaceID == kNameSpaceID_XUL || 1.176 +#endif 1.177 + aNameSpaceID == kNameSpaceID_MathML || 1.178 + aNameSpaceID == kNameSpaceID_SVG || 1.179 + false; 1.180 +} 1.181 + 1.182 +nsresult nsNameSpaceManager::AddNameSpace(const nsAString& aURI, 1.183 + const int32_t aNameSpaceID) 1.184 +{ 1.185 + if (aNameSpaceID < 0) { 1.186 + // We've wrapped... Can't do anything else here; just bail. 1.187 + return NS_ERROR_OUT_OF_MEMORY; 1.188 + } 1.189 + 1.190 + NS_ASSERTION(aNameSpaceID - 1 == (int32_t) mURIArray.Length(), 1.191 + "BAD! AddNameSpace not called in right order!"); 1.192 + 1.193 + nsString* uri = new nsString(aURI); 1.194 + if (!uri || !mURIArray.AppendElement(uri)) { 1.195 + delete uri; 1.196 + return NS_ERROR_OUT_OF_MEMORY; 1.197 + } 1.198 + 1.199 + mURIToIDTable.Put(uri, aNameSpaceID); 1.200 + 1.201 + return NS_OK; 1.202 +}