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

« back to all changes in this revision

Viewing changes to mozilla/editor/libeditor/html/nsHTMLURIRefObject.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
/* Here is the list, from beppe and glazman:
 
40
    href >> A, AREA, BASE, LINK
 
41
    src >> FRAME, IFRAME, IMG, INPUT, SCRIPT
 
42
    <META http-equiv="refresh" content="3,http://www.acme.com/intro.html">
 
43
    longdesc >> FRAME, IFRAME, IMG
 
44
    usemap >> IMG, INPUT, OBJECT
 
45
    action >> FORM
 
46
    background >> BODY
 
47
    codebase >> OBJECT, APPLET
 
48
    classid >> OBJECT
 
49
    data >> OBJECT
 
50
    cite >> BLOCKQUOTE, DEL, INS, Q
 
51
    profile >> HEAD
 
52
    ARCHIVE attribute on APPLET ; warning, it contains a list of URIs.
 
53
 
 
54
    Easier way of organizing the list:
 
55
    a:      href
 
56
    area:   href
 
57
    base:   href
 
58
    body:   background
 
59
    blockquote: cite (not normally rewritable)
 
60
    link:   href
 
61
    frame:  src, longdesc
 
62
    iframe: src, longdesc
 
63
    input:  src, usemap
 
64
    form:   action
 
65
    img:    src, longdesc, usemap
 
66
    script: src
 
67
    applet: codebase, archive <list>
 
68
    object: codebase, data, classid, usemap
 
69
    head:   profile
 
70
    del:    cite
 
71
    ins:    cite
 
72
    q:      cite
 
73
 */
 
74
 
 
75
/* Here is how to open a channel for testing
 
76
   (from embed/qa/testembed/Tests.cpp):
 
77
 
 
78
  nsCOMPtr<nsIChannel> theChannel;
 
79
  nsCString uri;
 
80
  nsCOMPtr<nsIURI> theURI;
 
81
  rv = NS_NewURI(getter_AddRefs(theURI), theSpec);
 
82
  if (!theURI)
 
83
    error;
 
84
  rv = NS_OpenURI(getter_AddRefs(theChannel), theURI, nsnull, theLoadGroup);
 
85
  if (!theChannel)
 
86
    error;
 
87
  nsCOMPtr<nsILoadGroup> theLoadGroup(do_CreateInstance(NS_LOADGROUP_CONTRACTID));
 
88
  if (!theLoadGroup)
 
89
    error;
 
90
                nsCOMPtr<nsIStreamListener> listener(NS_STATIC_CAST(nsIStreamListener*, qaBrowserImpl));
 
91
                //nsCOMPtr<nsIWeakReference> thisListener(do_GetWeakReference(listener));
 
92
                //qaWebBrowser->AddWebBrowserListener(thisListener, NS_GET_IID(nsIStreamListener));
 
93
 
 
94
                // this calls nsIStreamListener::OnDataAvailable()
 
95
                rv = theChannel->AsyncOpen(listener, nsnull);
 
96
 
 
97
                nsCOMPtr<nsIRequest> theRequest = do_QueryInterface(theChannel);
 
98
    // Now we can do things on nsIRequest (like what?)
 
99
 */
 
100
 
 
101
#include "nsHTMLURIRefObject.h"
 
102
 
 
103
#include "nsAString.h"
 
104
#include "nsString.h"
 
105
#include "nsIDOMAttr.h"
 
106
#include "nsIDOMElement.h"
 
107
 
 
108
// String classes change too often and I can't keep up.
 
109
// Set this macro to this week's approved case-insensitive compare routine.
 
110
#define MATCHES(tagName, str) tagName.EqualsIgnoreCase(str)
 
111
 
 
112
nsHTMLURIRefObject::nsHTMLURIRefObject()
 
113
{
 
114
  mCurAttrIndex = mAttributeCnt = 0;
 
115
}
 
116
 
 
117
nsHTMLURIRefObject::~nsHTMLURIRefObject()
 
118
{
 
119
}
 
120
 
 
121
//Interfaces for addref and release and queryinterface
 
122
NS_IMPL_ISUPPORTS1(nsHTMLURIRefObject, nsIURIRefObject)
 
123
 
 
124
NS_IMETHODIMP
 
125
nsHTMLURIRefObject::Reset()
 
126
{
 
127
  mCurAttrIndex = 0;
 
128
  return NS_OK;
 
129
}
 
130
 
 
131
NS_IMETHODIMP
 
132
nsHTMLURIRefObject::GetNextURI(nsAString & aURI)
 
