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
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.
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
46 codebase >> OBJECT, APPLET
49 cite >> BLOCKQUOTE, DEL, INS, Q
51 ARCHIVE attribute on APPLET ; warning, it contains a list of URIs.
53 Easier way of organizing the list:
58 blockquote: cite (not normally rewritable)
64 img: src, longdesc, usemap
66 applet: codebase, archive <list>
67 object: codebase, data, classid, usemap
74 /* Here is how to open a channel for testing
75 (from embed/qa/testembed/Tests.cpp):
77 nsCOMPtr<nsIChannel> theChannel;
79 nsCOMPtr<nsIURI> theURI;
80 rv = NS_NewURI(getter_AddRefs(theURI), theSpec);
83 rv = NS_OpenURI(getter_AddRefs(theChannel), theURI, nsnull, theLoadGroup);
86 nsCOMPtr<nsILoadGroup> theLoadGroup(do_CreateInstance(NS_LOADGROUP_CONTRACTID));
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
)
124 nsHTMLURIRefObject::Reset()
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:
142 nsCOMPtr
<nsIDOMElement
> element (do_QueryInterface(mNode
));
143 NS_ENSURE_TRUE(element
, NS_ERROR_INVALID_ARG
);
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
);
155 printf("Looking at tag '%s'\n",
156 NS_LossyConvertUTF16toASCII(tagName
).get());
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
);
169 rv
= curAttrNode
->GetName(curAttr
);
170 NS_ENSURE_SUCCESS(rv
, rv
);
172 // href >> A, AREA, BASE, LINK
174 printf("Trying to match attribute '%s'\n",
175 NS_LossyConvertUTF16toASCII(curAttr
).get());
177 if (MATCHES(curAttr
, "href"))
179 if (!MATCHES(tagName
, "a") && !MATCHES(tagName
, "area")
180 && !MATCHES(tagName
, "base") && !MATCHES(tagName
, "link"))
182 rv
= curAttrNode
->GetValue(aURI
);
183 NS_ENSURE_SUCCESS(rv
, rv
);
185 // href pointing to a named anchor doesn't count
186 if (aURI
.First() != PRUnichar('#'))
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"))
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"))
206 // longdesc >> FRAME, IFRAME, IMG
207 else if (MATCHES(curAttr
, "longdesc"))
209 if (!MATCHES(tagName
, "img")
210 && !MATCHES(tagName
, "frame") && !MATCHES(tagName
, "iframe"))
213 // usemap >> IMG, INPUT, OBJECT
214 else if (MATCHES(curAttr
, "usemap"))
216 if (!MATCHES(tagName
, "img")
217 && !MATCHES(tagName
, "input") && !MATCHES(tagName
, "object"))
221 else if (MATCHES(curAttr
, "action"))
223 if (!MATCHES(tagName
, "form"))
226 // background >> BODY
227 else if (MATCHES(curAttr
, "background"))
229 if (!MATCHES(tagName
, "body"))
232 // codebase >> OBJECT, APPLET
233 else if (MATCHES(curAttr
, "codebase"))
235 if (!MATCHES(tagName
, "meta"))
239 else if (MATCHES(curAttr
, "classid"))
241 if (!MATCHES(tagName
, "object"))
245 else if (MATCHES(curAttr
, "data"))
247 if (!MATCHES(tagName
, "object"))
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"))
258 else if (MATCHES(curAttr
, "profile"))
260 if (!MATCHES(tagName
, "head"))
263 // archive attribute on APPLET; warning, it contains a list of URIs.
264 else if (MATCHES(curAttr
, "archive"))
266 if (!MATCHES(tagName
, "applet"))
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
;
276 nsHTMLURIRefObject::RewriteAllURIs(const nsAString
& aOldPat
,
277 const nsAString
& aNewPat
,
281 printf("Can't rewrite URIs yet\n");
283 return NS_ERROR_NOT_IMPLEMENTED
;
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();
297 nsHTMLURIRefObject::SetNode(nsIDOMNode
*aNode
)
300 nsAutoString dummyURI
;
301 if (NS_SUCCEEDED(GetNextURI(dummyURI
)))
303 mCurAttrIndex
= 0; // Reset so we'll get the first node next time
307 // If there weren't any URIs in the attributes,
308 // then don't accept this node.
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
);
323 return refObject
->QueryInterface(NS_GET_IID(nsIURIRefObject
),