in a new class nsMarkupDocument. The point of nsMarkupDocument is to hold methods which are common to HTML and XML but not relevant to the base nsDocument class. 2) Added Selection support methods for Rod. 3) Added LookupProperty to nsCSSProperty: Given a property ID and Property Index returns back the string representation of the property. This was need to convert CSSValues back to strings for saving. TODO: Make sure that our URL Information stored in a CSSDeclaration contains enough information to return it to it's original form on output. git-svn-id: svn://10.0.0.236/trunk@5855 18797224-902f-48f8-a5cc-f745e15eee43
320 lines
8.9 KiB
C++
320 lines
8.9 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
#include "nsHTMLDocument.h"
|
|
#include "nsIParser.h"
|
|
#include "nsIHTMLContentSink.h"
|
|
#include "nsHTMLParts.h"
|
|
#include "nsIHTMLStyleSheet.h"
|
|
#include "nsIHTMLCSSStyleSheet.h"
|
|
#include "nsIStyleSet.h"
|
|
#include "nsIDocumentObserver.h"
|
|
#include "nsHTMLAtoms.h"
|
|
#include "nsIPresShell.h"
|
|
#include "nsIPresContext.h"
|
|
#include "nsIImageMap.h"
|
|
#include "nsIHTMLContent.h"
|
|
#include "nsIDOMElement.h"
|
|
#include "nsIDOMText.h"
|
|
#include "nsIPostToServer.h"
|
|
#include "nsIStreamListener.h"
|
|
#include "nsIURL.h"
|
|
#include "nsIWebWidget.h"
|
|
#include "nsIDocumentLoader.h"
|
|
#include "CNavDTD.h"
|
|
|
|
|
|
//#define rickgdebug 1
|
|
#ifdef rickgdebug
|
|
#include "nsHTMLContentSinkStream.h"
|
|
#endif
|
|
|
|
static NS_DEFINE_IID(kIWebWidgetIID, NS_IWEBWIDGET_IID);
|
|
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
|
|
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
|
|
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
|
|
static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID);
|
|
|
|
NS_LAYOUT nsresult
|
|
NS_NewHTMLDocument(nsIDocument** aInstancePtrResult)
|
|
{
|
|
nsHTMLDocument* doc = new nsHTMLDocument();
|
|
return doc->QueryInterface(kIDocumentIID, (void**) aInstancePtrResult);
|
|
}
|
|
|
|
nsHTMLDocument::nsHTMLDocument()
|
|
: nsMarkupDocument(),
|
|
mAttrStyleSheet(nsnull)
|
|
{
|
|
nsHTMLAtoms::AddrefAtoms();
|
|
}
|
|
|
|
nsHTMLDocument::~nsHTMLDocument()
|
|
{
|
|
NS_IF_RELEASE(mAttrStyleSheet);
|
|
nsHTMLAtoms::ReleaseAtoms();
|
|
}
|
|
|
|
NS_IMETHODIMP nsHTMLDocument::QueryInterface(REFNSIID aIID,
|
|
void** aInstancePtr)
|
|
{
|
|
NS_PRECONDITION(nsnull != aInstancePtr, "null ptr");
|
|
if (nsnull == aInstancePtr) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
if (aIID.Equals(kIHTMLDocumentIID)) {
|
|
AddRef();
|
|
*aInstancePtr = (void**) &mIHTMLDocument;
|
|
return NS_OK;
|
|
}
|
|
return nsDocument::QueryInterface(aIID, aInstancePtr);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLDocument::StartDocumentLoad(nsIURL *aURL,
|
|
nsIViewerContainer* aWebWidget,
|
|
nsIStreamListener **aDocListener)
|
|
{
|
|
nsresult rv;
|
|
nsIWebWidget* ww;
|
|
|
|
// Delete references to style sheets - this should be done in superclass...
|
|
PRInt32 index = mStyleSheets.Count();
|
|
while (--index >= 0) {
|
|
nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(index);
|
|
NS_RELEASE(sheet);
|
|
}
|
|
mStyleSheets.Clear();
|
|
|
|
NS_IF_RELEASE(mAttrStyleSheet);
|
|
NS_IF_RELEASE(mDocumentURL);
|
|
if (nsnull != mDocumentTitle) {
|
|
delete mDocumentTitle;
|
|
mDocumentTitle = nsnull;
|
|
}
|
|
|
|
mDocumentURL = aURL;
|
|
NS_ADDREF(aURL);
|
|
|
|
nsIParser* parser;
|
|
rv = NS_NewParser(&parser);
|
|
if (NS_OK == rv) {
|
|
nsIHTMLContentSink* sink;
|
|
|
|
#ifdef rickgdebug
|
|
rv = NS_New_HTML_ContentSinkStream(&sink);
|
|
#else
|
|
aWebWidget->QueryInterface(kIWebWidgetIID, (void**)&ww);
|
|
rv = NS_NewHTMLContentSink(&sink, this, aURL, ww);
|
|
NS_IF_RELEASE(ww);
|
|
#endif
|
|
|
|
if (NS_OK == rv) {
|
|
nsIHTMLCSSStyleSheet* styleAttrSheet;
|
|
if (NS_OK == NS_NewHTMLCSSStyleSheet(&styleAttrSheet, aURL)) {
|
|
AddStyleSheet(styleAttrSheet); // tell the world about our new style sheet
|
|
NS_RELEASE(styleAttrSheet);
|
|
}
|
|
if (NS_OK == NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURL)) {
|
|
AddStyleSheet(mAttrStyleSheet); // tell the world about our new style sheet
|
|
}
|
|
|
|
// Set the parser as the stream listener for the document loader...
|
|
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
|
|
rv = parser->QueryInterface(kIStreamListenerIID, (void**)aDocListener);
|
|
|
|
if (NS_OK == rv) {
|
|
|
|
//The following lines were added by Rick.
|
|
//These perform "dynamic" DTD registration, allowing
|
|
//the caller total control over process, and decoupling
|
|
//parser from any given grammar.
|
|
|
|
nsIDTD* theDTD=0;
|
|
NS_NewNavHTMLDTD(&theDTD);
|
|
parser->RegisterDTD(theDTD);
|
|
|
|
parser->SetContentSink(sink);
|
|
parser->Parse(aURL);
|
|
}
|
|
NS_RELEASE(sink);
|
|
}
|
|
NS_RELEASE(parser);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
|
|
static NS_DEFINE_IID(kIDocumentObserverIID, NS_IDOCUMENT_OBSERVER_IID);
|
|
|
|
NS_IMETHODIMP nsHTMLDocument::SetTitle(const nsString& aTitle)
|
|
{
|
|
if (nsnull == mDocumentTitle) {
|
|
mDocumentTitle = new nsString(aTitle);
|
|
}
|
|
else {
|
|
*mDocumentTitle = aTitle;
|
|
}
|
|
|
|
// XXX should be in nsDocument
|
|
// Pass on title to observers
|
|
PRInt32 i, n = mObservers.Count();
|
|
for (i = 0; i < n; i++) {
|
|
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
|
|
observer->SetTitle(*mDocumentTitle);
|
|
}
|
|
|
|
// Pass on to any interested containers
|
|
n = mPresShells.Count();
|
|
for (i = 0; i < n; i++) {
|
|
nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(i);
|
|
nsIPresContext* cx = shell->GetPresContext();
|
|
nsISupports* container;
|
|
if (NS_OK == cx->GetContainer(&container)) {
|
|
if (nsnull != container) {
|
|
nsIDocumentObserver* docob;
|
|
if (NS_OK == container->QueryInterface(kIDocumentObserverIID,
|
|
(void**) &docob)) {
|
|
docob->SetTitle(aTitle);
|
|
NS_RELEASE(docob);
|
|
}
|
|
NS_RELEASE(container);
|
|
}
|
|
}
|
|
NS_RELEASE(cx);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsHTMLDocument::AddImageMap(nsIImageMap* aMap)
|
|
{
|
|
NS_PRECONDITION(nsnull != aMap, "null ptr");
|
|
if (nsnull == aMap) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
if (mImageMaps.AppendElement(aMap)) {
|
|
NS_ADDREF(aMap);
|
|
return NS_OK;
|
|
}
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
NS_IMETHODIMP nsHTMLDocument::GetImageMap(const nsString& aMapName,
|
|
nsIImageMap** aResult)
|
|
{
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
if (nsnull == aResult) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
nsAutoString name;
|
|
PRInt32 i, n = mImageMaps.Count();
|
|
for (i = 0; i < n; i++) {
|
|
nsIImageMap* map = (nsIImageMap*) mImageMaps.ElementAt(i);
|
|
if (NS_OK == map->GetName(name)) {
|
|
if (name.EqualsIgnoreCase(aMapName)) {
|
|
*aResult = map;
|
|
NS_ADDREF(map);
|
|
return NS_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 1;/* XXX NS_NOT_FOUND */
|
|
}
|
|
|
|
void nsHTMLDocument::AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet)
|
|
{
|
|
if ((nsnull != mAttrStyleSheet) && (aSheet != mAttrStyleSheet)) {
|
|
aSet->InsertDocStyleSheetBefore(aSheet, mAttrStyleSheet);
|
|
}
|
|
else {
|
|
aSet->AppendDocStyleSheet(aSheet);
|
|
}
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLDocument::CreateElement(const nsString& aTagName,
|
|
nsIDOMNamedNodeMap* aAttributes,
|
|
nsIDOMElement** aReturn)
|
|
{
|
|
nsIHTMLContent* content;
|
|
nsresult rv = NS_CreateHTMLElement(&content, aTagName);
|
|
if (NS_OK != rv) {
|
|
return rv;
|
|
}
|
|
rv = content->QueryInterface(kIDOMElementIID, (void**)aReturn);
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsHTMLDocument::CreateTextNode(const nsString& aData, nsIDOMText** aTextNode)
|
|
{
|
|
nsIHTMLContent* text = nsnull;
|
|
nsresult rv = NS_NewHTMLText(&text, aData, aData.Length());
|
|
|
|
if (NS_OK == rv) {
|
|
rv = text->QueryInterface(kIDOMTextIID, (void**)aTextNode);
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
// Aggregation class to give nsHTMLDocument the nsIHTMLDocument interface
|
|
|
|
#define GET_OUTER() \
|
|
((nsHTMLDocument*) ((char*)this - nsHTMLDocument::GetOuterOffset()))
|
|
|
|
nsHTMLDocument::AggIHTMLDocument::AggIHTMLDocument() {
|
|
NS_INIT_REFCNT();
|
|
}
|
|
|
|
nsHTMLDocument::AggIHTMLDocument::~AggIHTMLDocument() { }
|
|
|
|
NS_IMETHODIMP_(nsrefcnt) nsHTMLDocument::AggIHTMLDocument::AddRef() {
|
|
return GET_OUTER()->AddRef();
|
|
}
|
|
|
|
NS_IMETHODIMP_(nsrefcnt) nsHTMLDocument::AggIHTMLDocument::Release() {
|
|
return GET_OUTER()->Release();
|
|
}
|
|
|
|
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::QueryInterface(REFNSIID aIID,
|
|
void** aInstancePtr)
|
|
{
|
|
return GET_OUTER()->QueryInterface(aIID, aInstancePtr);
|
|
}
|
|
|
|
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::SetTitle(const nsString& aTitle) {
|
|
return GET_OUTER()->SetTitle(aTitle);
|
|
}
|
|
|
|
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::AddImageMap(nsIImageMap* aMap) {
|
|
return GET_OUTER()->AddImageMap(aMap);
|
|
}
|
|
|
|
NS_IMETHODIMP nsHTMLDocument::AggIHTMLDocument::GetImageMap(const nsString& aMapName,
|
|
nsIImageMap** aResult) {
|
|
return GET_OUTER()->GetImageMap(aMapName, aResult);
|
|
}
|