133
{
 
134
  if (!mNode)
 
135
    return NS_ERROR_NOT_INITIALIZED;
 
136
 
 
137
  nsAutoString tagName;
 
138
  nsresult rv = mNode->GetNodeName(tagName);
 
139
  if (NS_FAILED(rv))
 
140
  return rv;
 
141
 
 
142
  // Loop over attribute list:
 
143
  if (!mAttributes)
 
144
  {
 
145
    nsCOMPtr<nsIDOMElement> element (do_QueryInterface(mNode));
 
146
    if (!element)
 
147
      return NS_ERROR_INVALID_ARG;
 
148
 
 
149
    mCurAttrIndex = 0;
 
150
    mNode->GetAttributes(getter_AddRefs(mAttributes));
 
151
    if (!mAttributes)
 
152
      return NS_ERROR_NOT_INITIALIZED;
 
153
 
 
154
    rv = mAttributes->GetLength(&mAttributeCnt);
 
155
    NS_ENSURE_SUCCESS(rv, rv);
 
156
    if (!mAttributeCnt) return NS_ERROR_FAILURE;
 
157
    mCurAttrIndex = 0;
 
158
  }
 
159
#ifdef DEBUG_akkana
 
160
  printf("Looking at tag '%s'\n",
 
161
         NS_LossyConvertUCS2toASCII(tagName).get());
 
162
#endif
 
163
  while (mCurAttrIndex < mAttributeCnt)
 
164
  {
 
165
    nsCOMPtr<nsIDOMNode> attrNode;
 
166
    rv = mAttributes->Item(mCurAttrIndex++, getter_AddRefs(attrNode));
 
167
      // XXX Does Item() addref, or not?
 
168
      // The comparable code in nsEditor assumes it doesn't.
 
169
    NS_ENSURE_SUCCESS(rv, rv);
 
170
    NS_ENSURE_ARG_POINTER(attrNode);
 
171
    nsCOMPtr<nsIDOMAttr> curAttrNode (do_QueryInterface(attrNode));
 
172
    NS_ENSURE_ARG_POINTER(curAttrNode);
 
173
    nsString curAttr;
 
174
    rv = curAttrNode->GetName(curAttr);
 
175
    NS_ENSURE_SUCCESS(rv, rv);
 
176
 
 
177
    // href >> A, AREA, BASE, LINK
 
178
#ifdef DEBUG_akkana
 
179
    printf("Trying to match attribute '%s'\n",
 
180
           NS_LossyConvertUCS2toASCII(curAttr).get());
 
181
#endif
 
182
    if (MATCHES(curAttr, "href"))
 
183
    {
 
184
      if (!MATCHES(tagName, "a") && !MATCHES(tagName, "area")
 
185
          && !MATCHES(tagName, "base") && !MATCHES(tagName, "link"))
 
186
        continue;
 
187
      rv = curAttrNode->GetValue(aURI);
 
188
      NS_ENSURE_SUCCESS(rv, rv);
 
189
      nsString uri (aURI);
 
190
      // href pointing to a named anchor doesn't count
 
191
      if (aURI.First() != PRUnichar('#'))
 
192
        return NS_OK;
 
193
      aURI.Truncate();
 
194
      return NS_ERROR_INVALID_ARG;
 
195
    }
 
196
    // src >> FRAME, IFRAME, IMG, INPUT, SCRIPT
 
197
    else if (MATCHES(curAttr, "src"))
 
198
    {
 
199
      if (!MATCHES(tagName, "img")
 
200
          && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe")
 
201
          && !MATCHES(tagName, "input") && !MATCHES(tagName, "script"))
 
202
        continue;
 
203
      return curAttrNode->GetValue(aURI);
 
204
    }
 
205
    //<META http-equiv="refresh" content="3,http://www.acme.com/intro.html">
 
206
    else if (MATCHES(curAttr, "content"))
 
207
    {
 
208
      if (!MATCHES(tagName, "meta"))
 
209
        continue;
 
210
    }
 
211
    // longdesc >> FRAME, IFRAME, IMG
 
212
    else if (MATCHES(curAttr, "longdesc"))
 
213
    {
 
214
      if (!MATCHES(tagName, "img")
 
215
          && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe"))
 
216
        continue;
 
217
    }
 
218
    // usemap >> IMG, INPUT, OBJECT
 
219
    else if (MATCHES(curAttr, "usemap"))
 
220
    {
 
221
      if (!MATCHES(tagName, "img")
 
222
          && !MATCHES(tagName, "input") && !MATCHES(tagName, "object"))
 
223
        continue;
 
224
    }
 
225
    // action >> FORM
 
226
    else if (MATCHES(curAttr, "action"))
 
227
    {
 
228
      if (!MATCHES(tagName, "form"))
 
229
        continue;
 
230
    }
 
231
    // background >> BODY
 
232
    else if (MATCHES(curAttr, "background"))
 
233
    {
 
234
      if (!MATCHES(tagName, "body"))
 
235
        continue;
 
236
    }
 
237
    // codebase >> OBJECT, APPLET
 
238
    else if (MATCHES(curAttr, "codebase"))
 
239
    {
 
240
      if (!MATCHES(tagName, "meta"))
 
241
        continue;
 
242
    }
 
243
    // classid >> OBJECT
 
244
    else if (MATCHES(curAttr, "classid"))
 
245
    {
 
246
      if (!MATCHES(tagName, "object"))
 
247
        continue;
 
248
    }
 
249
    // data >> OBJECT
 
250
    else if (MATCHES(curAttr, "data"))
 
251
    {
 
252
      if (!MATCHES(tagName, "object"))
 
253
        continue;
 
254
    }
 
255
    // cite >> BLOCKQUOTE, DEL, INS, Q
 
256
    else if (MATCHES(curAttr, "cite"))
 
257
    {
 
258
      if (!MATCHES(tagName, "blockquote") && !MATCHES(tagName, "q")
 
259
          && !MATCHES(tagName, "del") && !MATCHES(tagName, "ins"))
 
260
        continue;
 
261
    }
 
262
    // profile >> HEAD
 
263
    else if (MATCHES(curAttr, "profile"))
 
264
    {
 
265
      if (!MATCHES(tagName, "head"))
 
266
        continue;
 
267
    }
 
268
    // archive attribute on APPLET; warning, it contains a list of URIs.
 
269
    else if (MATCHES(curAttr, "archive"))
 
270
    {
 
271
      if (!MATCHES(tagName, "applet"))
 
272
        continue;
 
273
    }
 
274
  }
 
275
  // Return a code to indicate that there are no more,
 
276
  // to distinguish that case from real errors.
 
277
  return NS_ERROR_NOT_AVAILABLE;
 
278
}
 
279
 
 
280
NS_IMETHODIMP
 
281
nsHTMLURIRefObject::RewriteAllURIs(const nsAString & aOldPat,
 
282
                            const nsAString & aNewPat,
 
283
                            PRBool aMakeRel)
 
284
{
 
285
#ifdef DEBUG_akkana
 
286
  printf("Can't rewrite URIs yet\n");
 
287
#endif
 
288
  return NS_ERROR_NOT_IMPLEMENTED;
 
289
}
 
290
 
 
291
NS_IMETHODIMP
 
292
nsHTMLURIRefObject::GetNode(nsIDOMNode** aNode)
 
293
{
 
294
  if (!mNode)
 
295
    return NS_ERROR_NOT_INITIALIZED;
 
296
  if (!aNode)
 
297
    return NS_ERROR_NULL_POINTER;
 
298
  *aNode = mNode.get();
 
299
  NS_ADDREF(*aNode);
 
300
  return NS_OK;
 
301
}
 
302
 
 
303
NS_IMETHODIMP
 
304
nsHTMLURIRefObject::SetNode(nsIDOMNode *aNode)
 
305
{
 
306
  mNode = aNode;
 
307
  nsAutoString dummyURI;
 
308
  if (NS_SUCCEEDED(GetNextURI(dummyURI)))
 
309
  {
 
310
    mCurAttrIndex = 0;    // Reset so we'll get the first node next time
 
311
    return NS_OK;
 
312
  }
 
313
 
 
314
  // If there weren't any URIs in the attributes,
 
315
  // then don't accept this node.
 
316
  mNode = 0;
 
317
  return NS_ERROR_INVALID_ARG;
 
318
}
 
319
 
 
320
nsresult NS_NewHTMLURIRefObject(nsIURIRefObject** aResult, nsIDOMNode* aNode)
 
321
{
 
322
  nsHTMLURIRefObject* refObject = new nsHTMLURIRefObject();
 
323
  if (!refObject) return NS_ERROR_OUT_OF_MEMORY;
 
324
  nsresult rv = refObject->SetNode(aNode);
 
325
  if (NS_FAILED(rv)) {
 
326
    *aResult = 0;
 
327
    delete refObject;
 
328
    return rv;
 
329
  }
 
330
  return refObject->QueryInterface(NS_GET_IID(nsIURIRefObject),
 
331
                                   (void**)aResult);
 
332
}
 
333