~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/content/base/src/nsNodeInfo.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 *
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the NPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the NPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
#include "nscore.h"
 
40
#include "nsNodeInfo.h"
 
41
#include "nsNodeInfoManager.h"
 
42
#include "nsCOMPtr.h"
 
43
#include "nsString.h"
 
44
#include "nsIAtom.h"
 
45
#include "nsDOMString.h"
 
46
#include "nsCRT.h"
 
47
#include "nsContentUtils.h"
 
48
#include "nsReadableUtils.h"
 
49
 
 
50
// static
 
51
nsNodeInfo*
 
52
nsNodeInfo::Create()
 
53
{
 
54
  if (sCachedNodeInfo) {
 
55
    // We have cached unused instances of this class, return a cached
 
56
    // instance instead of always creating a new one.
 
57
    nsNodeInfo *nodeInfo = sCachedNodeInfo;
 
58
    sCachedNodeInfo = nsnull;
 
59
    return nodeInfo;
 
60
  }
 
61
 
 
62
  // Create a new one
 
63
  return new nsNodeInfo();
 
64
}
 
65
 
 
66
nsNodeInfo::nsNodeInfo()
 
67
{
 
68
}
 
69
 
 
70
 
 
71
nsNodeInfo::~nsNodeInfo()
 
72
{
 
73
  Clear();
 
74
}
 
75
 
 
76
void
 
77
nsNodeInfo::Clear()
 
78
{
 
79
  if (mOwnerManager) {
 
80
    NS_STATIC_CAST(nsNodeInfoManager*, mOwnerManager)->RemoveNodeInfo(this);
 
81
    NS_RELEASE(mOwnerManager);
 
82
  }
 
83
 
 
84
  NS_IF_RELEASE(mInner.mName);
 
85
  NS_IF_RELEASE(mInner.mPrefix);
 
86
}
 
87
 
 
88
 
 
89
nsresult
 
90
nsNodeInfo::Init(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
 
91
                 nsNodeInfoManager *aOwnerManager)
 
92
{
 
93
  NS_ENSURE_TRUE(!mInner.mName && !mInner.mPrefix && !mOwnerManager,
 
94
                 NS_ERROR_ALREADY_INITIALIZED);
 
95
  NS_ENSURE_ARG_POINTER(aName);
 
96
  NS_ENSURE_ARG_POINTER(aOwnerManager);
 
97
 
 
98
  mInner.mName = aName;
 
99
  NS_ADDREF(mInner.mName);
 
100
 
 
101
  mInner.mPrefix = aPrefix;
 
102
  NS_IF_ADDREF(mInner.mPrefix);
 
103
 
 
104
  mInner.mNamespaceID = aNamespaceID;
 
105
 
 
106
  mOwnerManager = aOwnerManager;
 
107
  NS_ADDREF(mOwnerManager);
 
108
 
 
109
  return NS_OK;
 
110
}
 
111
 
 
112
 
 
113
// nsISupports
 
114
 
 
115
NS_IMPL_ADDREF(nsNodeInfo)
 
116
NS_IMPL_RELEASE_WITH_DESTROY(nsNodeInfo, LastRelease())
 
117
NS_IMPL_QUERY_INTERFACE1(nsNodeInfo, nsINodeInfo)
 
118
 
 
119
// nsINodeInfo
 
120
 
 
121
void
 
122
nsNodeInfo::GetQualifiedName(nsAString& aQualifiedName) const
 
123
{
 
124
  if (mInner.mPrefix) {
 
125
    mInner.mPrefix->ToString(aQualifiedName);
 
126
 
 
127
    aQualifiedName.Append(PRUnichar(':'));
 
128
  } else {
 
129
    aQualifiedName.Truncate();
 
130
  }
 
131
 
 
132
  nsAutoString name;
 
133
  mInner.mName->ToString(name);
 
134
 
 
135
  aQualifiedName.Append(name);
 
136
}
 
137
 
 
138
 
 
139
void
 
140
nsNodeInfo::GetLocalName(nsAString& aLocalName) const
 
141
{
 
142
#ifdef STRICT_DOM_LEVEL2_LOCALNAME
 
143
  if (mInner.mNamespaceID > 0) {
 
144
    mInner.mName->ToString(aLocalName);
 
145
  } else {
 
146
    SetDOMStringToNull(aLocalName);
 
147
  }
 
148
#else
 
149
  mInner.mName->ToString(aLocalName);
 
150
#endif
 
151
}
 
152
 
 
153
 
 
154
nsresult
 
155
nsNodeInfo::GetNamespaceURI(nsAString& aNameSpaceURI) const
 
156
{
 
157
  nsresult rv = NS_OK;
 
158
 
 
159
  if (mInner.mNamespaceID > 0) {
 
160
    rv = nsContentUtils::GetNSManagerWeakRef()->GetNameSpaceURI(mInner.mNamespaceID,
 
161
                                                                aNameSpaceURI);
 
162
  } else {
 
163
    SetDOMStringToNull(aNameSpaceURI);
 
164
  }
 
165
 
 
166
  return rv;
 
167
}
 
