|
Packit |
f0b94e |
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
Packit |
f0b94e |
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit |
f0b94e |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit |
f0b94e |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/* Here is the list, from beppe and glazman:
|
|
Packit |
f0b94e |
href >> A, AREA, BASE, LINK
|
|
Packit |
f0b94e |
src >> FRAME, IFRAME, IMG, INPUT, SCRIPT
|
|
Packit |
f0b94e |
<META http-equiv="refresh" content="3,http://www.acme.com/intro.html">
|
|
Packit |
f0b94e |
longdesc >> FRAME, IFRAME, IMG
|
|
Packit |
f0b94e |
usemap >> IMG, INPUT, OBJECT
|
|
Packit |
f0b94e |
action >> FORM
|
|
Packit |
f0b94e |
background >> BODY
|
|
Packit |
f0b94e |
codebase >> OBJECT, APPLET
|
|
Packit |
f0b94e |
classid >> OBJECT
|
|
Packit |
f0b94e |
data >> OBJECT
|
|
Packit |
f0b94e |
cite >> BLOCKQUOTE, DEL, INS, Q
|
|
Packit |
f0b94e |
profile >> HEAD
|
|
Packit |
f0b94e |
ARCHIVE attribute on APPLET ; warning, it contains a list of URIs.
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
Easier way of organizing the list:
|
|
Packit |
f0b94e |
a: href
|
|
Packit |
f0b94e |
area: href
|
|
Packit |
f0b94e |
base: href
|
|
Packit |
f0b94e |
body: background
|
|
Packit |
f0b94e |
blockquote: cite (not normally rewritable)
|
|
Packit |
f0b94e |
link: href
|
|
Packit |
f0b94e |
frame: src, longdesc
|
|
Packit |
f0b94e |
iframe: src, longdesc
|
|
Packit |
f0b94e |
input: src, usemap
|
|
Packit |
f0b94e |
form: action
|
|
Packit |
f0b94e |
img: src, longdesc, usemap
|
|
Packit |
f0b94e |
script: src
|
|
Packit |
f0b94e |
applet: codebase, archive <list>
|
|
Packit |
f0b94e |
object: codebase, data, classid, usemap
|
|
Packit |
f0b94e |
head: profile
|
|
Packit |
f0b94e |
del: cite
|
|
Packit |
f0b94e |
ins: cite
|
|
Packit |
f0b94e |
q: cite
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "HTMLURIRefObject.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "mozilla/mozalloc.h"
|
|
Packit |
f0b94e |
#include "mozilla/dom/Attr.h"
|
|
Packit |
f0b94e |
#include "mozilla/dom/Element.h"
|
|
Packit |
f0b94e |
#include "nsAString.h"
|
|
Packit |
f0b94e |
#include "nsDebug.h"
|
|
Packit |
f0b94e |
#include "nsDOMAttributeMap.h"
|
|
Packit |
f0b94e |
#include "nsError.h"
|
|
Packit |
f0b94e |
#include "nsID.h"
|
|
Packit |
f0b94e |
#include "nsIDOMElement.h"
|
|
Packit |
f0b94e |
#include "nsIDOMNode.h"
|
|
Packit |
f0b94e |
#include "nsISupportsUtils.h"
|
|
Packit |
f0b94e |
#include "nsString.h"
|
|
Packit |
f0b94e |
#include "nsGkAtoms.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
namespace mozilla {
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// String classes change too often and I can't keep up.
|
|
Packit |
f0b94e |
// Set this macro to this week's approved case-insensitive compare routine.
|
|
Packit |
f0b94e |
#define MATCHES(tagName, str) tagName.EqualsIgnoreCase(str)
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
HTMLURIRefObject::HTMLURIRefObject()
|
|
Packit |
f0b94e |
: mCurAttrIndex(0), mAttributeCnt(0), mAttrsInited(false) {}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
HTMLURIRefObject::~HTMLURIRefObject() {}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Interfaces for addref and release and queryinterface
|
|
Packit |
f0b94e |
NS_IMPL_ISUPPORTS(HTMLURIRefObject, nsIURIRefObject)
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
HTMLURIRefObject::Reset() {
|
|
Packit |
f0b94e |
mCurAttrIndex = 0;
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
HTMLURIRefObject::GetNextURI(nsAString& aURI) {
|
|
Packit |
f0b94e |
NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsCOMPtr<dom::Element> element = do_QueryInterface(mNode);
|
|
Packit |
f0b94e |
NS_ENSURE_TRUE(element, NS_ERROR_INVALID_ARG);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Loop over attribute list:
|
|
Packit |
f0b94e |
if (!mAttrsInited) {
|
|
Packit |
f0b94e |
mAttrsInited = true;
|
|
Packit |
f0b94e |
mAttributeCnt = element->GetAttrCount();
|
|
Packit |
f0b94e |
NS_ENSURE_TRUE(mAttributeCnt, NS_ERROR_FAILURE);
|
|
Packit |
f0b94e |
mCurAttrIndex = 0;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
while (mCurAttrIndex < mAttributeCnt) {
|
|
Packit |
f0b94e |
BorrowedAttrInfo attrInfo = element->GetAttrInfoAt(mCurAttrIndex++);
|
|
Packit |
f0b94e |
NS_ENSURE_ARG_POINTER(attrInfo.mName);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// href >> A, AREA, BASE, LINK
|
|
Packit |
f0b94e |
if (attrInfo.mName->Equals(nsGkAtoms::href)) {
|
|
Packit |
f0b94e |
if (!element->IsAnyOfHTMLElements(nsGkAtoms::a, nsGkAtoms::area,
|
|
Packit |
f0b94e |
nsGkAtoms::base, nsGkAtoms::link)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
attrInfo.mValue->ToString(aURI);
|
|
Packit |
f0b94e |
// href pointing to a named anchor doesn't count
|
|
Packit |
f0b94e |
if (StringBeginsWith(aURI, NS_LITERAL_STRING("#"))) {
|
|
Packit |
f0b94e |
aURI.Truncate();
|
|
Packit |
f0b94e |
return NS_ERROR_INVALID_ARG;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// src >> FRAME, IFRAME, IMG, INPUT, SCRIPT
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::src)) {
|
|
Packit |
f0b94e |
if (!element->IsAnyOfHTMLElements(nsGkAtoms::img, nsGkAtoms::frame,
|
|
Packit |
f0b94e |
nsGkAtoms::iframe, nsGkAtoms::input,
|
|
Packit |
f0b94e |
nsGkAtoms::script)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
attrInfo.mValue->ToString(aURI);
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
//<META http-equiv="refresh" content="3,http://www.acme.com/intro.html">
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::content)) {
|
|
Packit |
f0b94e |
if (!element->IsHTMLElement(nsGkAtoms::meta)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// XXXbz And if it is?
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// longdesc >> FRAME, IFRAME, IMG
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::longdesc)) {
|
|
Packit |
f0b94e |
if (!element->IsAnyOfHTMLElements(nsGkAtoms::img, nsGkAtoms::frame,
|
|
Packit |
f0b94e |
nsGkAtoms::iframe)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// XXXbz And if it is?
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// usemap >> IMG, INPUT, OBJECT
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::usemap)) {
|
|
Packit |
f0b94e |
if (!element->IsAnyOfHTMLElements(nsGkAtoms::img, nsGkAtoms::input,
|
|
Packit |
f0b94e |
nsGkAtoms::object)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// action >> FORM
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::action)) {
|
|
Packit |
f0b94e |
if (!element->IsHTMLElement(nsGkAtoms::form)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// XXXbz And if it is?
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// background >> BODY
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::background)) {
|
|
Packit |
f0b94e |
if (!element->IsHTMLElement(nsGkAtoms::body)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// XXXbz And if it is?
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// codebase >> OBJECT
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::codebase)) {
|
|
Packit |
f0b94e |
if (!element->IsHTMLElement(nsGkAtoms::object)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// XXXbz And if it is?
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// classid >> OBJECT
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::classid)) {
|
|
Packit |
f0b94e |
if (!element->IsHTMLElement(nsGkAtoms::object)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// XXXbz And if it is?
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// data >> OBJECT
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::data)) {
|
|
Packit |
f0b94e |
if (!element->IsHTMLElement(nsGkAtoms::object)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// XXXbz And if it is?
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// cite >> BLOCKQUOTE, DEL, INS, Q
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::cite)) {
|
|
Packit |
f0b94e |
if (!element->IsAnyOfHTMLElements(nsGkAtoms::blockquote, nsGkAtoms::q,
|
|
Packit |
f0b94e |
nsGkAtoms::del, nsGkAtoms::ins)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// XXXbz And if it is?
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// profile >> HEAD
|
|
Packit |
f0b94e |
else if (attrInfo.mName->Equals(nsGkAtoms::profile)) {
|
|
Packit |
f0b94e |
if (!element->IsHTMLElement(nsGkAtoms::head)) {
|
|
Packit |
f0b94e |
continue;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// XXXbz And if it is?
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// Return a code to indicate that there are no more,
|
|
Packit |
f0b94e |
// to distinguish that case from real errors.
|
|
Packit |
f0b94e |
return NS_ERROR_NOT_AVAILABLE;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
HTMLURIRefObject::RewriteAllURIs(const nsAString& aOldPat,
|
|
Packit |
f0b94e |
const nsAString& aNewPat, bool aMakeRel) {
|
|
Packit |
f0b94e |
return NS_ERROR_NOT_IMPLEMENTED;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
HTMLURIRefObject::GetNode(nsIDOMNode** aNode) {
|
|
Packit |
f0b94e |
NS_ENSURE_TRUE(mNode, NS_ERROR_NOT_INITIALIZED);
|
|
Packit |
f0b94e |
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
|
Packit |
f0b94e |
*aNode = mNode.get();
|
|
Packit |
f0b94e |
NS_ADDREF(*aNode);
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
HTMLURIRefObject::SetNode(nsIDOMNode* aNode) {
|
|
Packit |
f0b94e |
mNode = aNode;
|
|
Packit |
f0b94e |
nsAutoString dummyURI;
|
|
Packit |
f0b94e |
if (NS_SUCCEEDED(GetNextURI(dummyURI))) {
|
|
Packit |
f0b94e |
mCurAttrIndex = 0; // Reset so we'll get the first node next time
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// If there weren't any URIs in the attributes,
|
|
Packit |
f0b94e |
// then don't accept this node.
|
|
Packit |
f0b94e |
mNode = nullptr;
|
|
Packit |
f0b94e |
return NS_ERROR_INVALID_ARG;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
} // namespace mozilla
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsresult NS_NewHTMLURIRefObject(nsIURIRefObject** aResult, nsIDOMNode* aNode) {
|
|
Packit |
f0b94e |
RefPtr<mozilla::HTMLURIRefObject> refObject = new mozilla::HTMLURIRefObject();
|
|
Packit |
f0b94e |
nsresult rv = refObject->SetNode(aNode);
|
|
Packit |
f0b94e |
if (NS_FAILED(rv)) {
|
|
Packit |
f0b94e |
*aResult = 0;
|
|
Packit |
f0b94e |
return rv;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
refObject.forget(aResult);
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|