Blame editor/libeditor/HTMLURIRefObject.cpp

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
}