168
 
 
169
 
 
170
PRBool
 
171
nsNodeInfo::Equals(const nsAString& aName) const
 
172
{
 
173
  return mInner.mName->Equals(aName);
 
174
}
 
175
 
 
176
 
 
177
PRBool
 
178
nsNodeInfo::Equals(const nsAString& aName, const nsAString& aPrefix) const
 
179
{
 
180
  if (!mInner.mName->Equals(aName)) {
 
181
    return PR_FALSE;
 
182
  }
 
183
 
 
184
  if (!mInner.mPrefix) {
 
185
    return aPrefix.IsEmpty();
 
186
  }
 
187
 
 
188
  return mInner.mPrefix->Equals(aPrefix);
 
189
}
 
190
 
 
191
 
 
192
PRBool
 
193
nsNodeInfo::Equals(const nsAString& aName, PRInt32 aNamespaceID) const
 
194
{
 
195
  return mInner.mNamespaceID == aNamespaceID &&
 
196
    mInner.mName->Equals(aName);
 
197
}
 
198
 
 
199
 
 
200
PRBool
 
201
nsNodeInfo::Equals(const nsAString& aName, const nsAString& aPrefix,
 
202
                   PRInt32 aNamespaceID) const
 
203
{
 
204
  if (!mInner.mNamespaceID == aNamespaceID ||
 
205
      !mInner.mName->Equals(aName))
 
206
    return PR_FALSE;
 
207
 
 
208
  return mInner.mPrefix ? mInner.mPrefix->Equals(aPrefix) :
 
209
    aPrefix.IsEmpty();
 
210
}
 
211
 
 
212
 
 
213
PRBool
 
214
nsNodeInfo::NamespaceEquals(const nsAString& aNamespaceURI) const
 
215
{
 
216
  PRInt32 nsid;
 
217
  nsContentUtils::GetNSManagerWeakRef()->GetNameSpaceID(aNamespaceURI, &nsid);
 
218
 
 
219
  return nsINodeInfo::NamespaceEquals(nsid);
 
220
}
 
221
 
 
222
PRBool
 
223
nsNodeInfo::QualifiedNameEquals(const nsACString& aQualifiedName) const
 
224
{
 
225
  
 
226
  if (!mInner.mPrefix)
 
227
    return mInner.mName->EqualsUTF8(aQualifiedName);
 
228
 
 
229
  nsACString::const_iterator start;
 
230
  aQualifiedName.BeginReading(start);
 
231
 
 
232
  nsACString::const_iterator colon(start);
 
233
 
 
234
  const char* prefix;
 
235
  mInner.mPrefix->GetUTF8String(&prefix);
 
236
 
 
237
  PRUint32 len = strlen(prefix);
 
238
 
 
239
  if (len >= aQualifiedName.Length()) {
 
240
    return PR_FALSE;
 
241
  }
 
242
 
 
243
  colon.advance(len);
 
244
 
 
245
  // If the character at the prefix length index is not a colon,
 
246
  // aQualifiedName is not equal to this string.
 
247
  if (*colon != ':') {
 
248
    return PR_FALSE;
 
249
  }
 
250
 
 
251
  // Compare the prefix to the string from the start to the colon
 
252
  if (!mInner.mPrefix->EqualsUTF8(Substring(start, colon)))
 
253
    return PR_FALSE;
 
254
 
 
255
  ++colon; // Skip the ':'
 
256
 
 
257
  nsACString::const_iterator end;
 
258
  aQualifiedName.EndReading(end);
 
259
 
 
260
  // Compare the local name to the string between the colon and the
 
261
  // end of aQualifiedName
 
262
  return mInner.mName->EqualsUTF8(Substring(colon, end));
 
263
}
 
264
 
 
265
// static
 
266
nsNodeInfo *nsNodeInfo::sCachedNodeInfo = nsnull;
 
267
 
 
268
// static
 
269
void
 
270
nsNodeInfo::ClearCache()
 
271
{
 
272
  // Clear our cache.
 
273
  delete sCachedNodeInfo;
 
274
  sCachedNodeInfo = nsnull;
 
275
}
 
276
 
 
277
void
 
278
nsNodeInfo::LastRelease()
 
279
{
 
280
  if (sCachedNodeInfo) {
 
281
    // No room in cache
 
282
    delete this;
 
283
    return;
 
284
  }
 
285
 
 
286
  // There's space in the cache for one instance. Put
 
287
  // this instance in the cache instead of deleting it.
 
288
  sCachedNodeInfo = this;
 
289
 
 
290
  // Clear object so that we have no references to anything external
 
291
  Clear();
 
292
 
 
293
  // The refcount balancing and destructor re-entrancy protection
 
294
  // code in Release() sets mRefCnt to 1 so we have to set it to 0
 
295
  // here to prevent leaks
 
296
  mRefCnt = 0;
 
297
}