diff -r 000000000000 -r 6474c204b198 editor/libeditor/html/nsHTMLURIRefObject.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/editor/libeditor/html/nsHTMLURIRefObject.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,295 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Here is the list, from beppe and glazman: + href >> A, AREA, BASE, LINK + src >> FRAME, IFRAME, IMG, INPUT, SCRIPT + + longdesc >> FRAME, IFRAME, IMG + usemap >> IMG, INPUT, OBJECT + action >> FORM + background >> BODY + codebase >> OBJECT, APPLET + classid >> OBJECT + data >> OBJECT + cite >> BLOCKQUOTE, DEL, INS, Q + profile >> HEAD + ARCHIVE attribute on APPLET ; warning, it contains a list of URIs. + + Easier way of organizing the list: + a: href + area: href + base: href + body: background + blockquote: cite (not normally rewritable) + link: href + frame: src, longdesc + iframe: src, longdesc + input: src, usemap + form: action + img: src, longdesc, usemap + script: src + applet: codebase, archive + object: codebase, data, classid, usemap + head: profile + del: cite + ins: cite + q: cite + */ + +/* Here is how to open a channel for testing + (from embed/qa/testembed/Tests.cpp): + + nsCOMPtr theChannel; + nsCString uri; + nsCOMPtr theURI; + rv = NS_NewURI(getter_AddRefs(theURI), theSpec); + if (!theURI) + error; + rv = NS_OpenURI(getter_AddRefs(theChannel), theURI, nullptr, theLoadGroup); + if (!theChannel) + error; + nsCOMPtr theLoadGroup(do_CreateInstance(NS_LOADGROUP_CONTRACTID)); + if (!theLoadGroup) + error; + nsCOMPtr listener(static_cast(qaBrowserImpl)); + //nsCOMPtr thisListener(do_GetWeakReference(listener)); + //qaWebBrowser->AddWebBrowserListener(thisListener, NS_GET_IID(nsIStreamListener)); + + // this calls nsIStreamListener::OnDataAvailable() + rv = theChannel->AsyncOpen(listener, nullptr); + + nsCOMPtr theRequest = do_QueryInterface(theChannel); + // Now we can do things on nsIRequest (like what?) + */ + +#include "mozilla/mozalloc.h" +#include "nsAString.h" +#include "nsDebug.h" +#include "nsError.h" +#include "nsHTMLURIRefObject.h" +#include "nsID.h" +#include "nsIDOMAttr.h" +#include "nsIDOMElement.h" +#include "nsIDOMMozNamedAttrMap.h" +#include "nsIDOMNode.h" +#include "nsISupportsUtils.h" +#include "nsString.h" + +// String classes change too often and I can't keep up. +// Set this macro to this week's approved case-insensitive compare routine. +#define MATCHES(tagName, str) tagName.EqualsIgnoreCase(str) + +nsHTMLURIRefObject::nsHTMLURIRefObject() +{ + mCurAttrIndex = mAttributeCnt = 0; +} + +nsHTMLURIRefObject::~nsHTMLURIRefObject() +{ +} + +//Interfaces for addref and release and queryinterface +NS_IMPL_ISUPPORTS(nsHTMLURIRefObject, nsIURIRefObject) + +NS_IMETHODIMP +nsHTMLURIRefObject::Reset() +{ + mCurAttrIndex = 0; + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLURIRefObject::GetNextURI(nsAString & aURI) +{ + NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED); + + nsAutoString tagName; + nsresult rv = mNode->GetNodeName(tagName); + NS_ENSURE_SUCCESS(rv, rv); + + // Loop over attribute list: + if (!mAttributes) + { + nsCOMPtr element (do_QueryInterface(mNode)); + NS_ENSURE_TRUE(element, NS_ERROR_INVALID_ARG); + + mCurAttrIndex = 0; + element->GetAttributes(getter_AddRefs(mAttributes)); + NS_ENSURE_TRUE(mAttributes, NS_ERROR_NOT_INITIALIZED); + + rv = mAttributes->GetLength(&mAttributeCnt); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(mAttributeCnt, NS_ERROR_FAILURE); + mCurAttrIndex = 0; + } +#ifdef DEBUG_akkana + printf("Looking at tag '%s'\n", + NS_LossyConvertUTF16toASCII(tagName).get()); +#endif + while (mCurAttrIndex < mAttributeCnt) + { + nsCOMPtr attrNode; + rv = mAttributes->Item(mCurAttrIndex++, getter_AddRefs(attrNode)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_ARG_POINTER(attrNode); + nsString curAttr; + rv = attrNode->GetName(curAttr); + NS_ENSURE_SUCCESS(rv, rv); + + // href >> A, AREA, BASE, LINK +#ifdef DEBUG_akkana + printf("Trying to match attribute '%s'\n", + NS_LossyConvertUTF16toASCII(curAttr).get()); +#endif + if (MATCHES(curAttr, "href")) + { + if (!MATCHES(tagName, "a") && !MATCHES(tagName, "area") + && !MATCHES(tagName, "base") && !MATCHES(tagName, "link")) + continue; + rv = attrNode->GetValue(aURI); + NS_ENSURE_SUCCESS(rv, rv); + nsString uri (aURI); + // href pointing to a named anchor doesn't count + if (aURI.First() != char16_t('#')) + return NS_OK; + aURI.Truncate(); + return NS_ERROR_INVALID_ARG; + } + // src >> FRAME, IFRAME, IMG, INPUT, SCRIPT + else if (MATCHES(curAttr, "src")) + { + if (!MATCHES(tagName, "img") + && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe") + && !MATCHES(tagName, "input") && !MATCHES(tagName, "script")) + continue; + return attrNode->GetValue(aURI); + } + // + else if (MATCHES(curAttr, "content")) + { + if (!MATCHES(tagName, "meta")) + continue; + } + // longdesc >> FRAME, IFRAME, IMG + else if (MATCHES(curAttr, "longdesc")) + { + if (!MATCHES(tagName, "img") + && !MATCHES(tagName, "frame") && !MATCHES(tagName, "iframe")) + continue; + } + // usemap >> IMG, INPUT, OBJECT + else if (MATCHES(curAttr, "usemap")) + { + if (!MATCHES(tagName, "img") + && !MATCHES(tagName, "input") && !MATCHES(tagName, "object")) + continue; + } + // action >> FORM + else if (MATCHES(curAttr, "action")) + { + if (!MATCHES(tagName, "form")) + continue; + } + // background >> BODY + else if (MATCHES(curAttr, "background")) + { + if (!MATCHES(tagName, "body")) + continue; + } + // codebase >> OBJECT, APPLET + else if (MATCHES(curAttr, "codebase")) + { + if (!MATCHES(tagName, "meta")) + continue; + } + // classid >> OBJECT + else if (MATCHES(curAttr, "classid")) + { + if (!MATCHES(tagName, "object")) + continue; + } + // data >> OBJECT + else if (MATCHES(curAttr, "data")) + { + if (!MATCHES(tagName, "object")) + continue; + } + // cite >> BLOCKQUOTE, DEL, INS, Q + else if (MATCHES(curAttr, "cite")) + { + if (!MATCHES(tagName, "blockquote") && !MATCHES(tagName, "q") + && !MATCHES(tagName, "del") && !MATCHES(tagName, "ins")) + continue; + } + // profile >> HEAD + else if (MATCHES(curAttr, "profile")) + { + if (!MATCHES(tagName, "head")) + continue; + } + // archive attribute on APPLET; warning, it contains a list of URIs. + else if (MATCHES(curAttr, "archive")) + { + if (!MATCHES(tagName, "applet")) + continue; + } + } + // Return a code to indicate that there are no more, + // to distinguish that case from real errors. + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +nsHTMLURIRefObject::RewriteAllURIs(const nsAString & aOldPat, + const nsAString & aNewPat, + bool aMakeRel) +{ +#ifdef DEBUG_akkana + printf("Can't rewrite URIs yet\n"); +#endif + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsHTMLURIRefObject::GetNode(nsIDOMNode** aNode) +{ + NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED); + NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER); + *aNode = mNode.get(); + NS_ADDREF(*aNode); + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLURIRefObject::SetNode(nsIDOMNode *aNode) +{ + mNode = aNode; + nsAutoString dummyURI; + if (NS_SUCCEEDED(GetNextURI(dummyURI))) + { + mCurAttrIndex = 0; // Reset so we'll get the first node next time + return NS_OK; + } + + // If there weren't any URIs in the attributes, + // then don't accept this node. + mNode = 0; + return NS_ERROR_INVALID_ARG; +} + +nsresult NS_NewHTMLURIRefObject(nsIURIRefObject** aResult, nsIDOMNode* aNode) +{ + nsHTMLURIRefObject* refObject = new nsHTMLURIRefObject(); + nsresult rv = refObject->SetNode(aNode); + if (NS_FAILED(rv)) { + *aResult = 0; + delete refObject; + return rv; + } + return refObject->QueryInterface(NS_GET_IID(nsIURIRefObject), + (void**)aResult); +} +