1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/editor/libeditor/html/nsHTMLURIRefObject.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,295 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* Here is the list, from beppe and glazman: 1.10 + href >> A, AREA, BASE, LINK 1.11 + src >> FRAME, IFRAME, IMG, INPUT, SCRIPT 1.12 + <META http-equiv="refresh" content="3,http://www.acme.com/intro.html"> 1.13 + longdesc >> FRAME, IFRAME, IMG 1.14 + usemap >> IMG, INPUT, OBJECT 1.15 + action >> FORM 1.16 + background >> BODY 1.17 + codebase >> OBJECT, APPLET 1.18 + classid >> OBJECT 1.19 + data >> OBJECT 1.20 + cite >> BLOCKQUOTE, DEL, INS, Q 1.21 + profile >> HEAD 1.22 + ARCHIVE attribute on APPLET ; warning, it contains a list of URIs. 1.23 + 1.24 + Easier way of organizing the list: 1.25 + a: href 1.26 + area: href 1.27 + base: href 1.28 + body: background 1.29 + blockquote: cite (not normally rewritable) 1.30 + link: href 1.31 + frame: src, longdesc 1.32 + iframe: src, longdesc 1.33 + input: src, usemap 1.34 + form: action 1.35 + img: src, longdesc, usemap 1.36 + script: src 1.37 + applet: codebase, archive <list> 1.38 + object: codebase, data, classid, usemap 1.39 + head: profile 1.40 + del: cite 1.41 + ins: cite 1.42 + q: cite 1.43 + */ 1.44 + 1.45 +/* Here is how to open a channel for testing 1.46 + (from embed/qa/testembed/Tests.cpp): 1.47 + 1.48 + nsCOMPtr<nsIChannel> theChannel; 1.49 + nsCString uri; 1.50 + nsCOMPtr<nsIURI> theURI; 1.51 + rv = NS_NewURI(getter_AddRefs(theURI), theSpec); 1.52 + if (!theURI) 1.53 + error; 1.54 + rv = NS_OpenURI(getter_AddRefs(theChannel), theURI, nullptr, theLoadGroup); 1.55 + if (!theChannel) 1.56 + error; 1.57 + nsCOMPtr<nsILoadGroup> theLoadGroup(do_CreateInstance(NS_LOADGROUP_CONTRACTID)); 1.58 + if (!theLoadGroup) 1.59 + error; 1.60 + nsCOMPtr<nsIStreamListener> listener(static_cast<nsIStreamListener*>(qaBrowserImpl)); 1.61 + //nsCOMPtr<nsIWeakReference> thisListener(do_GetWeakReference(listener)); 1.62 + //qaWebBrowser->AddWebBrowserListener(thisListener, NS_GET_IID(nsIStreamListener)); 1.63 + 1.64 + // this calls nsIStreamListener::OnDataAvailable() 1.65 + rv = theChannel->AsyncOpen(listener, nullptr); 1.66 + 1.67 + nsCOMPtr<nsIRequest> theRequest = do_QueryInterface(theChannel); 1.68 + // Now we can do things on nsIRequest (like what?) 1.69 + */ 1.70 + 1.71 +#include "mozilla/mozalloc.h" 1.72 +#include "nsAString.h" 1.73 +#include "nsDebug.h" 1.74 +#include "nsError.h" 1.75 +#include "nsHTMLURIRefObject.h" 1.76 +#include "nsID.h" 1.77 +#include "nsIDOMAttr.h" 1.78 +#include "nsIDOMElement.h" 1.79 +#include "nsIDOMMozNamedAttrMap.h" 1.80 +#include "nsIDOMNode.h" 1.81 +#include "nsISupportsUtils.h" 1.82 +#include "nsString.h" 1.83 + 1.84 +// String classes change too often and I can't keep up. 1.85 +// Set this macro to this week's approved case-insensitive compare routine. 1.86 +#define MATCHES(tagName, str) tagName.EqualsIgnoreCase(str) 1.87 + 1.88 +nsHTMLURIRefObject::nsHTMLURIRefObject() 1.89 +{ 1.90 + mCurAttrIndex = mAttributeCnt = 0; 1.91 +} 1.92 + 1.93 +nsHTMLURIRefObject::~nsHTMLURIRefObject() 1.94 +{ 1.95 +} 1.96 + 1.97 +//Interfaces for addref and release and queryinterface 1.98 +NS_IMPL_ISUPPORTS(nsHTMLURIRefObject, nsIURIRefObject) 1.99 + 1.100 +NS_IMETHODIMP 1.101 +nsHTMLURIRefObject::Reset() 1.102 +{ 1.103 + mCurAttrIndex = 0; 1.104 + return NS_OK; 1.105 +} 1.106 + 1.107 +NS_IMETHODIMP 1.108 +nsHTMLURIRefObject::GetNextURI(nsAString & aURI) 1.109 +{ 1.110 + NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED); 1.111 + 1.112 + nsAutoString tagName; 1.113 + nsresult rv = mNode->GetNodeName(tagName); 1.114 + NS_ENSURE_SUCCESS(rv, rv); 1.115 + 1.116 + // Loop over attribute list: 1.117 + if (!mAttributes) 1.118 + { 1.119 + nsCOMPtr<nsIDOMElement> element (do_QueryInterface(mNode)); 1.120 + NS_ENSURE_TRUE(element, NS_ERROR_INVALID_ARG); 1.121 + 1.122 + mCurAttrIndex = 0; 1.123 + element->GetAttributes(getter_AddRefs(mAttributes)); 1.124 + NS_ENSURE_TRUE(mAttributes, NS_ERROR_NOT_INITIALIZED); 1.125 + 1.126 + rv = mAttributes->GetLength(&mAttributeCnt); 1.127 + NS_ENSURE_SUCCESS(rv, rv); 1.128 + NS_ENSURE_TRUE(mAttributeCnt, NS_ERROR_FAILURE); 1.129 + mCurAttrIndex = 0; 1.130 + } 1.131 +#ifdef DEBUG_akkana 1.132 + printf("Looking at tag '%s'\n", 1.133 + NS_LossyConvertUTF16toASCII(tagName).get()); 1.134 +#endif 1.135 + while (mCurAttrIndex < mAttributeCnt) 1.136 + { 1.137 + nsCOMPtr<nsIDOMAttr> attrNode; 1.138 + rv = mAttributes->Item(mCurAttrIndex++, getter_AddRefs(attrNode)); 1.139 + NS_ENSURE_SUCCESS(rv, rv); 1.140 + NS_ENSURE_ARG_POINTER(attrNode); 1.141 + nsString curAttr; 1.142 + rv = attrNode->GetName(curAttr); 1.143 + NS_ENSURE_SUCCESS(rv, rv); 1.144 + 1.145 + // href >> A, AREA, BASE, LINK 1.146 +#ifdef DEBUG_akkana 1.147 + printf("Trying to match attribute '%s'\n", 1.148 + NS_LossyConvertUTF16toASCII(curAttr).get()); 1.149 +#endif 1.150 + if (MATCHES(curAttr, "href")) 1.151 + { 1.152 + if (!MATCHES(tagName, "a") && !MATCHES(tagName, "area") 1.153 + && !MATCHES(tagName, "base") && !MATCHES(tagName, "link")) 1.154 + continue; 1.155 + rv = attrNode->GetValue(aURI); 1.156 + NS_ENSURE_SUCCESS(rv, rv); 1.157 + nsString uri (aURI); 1.158 + // href pointing to a named anchor doesn't count 1.159 + if (aURI.First() != char16_t('#')) 1.160 + return NS_OK; 1.161 + aURI.Truncate(); 1.162 + return NS_ERROR_INVALID_ARG; 1.163 + } 1.164 + // src >> FRAME, IFRAME, IMG, INPUT, SCRIPT 1.165 + else if (MATCHES(curAttr, "src")) 1.166 + { 1.167 + if (!MATCHES(tagName, "img") 1.168 + && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe") 1.169 + && !MATCHES(tagName, "input") && !MATCHES(tagName, "script")) 1.170 + continue; 1.171 + return attrNode->GetValue(aURI); 1.172 + } 1.173 + //<META http-equiv="refresh" content="3,http://www.acme.com/intro.html"> 1.174 + else if (MATCHES(curAttr, "content")) 1.175 + { 1.176 + if (!MATCHES(tagName, "meta")) 1.177 + continue; 1.178 + } 1.179 + // longdesc >> FRAME, IFRAME, IMG 1.180 + else if (MATCHES(curAttr, "longdesc")) 1.181 + { 1.182 + if (!MATCHES(tagName, "img") 1.183 + && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe")) 1.184 + continue; 1.185 + } 1.186 + // usemap >> IMG, INPUT, OBJECT 1.187 + else if (MATCHES(curAttr, "usemap")) 1.188 + { 1.189 + if (!MATCHES(tagName, "img") 1.190 + && !MATCHES(tagName, "input") && !MATCHES(tagName, "object")) 1.191 + continue; 1.192 + } 1.193 + // action >> FORM 1.194 + else if (MATCHES(curAttr, "action")) 1.195 + { 1.196 + if (!MATCHES(tagName, "form")) 1.197 + continue; 1.198 + } 1.199 + // background >> BODY 1.200 + else if (MATCHES(curAttr, "background")) 1.201 + { 1.202 + if (!MATCHES(tagName, "body")) 1.203 + continue; 1.204 + } 1.205 + // codebase >> OBJECT, APPLET 1.206 + else if (MATCHES(curAttr, "codebase")) 1.207 + { 1.208 + if (!MATCHES(tagName, "meta")) 1.209 + continue; 1.210 + } 1.211 + // classid >> OBJECT 1.212 + else if (MATCHES(curAttr, "classid")) 1.213 + { 1.214 + if (!MATCHES(tagName, "object")) 1.215 + continue; 1.216 + } 1.217 + // data >> OBJECT 1.218 + else if (MATCHES(curAttr, "data")) 1.219 + { 1.220 + if (!MATCHES(tagName, "object")) 1.221 + continue; 1.222 + } 1.223 + // cite >> BLOCKQUOTE, DEL, INS, Q 1.224 + else if (MATCHES(curAttr, "cite")) 1.225 + { 1.226 + if (!MATCHES(tagName, "blockquote") && !MATCHES(tagName, "q") 1.227 + && !MATCHES(tagName, "del") && !MATCHES(tagName, "ins")) 1.228 + continue; 1.229 + } 1.230 + // profile >> HEAD 1.231 + else if (MATCHES(curAttr, "profile")) 1.232 + { 1.233 + if (!MATCHES(tagName, "head")) 1.234 + continue; 1.235 + } 1.236 + // archive attribute on APPLET; warning, it contains a list of URIs. 1.237 + else if (MATCHES(curAttr, "archive")) 1.238 + { 1.239 + if (!MATCHES(tagName, "applet")) 1.240 + continue; 1.241 + } 1.242 + } 1.243 + // Return a code to indicate that there are no more, 1.244 + // to distinguish that case from real errors. 1.245 + return NS_ERROR_NOT_AVAILABLE; 1.246 +} 1.247 + 1.248 +NS_IMETHODIMP 1.249 +nsHTMLURIRefObject::RewriteAllURIs(const nsAString & aOldPat, 1.250 + const nsAString & aNewPat, 1.251 + bool aMakeRel) 1.252 +{ 1.253 +#ifdef DEBUG_akkana 1.254 + printf("Can't rewrite URIs yet\n"); 1.255 +#endif 1.256 + return NS_ERROR_NOT_IMPLEMENTED; 1.257 +} 1.258 + 1.259 +NS_IMETHODIMP 1.260 +nsHTMLURIRefObject::GetNode(nsIDOMNode** aNode) 1.261 +{ 1.262 + NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED); 1.263 + NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER); 1.264 + *aNode = mNode.get(); 1.265 + NS_ADDREF(*aNode); 1.266 + return NS_OK; 1.267 +} 1.268 + 1.269 +NS_IMETHODIMP 1.270 +nsHTMLURIRefObject::SetNode(nsIDOMNode *aNode) 1.271 +{ 1.272 + mNode = aNode; 1.273 + nsAutoString dummyURI; 1.274 + if (NS_SUCCEEDED(GetNextURI(dummyURI))) 1.275 + { 1.276 + mCurAttrIndex = 0; // Reset so we'll get the first node next time 1.277 + return NS_OK; 1.278 + } 1.279 + 1.280 + // If there weren't any URIs in the attributes, 1.281 + // then don't accept this node. 1.282 + mNode = 0; 1.283 + return NS_ERROR_INVALID_ARG; 1.284 +} 1.285 + 1.286 +nsresult NS_NewHTMLURIRefObject(nsIURIRefObject** aResult, nsIDOMNode* aNode) 1.287 +{ 1.288 + nsHTMLURIRefObject* refObject = new nsHTMLURIRefObject(); 1.289 + nsresult rv = refObject->SetNode(aNode); 1.290 + if (NS_FAILED(rv)) { 1.291 + *aResult = 0; 1.292 + delete refObject; 1.293 + return rv; 1.294 + } 1.295 + return refObject->QueryInterface(NS_GET_IID(nsIURIRefObject), 1.296 + (void**)aResult); 1.297 +} 1.298 +