Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* Here is the list, from beppe and glazman:
7 href >> A, AREA, BASE, LINK
8 src >> FRAME, IFRAME, IMG, INPUT, SCRIPT
9 <META http-equiv="refresh" content="3,http://www.acme.com/intro.html">
10 longdesc >> FRAME, IFRAME, IMG
11 usemap >> IMG, INPUT, OBJECT
12 action >> FORM
13 background >> BODY
14 codebase >> OBJECT, APPLET
15 classid >> OBJECT
16 data >> OBJECT
17 cite >> BLOCKQUOTE, DEL, INS, Q
18 profile >> HEAD
19 ARCHIVE attribute on APPLET ; warning, it contains a list of URIs.
21 Easier way of organizing the list:
22 a: href
23 area: href
24 base: href
25 body: background
26 blockquote: cite (not normally rewritable)
27 link: href
28 frame: src, longdesc
29 iframe: src, longdesc
30 input: src, usemap
31 form: action
32 img: src, longdesc, usemap
33 script: src
34 applet: codebase, archive <list>
35 object: codebase, data, classid, usemap
36 head: profile
37 del: cite
38 ins: cite
39 q: cite
40 */
42 /* Here is how to open a channel for testing
43 (from embed/qa/testembed/Tests.cpp):
45 nsCOMPtr<nsIChannel> theChannel;
46 nsCString uri;
47 nsCOMPtr<nsIURI> theURI;
48 rv = NS_NewURI(getter_AddRefs(theURI), theSpec);
49 if (!theURI)
50 error;
51 rv = NS_OpenURI(getter_AddRefs(theChannel), theURI, nullptr, theLoadGroup);
52 if (!theChannel)
53 error;
54 nsCOMPtr<nsILoadGroup> theLoadGroup(do_CreateInstance(NS_LOADGROUP_CONTRACTID));
55 if (!theLoadGroup)
56 error;
57 nsCOMPtr<nsIStreamListener> listener(static_cast<nsIStreamListener*>(qaBrowserImpl));
58 //nsCOMPtr<nsIWeakReference> thisListener(do_GetWeakReference(listener));
59 //qaWebBrowser->AddWebBrowserListener(thisListener, NS_GET_IID(nsIStreamListener));
61 // this calls nsIStreamListener::OnDataAvailable()
62 rv = theChannel->AsyncOpen(listener, nullptr);
64 nsCOMPtr<nsIRequest> theRequest = do_QueryInterface(theChannel);
65 // Now we can do things on nsIRequest (like what?)
66 */
68 #include "mozilla/mozalloc.h"
69 #include "nsAString.h"
70 #include "nsDebug.h"
71 #include "nsError.h"
72 #include "nsHTMLURIRefObject.h"
73 #include "nsID.h"
74 #include "nsIDOMAttr.h"
75 #include "nsIDOMElement.h"
76 #include "nsIDOMMozNamedAttrMap.h"
77 #include "nsIDOMNode.h"
78 #include "nsISupportsUtils.h"
79 #include "nsString.h"
81 // String classes change too often and I can't keep up.
82 // Set this macro to this week's approved case-insensitive compare routine.
83 #define MATCHES(tagName, str) tagName.EqualsIgnoreCase(str)
85 nsHTMLURIRefObject::nsHTMLURIRefObject()
86 {
87 mCurAttrIndex = mAttributeCnt = 0;
88 }
90 nsHTMLURIRefObject::~nsHTMLURIRefObject()
91 {
92 }
94 //Interfaces for addref and release and queryinterface
95 NS_IMPL_ISUPPORTS(nsHTMLURIRefObject, nsIURIRefObject)
97 NS_IMETHODIMP
98 nsHTMLURIRefObject::Reset()
99 {
100 mCurAttrIndex = 0;
101 return NS_OK;
102 }
104 NS_IMETHODIMP
105 nsHTMLURIRefObject::GetNextURI(nsAString & aURI)
106 {
107 NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED);
109 nsAutoString tagName;
110 nsresult rv = mNode->GetNodeName(tagName);
111 NS_ENSURE_SUCCESS(rv, rv);
113 // Loop over attribute list:
114 if (!mAttributes)
115 {
116 nsCOMPtr<nsIDOMElement> element (do_QueryInterface(mNode));
117 NS_ENSURE_TRUE(element, NS_ERROR_INVALID_ARG);
119 mCurAttrIndex = 0;
120 element->GetAttributes(getter_AddRefs(mAttributes));
121 NS_ENSURE_TRUE(mAttributes, NS_ERROR_NOT_INITIALIZED);
123 rv = mAttributes->GetLength(&mAttributeCnt);
124 NS_ENSURE_SUCCESS(rv, rv);
125 NS_ENSURE_TRUE(mAttributeCnt, NS_ERROR_FAILURE);
126 mCurAttrIndex = 0;
127 }
128 #ifdef DEBUG_akkana
129 printf("Looking at tag '%s'\n",
130 NS_LossyConvertUTF16toASCII(tagName).get());
131 #endif
132 while (mCurAttrIndex < mAttributeCnt)
133 {
134 nsCOMPtr<nsIDOMAttr> attrNode;
135 rv = mAttributes->Item(mCurAttrIndex++, getter_AddRefs(attrNode));
136 NS_ENSURE_SUCCESS(rv, rv);
137 NS_ENSURE_ARG_POINTER(attrNode);
138 nsString curAttr;
139 rv = attrNode->GetName(curAttr);
140 NS_ENSURE_SUCCESS(rv, rv);
142 // href >> A, AREA, BASE, LINK
143 #ifdef DEBUG_akkana
144 printf("Trying to match attribute '%s'\n",
145 NS_LossyConvertUTF16toASCII(curAttr).get());
146 #endif
147 if (MATCHES(curAttr, "href"))
148 {
149 if (!MATCHES(tagName, "a") && !MATCHES(tagName, "area")
150 && !MATCHES(tagName, "base") && !MATCHES(tagName, "link"))
151 continue;
152 rv = attrNode->GetValue(aURI);
153 NS_ENSURE_SUCCESS(rv, rv);
154 nsString uri (aURI);
155 // href pointing to a named anchor doesn't count
156 if (aURI.First() != char16_t('#'))
157 return NS_OK;
158 aURI.Truncate();
159 return NS_ERROR_INVALID_ARG;
160 }
161 // src >> FRAME, IFRAME, IMG, INPUT, SCRIPT
162 else if (MATCHES(curAttr, "src"))
163 {
164 if (!MATCHES(tagName, "img")
165 && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe")
166 && !MATCHES(tagName, "input") && !MATCHES(tagName, "script"))
167 continue;
168 return attrNode->GetValue(aURI);
169 }
170 //<META http-equiv="refresh" content="3,http://www.acme.com/intro.html">
171 else if (MATCHES(curAttr, "content"))
172 {
173 if (!MATCHES(tagName, "meta"))
174 continue;
175 }
176 // longdesc >> FRAME, IFRAME, IMG
177 else if (MATCHES(curAttr, "longdesc"))
178 {
179 if (!MATCHES(tagName, "img")
180 && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe"))
181 continue;
182 }
183 // usemap >> IMG, INPUT, OBJECT
184 else if (MATCHES(curAttr, "usemap"))
185 {
186 if (!MATCHES(tagName, "img")
187 && !MATCHES(tagName, "input") && !MATCHES(tagName, "object"))
188 continue;
189 }
190 // action >> FORM
191 else if (MATCHES(curAttr, "action"))
192 {
193 if (!MATCHES(tagName, "form"))
194 continue;
195 }
196 // background >> BODY
197 else if (MATCHES(curAttr, "background"))
198 {
199 if (!MATCHES(tagName, "body"))
200 continue;
201 }
202 // codebase >> OBJECT, APPLET
203 else if (MATCHES(curAttr, "codebase"))
204 {
205 if (!MATCHES(tagName, "meta"))
206 continue;
207 }
208 // classid >> OBJECT
209 else if (MATCHES(curAttr, "classid"))
210 {
211 if (!MATCHES(tagName, "object"))
212 continue;
213 }
214 // data >> OBJECT
215 else if (MATCHES(curAttr, "data"))
216 {
217 if (!MATCHES(tagName, "object"))
218 continue;
219 }
220 // cite >> BLOCKQUOTE, DEL, INS, Q
221 else if (MATCHES(curAttr, "cite"))
222 {
223 if (!MATCHES(tagName, "blockquote") && !MATCHES(tagName, "q")
224 && !MATCHES(tagName, "del") && !MATCHES(tagName, "ins"))
225 continue;
226 }
227 // profile >> HEAD
228 else if (MATCHES(curAttr, "profile"))
229 {
230 if (!MATCHES(tagName, "head"))
231 continue;
232 }
233 // archive attribute on APPLET; warning, it contains a list of URIs.
234 else if (MATCHES(curAttr, "archive"))
235 {
236 if (!MATCHES(tagName, "applet"))
237 continue;
238 }
239 }
240 // Return a code to indicate that there are no more,
241 // to distinguish that case from real errors.
242 return NS_ERROR_NOT_AVAILABLE;
243 }
245 NS_IMETHODIMP
246 nsHTMLURIRefObject::RewriteAllURIs(const nsAString & aOldPat,
247 const nsAString & aNewPat,
248 bool aMakeRel)
249 {
250 #ifdef DEBUG_akkana
251 printf("Can't rewrite URIs yet\n");
252 #endif
253 return NS_ERROR_NOT_IMPLEMENTED;
254 }
256 NS_IMETHODIMP
257 nsHTMLURIRefObject::GetNode(nsIDOMNode** aNode)
258 {
259 NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED);
260 NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
261 *aNode = mNode.get();
262 NS_ADDREF(*aNode);
263 return NS_OK;
264 }
266 NS_IMETHODIMP
267 nsHTMLURIRefObject::SetNode(nsIDOMNode *aNode)
268 {
269 mNode = aNode;
270 nsAutoString dummyURI;
271 if (NS_SUCCEEDED(GetNextURI(dummyURI)))
272 {
273 mCurAttrIndex = 0; // Reset so we'll get the first node next time
274 return NS_OK;
275 }
277 // If there weren't any URIs in the attributes,
278 // then don't accept this node.
279 mNode = 0;
280 return NS_ERROR_INVALID_ARG;
281 }
283 nsresult NS_NewHTMLURIRefObject(nsIURIRefObject** aResult, nsIDOMNode* aNode)
284 {
285 nsHTMLURIRefObject* refObject = new nsHTMLURIRefObject();
286 nsresult rv = refObject->SetNode(aNode);
287 if (NS_FAILED(rv)) {
288 *aResult = 0;
289 delete refObject;
290 return rv;
291 }
292 return refObject->QueryInterface(NS_GET_IID(nsIURIRefObject),
293 (void**)aResult);
294 }