editor/libeditor/html/nsHTMLURIRefObject.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

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

mercurial