CLOSED TREE: TraceMonkey merge head. (a=blockers)
[mozilla-central.git] / editor / libeditor / html / nsHTMLURIRefObject.cpp
blob0a3cfa695a793fdd4b8b4877c745bbddfb160e31
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
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.
15 * The Original Code is mozilla.org code.
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.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 /* Here is the list, from beppe and glazman:
39 href >> A, AREA, BASE, LINK
40 src >> FRAME, IFRAME, IMG, INPUT, SCRIPT
41 <META http-equiv="refresh" content="3,http://www.acme.com/intro.html">
42 longdesc >> FRAME, IFRAME, IMG
43 usemap >> IMG, INPUT, OBJECT
44 action >> FORM
45 background >> BODY
46 codebase >> OBJECT, APPLET
47 classid >> OBJECT
48 data >> OBJECT
49 cite >> BLOCKQUOTE, DEL, INS, Q
50 profile >> HEAD
51 ARCHIVE attribute on APPLET ; warning, it contains a list of URIs.
53 Easier way of organizing the list:
54 a: href
55 area: href
56 base: href
57 body: background
58 blockquote: cite (not normally rewritable)
59 link: href
60 frame: src, longdesc
61 iframe: src, longdesc
62 input: src, usemap
63 form: action
64 img: src, longdesc, usemap
65 script: src
66 applet: codebase, archive <list>
67 object: codebase, data, classid, usemap
68 head: profile
69 del: cite
70 ins: cite
71 q: cite
74 /* Here is how to open a channel for testing
75 (from embed/qa/testembed/Tests.cpp):
77 nsCOMPtr<nsIChannel> theChannel;
78 nsCString uri;
79 nsCOMPtr<nsIURI> theURI;
80 rv = NS_NewURI(getter_AddRefs(theURI), theSpec);
81 if (!theURI)
82 error;
83 rv = NS_OpenURI(getter_AddRefs(theChannel), theURI, nsnull, theLoadGroup);
84 if (!theChannel)
85 error;
86 nsCOMPtr<nsILoadGroup> theLoadGroup(do_CreateInstance(NS_LOADGROUP_CONTRACTID));
87 if (!theLoadGroup)
88 error;
89 nsCOMPtr<nsIStreamListener> listener(static_cast<nsIStreamListener*>(qaBrowserImpl));
90 //nsCOMPtr<nsIWeakReference> thisListener(do_GetWeakReference(listener));
91 //qaWebBrowser->AddWebBrowserListener(thisListener, NS_GET_IID(nsIStreamListener));
93 // this calls nsIStreamListener::OnDataAvailable()
94 rv = theChannel->AsyncOpen(listener, nsnull);
96 nsCOMPtr<nsIRequest> theRequest = do_QueryInterface(theChannel);
97 // Now we can do things on nsIRequest (like what?)
100 #include "nsHTMLURIRefObject.h"
102 #include "nsAString.h"
103 #include "nsString.h"
104 #include "nsIDOMAttr.h"
105 #include "nsIDOMElement.h"
107 // String classes change too often and I can't keep up.
108 // Set this macro to this week's approved case-insensitive compare routine.
109 #define MATCHES(tagName, str) tagName.EqualsIgnoreCase(str)
111 nsHTMLURIRefObject::nsHTMLURIRefObject()
113 mCurAttrIndex = mAttributeCnt = 0;
116 nsHTMLURIRefObject::~nsHTMLURIRefObject()
120 //Interfaces for addref and release and queryinterface
121 NS_IMPL_ISUPPORTS1(nsHTMLURIRefObject, nsIURIRefObject)
123 NS_IMETHODIMP
124 nsHTMLURIRefObject::Reset()
126 mCurAttrIndex = 0;
127 return NS_OK;
130 NS_IMETHODIMP
131 nsHTMLURIRefObject::GetNextURI(nsAString & aURI)
133 NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED);
135 nsAutoString tagName;
136 nsresult rv = mNode->GetNodeName(tagName);
137 NS_ENSURE_SUCCESS(rv, rv);
139 // Loop over attribute list:
140 if (!mAttributes)
142 nsCOMPtr<nsIDOMElement> element (do_QueryInterface(mNode));
143 NS_ENSURE_TRUE(element, NS_ERROR_INVALID_ARG);
145 mCurAttrIndex = 0;
146 mNode->GetAttributes(getter_AddRefs(mAttributes));
147 NS_ENSURE_TRUE(mAttributes, NS_ERROR_NOT_INITIALIZED);
149 rv = mAttributes->GetLength(&mAttributeCnt);
150 NS_ENSURE_SUCCESS(rv, rv);
151 NS_ENSURE_TRUE(mAttributeCnt, NS_ERROR_FAILURE);
152 mCurAttrIndex = 0;
154 #ifdef DEBUG_akkana
155 printf("Looking at tag '%s'\n",
156 NS_LossyConvertUTF16toASCII(tagName).get());
157 #endif
158 while (mCurAttrIndex < mAttributeCnt)
160 nsCOMPtr<nsIDOMNode> attrNode;
161 rv = mAttributes->Item(mCurAttrIndex++, getter_AddRefs(attrNode));
162 // XXX Does Item() addref, or not?
163 // The comparable code in nsEditor assumes it doesn't.
164 NS_ENSURE_SUCCESS(rv, rv);
165 NS_ENSURE_ARG_POINTER(attrNode);
166 nsCOMPtr<nsIDOMAttr> curAttrNode (do_QueryInterface(attrNode));
167 NS_ENSURE_ARG_POINTER(curAttrNode);
168 nsString curAttr;
169 rv = curAttrNode->GetName(curAttr);
170 NS_ENSURE_SUCCESS(rv, rv);
172 // href >> A, AREA, BASE, LINK
173 #ifdef DEBUG_akkana
174 printf("Trying to match attribute '%s'\n",
175 NS_LossyConvertUTF16toASCII(curAttr).get());
176 #endif
177 if (MATCHES(curAttr, "href"))
179 if (!MATCHES(tagName, "a") && !MATCHES(tagName, "area")
180 && !MATCHES(tagName, "base") && !MATCHES(tagName, "link"))
181 continue;
182 rv = curAttrNode->GetValue(aURI);
183 NS_ENSURE_SUCCESS(rv, rv);
184 nsString uri (aURI);
185 // href pointing to a named anchor doesn't count
186 if (aURI.First() != PRUnichar('#'))
187 return NS_OK;
188 aURI.Truncate();
189 return NS_ERROR_INVALID_ARG;
191 // src >> FRAME, IFRAME, IMG, INPUT, SCRIPT
192 else if (MATCHES(curAttr, "src"))
194 if (!MATCHES(tagName, "img")
195 && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe")
196 && !MATCHES(tagName, "input") && !MATCHES(tagName, "script"))
197 continue;
198 return curAttrNode->GetValue(aURI);
200 //<META http-equiv="refresh" content="3,http://www.acme.com/intro.html">
201 else if (MATCHES(curAttr, "content"))
203 if (!MATCHES(tagName, "meta"))
204 continue;
206 // longdesc >> FRAME, IFRAME, IMG
207 else if (MATCHES(curAttr, "longdesc"))
209 if (!MATCHES(tagName, "img")
210 && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe"))
211 continue;
213 // usemap >> IMG, INPUT, OBJECT
214 else if (MATCHES(curAttr, "usemap"))
216 if (!MATCHES(tagName, "img")
217 && !MATCHES(tagName, "input") && !MATCHES(tagName, "object"))
218 continue;
220 // action >> FORM
221 else if (MATCHES(curAttr, "action"))
223 if (!MATCHES(tagName, "form"))
224 continue;
226 // background >> BODY
227 else if (MATCHES(curAttr, "background"))
229 if (!MATCHES(tagName, "body"))
230 continue;
232 // codebase >> OBJECT, APPLET
233 else if (MATCHES(curAttr, "codebase"))
235 if (!MATCHES(tagName, "meta"))
236 continue;
238 // classid >> OBJECT
239 else if (MATCHES(curAttr, "classid"))
241 if (!MATCHES(tagName, "object"))
242 continue;
244 // data >> OBJECT
245 else if (MATCHES(curAttr, "data"))
247 if (!MATCHES(tagName, "object"))
248 continue;
250 // cite >> BLOCKQUOTE, DEL, INS, Q
251 else if (MATCHES(curAttr, "cite"))
253 if (!MATCHES(tagName, "blockquote") && !MATCHES(tagName, "q")
254 && !MATCHES(tagName, "del") && !MATCHES(tagName, "ins"))
255 continue;
257 // profile >> HEAD
258 else if (MATCHES(curAttr, "profile"))
260 if (!MATCHES(tagName, "head"))
261 continue;
263 // archive attribute on APPLET; warning, it contains a list of URIs.
264 else if (MATCHES(curAttr, "archive"))
266 if (!MATCHES(tagName, "applet"))
267 continue;
270 // Return a code to indicate that there are no more,
271 // to distinguish that case from real errors.
272 return NS_ERROR_NOT_AVAILABLE;
275 NS_IMETHODIMP
276 nsHTMLURIRefObject::RewriteAllURIs(const nsAString & aOldPat,
277 const nsAString & aNewPat,
278 PRBool aMakeRel)
280 #ifdef DEBUG_akkana
281 printf("Can't rewrite URIs yet\n");
282 #endif
283 return NS_ERROR_NOT_IMPLEMENTED;
286 NS_IMETHODIMP
287 nsHTMLURIRefObject::GetNode(nsIDOMNode** aNode)
289 NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED);
290 NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
291 *aNode = mNode.get();
292 NS_ADDREF(*aNode);
293 return NS_OK;
296 NS_IMETHODIMP
297 nsHTMLURIRefObject::SetNode(nsIDOMNode *aNode)
299 mNode = aNode;
300 nsAutoString dummyURI;
301 if (NS_SUCCEEDED(GetNextURI(dummyURI)))
303 mCurAttrIndex = 0; // Reset so we'll get the first node next time
304 return NS_OK;
307 // If there weren't any URIs in the attributes,
308 // then don't accept this node.
309 mNode = 0;
310 return NS_ERROR_INVALID_ARG;
313 nsresult NS_NewHTMLURIRefObject(nsIURIRefObject** aResult, nsIDOMNode* aNode)
315 nsHTMLURIRefObject* refObject = new nsHTMLURIRefObject();
316 NS_ENSURE_TRUE(refObject, NS_ERROR_OUT_OF_MEMORY);
317 nsresult rv = refObject->SetNode(aNode);
318 if (NS_FAILED(rv)) {
319 *aResult = 0;
320 delete refObject;
321 return rv;
323 return refObject->QueryInterface(NS_GET_IID(nsIURIRefObject),
324 (void**)aResult);