Files
Mozilla/mozilla/layout/base/src/nsDocument.cpp
kostello 99d792b211 Added XIF (XML Interchange Format) Support. XIF is designed
as an Netscape internal XML application. It is designed to
allow conversion from our content model to any output format --
most importantly to HTML 3.2 and HTML4.0 format.


git-svn-id: svn://10.0.0.236/trunk@5521 18797224-902f-48f8-a5cc-f745e15eee43
1998-07-14 22:34:27 +00:00

1227 lines
28 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 "plstr.h"
#include "nsDocument.h"
#include "nsIArena.h"
#include "nsIURL.h"
#include "nsString.h"
#include "nsIContent.h"
#include "nsIStyleSet.h"
#include "nsIStyleSheet.h"
#include "nsIPresShell.h"
#include "nsIDocumentObserver.h"
#include "nsEventListenerManager.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContextOwner.h"
#include "nsIParser.h"
#include "nsCSSPropIDs.h"
#include "nsCSSProps.h"
#include "nsICSSStyleSheet.h"
#include "nsICSSStyleRule.h"
#include "nsICSSDeclaration.h"
#include "nsIHTMLCSSStyleSheet.h"
#include "nsHTMLValue.h"
#include "nsXIFConverter.h"
#include "nsSelection.h"
#include "nsIDOMText.h"
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID);
#include "nsIDOMElement.h"
static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID);
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
static NS_DEFINE_IID(kIDOMEventCapturerIID, NS_IDOMEVENTCAPTURER_IID);
static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID);
static NS_DEFINE_IID(kIPostDataIID, NS_IPOSTDATA_IID);
static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID);
NS_LAYOUT nsresult
NS_NewPostData(PRBool aIsFile, char* aData,
nsIPostData** aInstancePtrResult)
{
nsresult rv = NS_OK;
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
*aInstancePtrResult = new nsPostData(aIsFile, aData);
if (nsnull != *aInstancePtrResult) {
NS_ADDREF(*aInstancePtrResult);
} else {
rv = NS_ERROR_OUT_OF_MEMORY;
}
return rv;
}
nsPostData::nsPostData(PRBool aIsFile, char* aData)
{
NS_INIT_REFCNT();
mData = nsnull;
mDataLen = 0;
mIsFile = aIsFile;
if (aData) {
mDataLen = PL_strlen(aData);
mData = aData;
}
}
nsPostData::~nsPostData()
{
if (nsnull != mData) {
delete [] mData;
mData = nsnull;
}
}
/*
* Implementation of ISupports methods...
*/
NS_IMPL_ISUPPORTS(nsPostData,kIPostDataIID);
PRBool nsPostData::IsFile()
{
return mIsFile;
}
const char* nsPostData::GetData()
{
return mData;
}
PRInt32 nsPostData::GetDataLength()
{
return mDataLen;
}
nsDocument::nsDocument()
{
NS_INIT_REFCNT();
mArena = nsnull;
mDocumentTitle = nsnull;
mDocumentURL = nsnull;
mCharacterSet = eCharSetID_IsoLatin1;
mParentDocument = nsnull;
mRootContent = nsnull;
mScriptObject = nsnull;
mScriptContextOwner = nsnull;
mListenerManager = nsnull;
mParser = nsnull;
if (NS_OK != NS_NewSelection(&mSelection)) {
printf("*************** Error: nsDocument::nsDocument - Creation of Selection failed!\n");
}
Init();/* XXX */
}
nsDocument::~nsDocument()
{
if (nsnull != mDocumentTitle) {
delete mDocumentTitle;
mDocumentTitle = nsnull;
}
NS_IF_RELEASE(mDocumentURL);
mParentDocument = nsnull;
// Delete references to sub-documents
PRInt32 index = mSubDocuments.Count();
while (--index >= 0) {
nsIDocument* subdoc = (nsIDocument*) mSubDocuments.ElementAt(index);
NS_RELEASE(subdoc);
}
NS_IF_RELEASE(mRootContent);
// Delete references to style sheets
index = mStyleSheets.Count();
while (--index >= 0) {
nsIStyleSheet* sheet = (nsIStyleSheet*) mStyleSheets.ElementAt(index);
NS_RELEASE(sheet);
}
NS_IF_RELEASE(mArena);
NS_IF_RELEASE(mSelection);
NS_IF_RELEASE(mScriptContextOwner);
NS_IF_RELEASE(mParser);
}
nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIDocumentIID)) {
*aInstancePtr = (void*)(nsIDocument*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIDOMDocumentIID)) {
*aInstancePtr = (void*)(nsIDOMDocument*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIDOMEventCapturerIID)) {
*aInstancePtr = (void*)(nsIDOMEventCapturer*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIDOMEventReceiverIID)) {
*aInstancePtr = (void*)(nsIDOMEventReceiver*)this;
AddRef();
return NS_OK;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDocument*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsDocument)
NS_IMPL_RELEASE(nsDocument)
nsresult nsDocument::Init()
{
nsresult rv = NS_NewHeapArena(&mArena, nsnull);
if (NS_OK != rv) {
return rv;
}
return NS_OK;
}
nsIArena* nsDocument::GetArena()
{
if (nsnull != mArena) {
NS_ADDREF(mArena);
}
return mArena;
}
const nsString* nsDocument::GetDocumentTitle() const
{
return mDocumentTitle;
}
nsIURL* nsDocument::GetDocumentURL() const
{
NS_IF_ADDREF(mDocumentURL);
return mDocumentURL;
}
nsCharSetID nsDocument::GetDocumentCharacterSet() const
{
return mCharacterSet;
}
void nsDocument::SetDocumentCharacterSet(nsCharSetID aCharSetID)
{
mCharacterSet = aCharSetID;
}
nsresult nsDocument::CreateShell(nsIPresContext* aContext,
nsIViewManager* aViewManager,
nsIStyleSet* aStyleSet,
nsIPresShell** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIPresShell* shell;
nsresult rv = NS_NewPresShell(&shell);
if (NS_OK != rv) {
return rv;
}
if (NS_OK != shell->Init(this, aContext, aViewManager, aStyleSet)) {
NS_RELEASE(shell);
return rv;
}
// Note: we don't hold a ref to the shell (it holds a ref to us)
mPresShells.AppendElement(shell);
*aInstancePtrResult = shell;
return NS_OK;
}
PRBool nsDocument::DeleteShell(nsIPresShell* aShell)
{
return mPresShells.RemoveElement(aShell);
}
PRInt32 nsDocument::GetNumberOfShells()
{
return mPresShells.Count();
}
nsIPresShell* nsDocument::GetShellAt(PRInt32 aIndex)
{
nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(aIndex);
if (nsnull != shell) {
NS_ADDREF(shell);
}
return shell;
}
nsIDocument* nsDocument::GetParentDocument()
{
if (nsnull != mParentDocument) {
NS_ADDREF(mParentDocument);
}
return mParentDocument;
}
/**
* Note that we do *not* AddRef our parent because that would
* create a circular reference.
*/
void nsDocument::SetParentDocument(nsIDocument* aParent)
{
mParentDocument = aParent;
}
void nsDocument::AddSubDocument(nsIDocument* aSubDoc)
{
NS_ADDREF(aSubDoc);
mSubDocuments.AppendElement(aSubDoc);
}
PRInt32 nsDocument::GetNumberOfSubDocuments()
{
return mSubDocuments.Count();
}
nsIDocument* nsDocument::GetSubDocumentAt(PRInt32 aIndex)
{
nsIDocument* doc = (nsIDocument*) mSubDocuments.ElementAt(aIndex);
if (nsnull != doc) {
NS_ADDREF(doc);
}
return doc;
}
nsIContent* nsDocument::GetRootContent()
{
if (nsnull != mRootContent) {
NS_ADDREF(mRootContent);
}
return mRootContent;
}
void nsDocument::SetRootContent(nsIContent* aRoot)
{
NS_IF_RELEASE(mRootContent);
if (nsnull != aRoot) {
mRootContent = aRoot;
NS_ADDREF(aRoot);
}
}
PRInt32 nsDocument::GetNumberOfStyleSheets()
{
return mStyleSheets.Count();
}
nsIStyleSheet* nsDocument::GetStyleSheetAt(PRInt32 aIndex)
{
nsIStyleSheet* sheet = (nsIStyleSheet*)mStyleSheets.ElementAt(aIndex);
NS_IF_ADDREF(sheet);
return sheet;
}
void nsDocument::AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet)
{
aSet->AppendDocStyleSheet(aSheet);
}
void nsDocument::AddStyleSheet(nsIStyleSheet* aSheet)
{
NS_PRECONDITION(nsnull != aSheet, "null arg");
mStyleSheets.AppendElement(aSheet);
NS_ADDREF(aSheet);
PRInt32 count = mPresShells.Count();
PRInt32 index;
for (index = 0; index < count; index++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(index);
nsIStyleSet* set = shell->GetStyleSet();
if (nsnull != set) {
AddStyleSheetToSet(aSheet, set);
NS_RELEASE(set);
}
}
count = mObservers.Count();
for (index = 0; index < count; index++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers.ElementAt(index);
observer->StyleSheetAdded(aSheet);
}
}
nsIScriptContextOwner *nsDocument::GetScriptContextOwner()
{
if (nsnull != mScriptContextOwner) {
NS_ADDREF(mScriptContextOwner);
}
return mScriptContextOwner;
}
void nsDocument::SetScriptContextOwner(nsIScriptContextOwner *aScriptContextOwner)
{
if (nsnull != mScriptContextOwner) {
NS_RELEASE(mScriptContextOwner);
}
mScriptContextOwner = aScriptContextOwner;
if (nsnull != mScriptContextOwner) {
NS_ADDREF(mScriptContextOwner);
}
}
nsIParser *nsDocument::GetParser()
{
NS_IF_ADDREF(mParser);
return mParser;
}
void nsDocument::SetParser(nsIParser *aParser)
{
NS_IF_RELEASE(mParser);
mParser = aParser;
NS_IF_ADDREF(mParser);
}
// Note: We don't hold a reference to the document observer; we assume
// that it has a live reference to the document.
void nsDocument::AddObserver(nsIDocumentObserver* aObserver)
{
// XXX Make sure the observer isn't already in the list
if (mObservers.IndexOf(aObserver) == -1) {
mObservers.AppendElement(aObserver);
}
}
PRBool nsDocument::RemoveObserver(nsIDocumentObserver* aObserver)
{
return mObservers.RemoveElement(aObserver);
}
NS_IMETHODIMP
nsDocument::BeginLoad()
{
PRInt32 i, count = mObservers.Count();
for (i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
observer->BeginLoad();
}
return NS_OK;
}
NS_IMETHODIMP
nsDocument::EndLoad()
{
PRInt32 i, count = mObservers.Count();
for (i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*) mObservers[i];
observer->EndLoad();
}
return NS_OK;
}
void nsDocument::ContentChanged(nsIContent* aContent,
nsISupports* aSubContent)
{
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentChanged(aContent, aSubContent);
}
}
void nsDocument::ContentAppended(nsIContent* aContainer)
{
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentAppended(aContainer);
}
}
void nsDocument::ContentInserted(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentInserted(aContainer, aChild, aIndexInContainer);
}
}
void nsDocument::ContentReplaced(nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentReplaced(aContainer, aOldChild, aNewChild,
aIndexInContainer);
}
}
void nsDocument::ContentWillBeRemoved(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentWillBeRemoved(aContainer, aChild, aIndexInContainer);
}
}
void nsDocument::ContentHasBeenRemoved(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
PRInt32 count = mObservers.Count();
for (PRInt32 i = 0; i < count; i++) {
nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i];
observer->ContentHasBeenRemoved(aContainer, aChild, aIndexInContainer);
}
}
nsresult nsDocument::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
res = NS_NewScriptDocument(aContext, this, global, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return res;
}
nsresult nsDocument::ResetScriptObject()
{
mScriptObject = nsnull;
return NS_OK;
}
//
// nsIDOMDocument interface
//
NS_IMETHODIMP
nsDocument::GetMasterDoc(nsIDOMDocument **aDocument)
{
AddRef();
*aDocument = (nsIDOMDocument*)this;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::GetDocumentType(nsIDOMDocumentType** aDocumentType)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetProlog(nsIDOMNodeList** aProlog)
{
*aProlog = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::GetEpilog(nsIDOMNodeList** aEpilog)
{
*aEpilog = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDocument::GetDocumentElement(nsIDOMElement** aDocumentElement)
{
nsresult res = NS_ERROR_FAILURE;
if (nsnull != mRootContent) {
res = mRootContent->QueryInterface(kIDOMElementIID, (void**)aDocumentElement);
NS_ASSERTION(NS_OK == res, "Must be a DOM Element");
}
return res;
}
#if 0
NS_IMETHODIMP
nsDocument::SetDocumentElement(nsIDOMElement *aElement)
{
NS_PRECONDITION(nsnull != aElement, "null arg");
nsIContent* content;
nsresult res = aElement->QueryInterface(kIContentIID, (void**)&content);
if (NS_OK == res) {
SetRootContent(content);
NS_RELEASE(content);
}
else NS_ASSERTION(0, "Must be an nsIContent"); // nsIContent not supported. Who are you?
return res;
}
#endif
NS_IMETHODIMP
nsDocument::CreateElement(const nsString& aTagName,
nsIDOMNamedNodeMap* aAttributes,
nsIDOMElement** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::CreateTextNode(const nsString& aData, nsIDOMText** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::CreateDocumentFragment(nsIDOMDocumentFragment** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::CreateComment(const nsString& aData, nsIDOMComment** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::CreateProcessingInstruction(const nsString& aTarget,
const nsString& aData,
nsIDOMProcessingInstruction** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::CreateAttribute(const nsString& aName,
nsIDOMNode* aValue,
nsIDOMAttribute** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetElementsByTagName(const nsString& aTagname,
nsIDOMNodeList** aReturn)
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
//
// nsIDOMNode methods
//
NS_IMETHODIMP
nsDocument::GetNodeName(nsString& aNodeName)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetNodeValue(nsString& aNodeValue)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::SetNodeValue(const nsString& aNodeValue)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetNodeType(PRInt32* aNodeType)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetParentNode(nsIDOMNode** aParentNode)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetChildNodes(nsIDOMNodeList** aChildNodes)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetHasChildNodes(PRBool* aHasChildNodes)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetFirstChild(nsIDOMNode** aFirstChild)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetLastChild(nsIDOMNode** aLastChild)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetNextSibling(nsIDOMNode** aNextSibling)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::CloneNode(nsIDOMNode** aReturn)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDocument::Equals(nsIDOMNode* aNode, PRBool aDeep, PRBool* aReturn)
{
// XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult nsDocument::GetListenerManager(nsIEventListenerManager **aInstancePtrResult)
{
if (nsnull != mListenerManager) {
return mListenerManager->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult);;
}
else {
nsIEventListenerManager* l = new nsEventListenerManager();
if (nsnull == l) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (NS_OK == l->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult)) {
mListenerManager = l;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
}
nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsIDOMEvent* aDOMEvent,
nsEventStatus& aEventStatus)
{
//Capturing stage
//Local handling stage
if (nsnull != mListenerManager) {
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
}
//Bubbling stage
/*Need to go to window here*/
return NS_OK;
}
nsresult nsDocument::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
manager->AddEventListener(aListener, aIID);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDocument::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
manager->RemoveEventListener(aListener, aIID);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDocument::CaptureEvent(nsIDOMEventListener *aListener)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
manager->CaptureEvent(aListener);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDocument::ReleaseEvent(nsIDOMEventListener *aListener)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
manager->ReleaseEvent(aListener);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
/**
* Returns the Selection Object
*/
nsISelection * nsDocument::GetSelection() {
if (mSelection != nsnull) {
NS_ADDREF(mSelection);
}
return mSelection;
}
/**
* Selects all the Content
*/
void nsDocument::SelectAll() {
nsIContent * start = mRootContent;
nsIContent * end = mRootContent;
// Find Very first Piece of Content
while (start->ChildCount() > 0) {
start = start->ChildAt(0);
}
// Last piece of Content
PRInt32 count = end->ChildCount();
while (count > 0) {
end = end->ChildAt(count-1);
count = end->ChildCount();
}
nsSelectionRange * range = mSelection->GetRange();
nsSelectionPoint * startPnt = range->GetStartPoint();
nsSelectionPoint * endPnt = range->GetEndPoint();
startPnt->SetPoint(start, -1, PR_TRUE);
endPnt->SetPoint(end, -1, PR_FALSE);
}
void nsDocument::TraverseTree(nsString & aText,
nsIContent * aContent,
nsIContent * aStart,
nsIContent * aEnd,
PRBool & aInRange) {
if (aContent == aStart) {
aInRange = PR_TRUE;
}
PRBool addReturn = PR_FALSE;
if (aInRange) {
nsIDOMText * textContent;
nsresult status = aContent->QueryInterface(kIDOMTextIID, (void**) &textContent);
if (NS_OK == status) {
nsString text;
textContent->GetData(text);
aText.Append(text);
//NS_IF_RELEASE(textContent);
} else {
nsIAtom * atom = aContent->GetTag();
if (atom != nsnull) {
nsString str;
atom->ToString(str);
//char * s = str.ToNewCString();
if (str.Equals("P") ||
str.Equals("OL") ||
str.Equals("LI") ||
str.Equals("TD") ||
str.Equals("H1") ||
str.Equals("H2") ||
str.Equals("H3") ||
str.Equals("H4") ||
str.Equals("H5") ||
str.Equals("H6") ||
str.Equals("TABLE")) {
addReturn = PR_TRUE;
}
//printf("[%s]\n", s);
//delete s;
}
}
}
for (PRInt32 i=0;i<aContent->ChildCount();i++) {
TraverseTree(aText, aContent->ChildAt(i), aStart, aEnd, aInRange);
}
if (addReturn) {
aText.Append("\n");
}
if (aContent == aEnd) {
aInRange = PR_FALSE;
}
}
void nsDocument::GetSelectionText(nsString & aText) {
nsSelectionRange * range = mSelection->GetRange();
nsSelectionPoint * startPnt = range->GetStartPoint();
nsSelectionPoint * endPnt = range->GetEndPoint();
PRBool inRange = PR_FALSE;
TraverseTree(aText, mRootContent, startPnt->GetContent(), endPnt->GetContent(), inRange);
}
void nsDocument::CSSSelectorToXIF(nsXIFConverter& aConverter, nsCSSSelector& aSelector)
{
nsString s;
nsCSSSelector* next = aSelector.mNext;
if (nsnull != next)
CSSSelectorToXIF(aConverter,*next);
aConverter.BeginCSSSelector();
if (aSelector.mTag != nsnull)
{
aSelector.mTag->ToString(s);
aConverter.AddCSSTag(s);
}
if (aSelector.mID != nsnull)
{
aSelector.mID->ToString(s);
aConverter.AddCSSID(s);
}
if (aSelector.mClass != nsnull)
{
aSelector.mClass->ToString(s);
aConverter.AddCSSClass(s);
}
if (aSelector.mPseudoClass != nsnull)
{
aSelector.mPseudoClass->ToString(s);
aConverter.AddCSSPsuedoClass(s);
}
aConverter.EndCSSSelector();
}
void nsDocument::CSSDeclarationToXIF(nsXIFConverter& aConverter, nsICSSDeclaration& aDeclaration)
{
PRInt32 propId;
nsCSSValue value;
nsString name;
nsString str;
aConverter.BeginCSSDeclarationList();
for (propId = 0; propId < PROP_MAX; propId++)
{
switch(propId)
{
case PROP_BACKGROUND:
case PROP_BORDER:
case PROP_CLIP:
case PROP_FONT:
case PROP_LIST_STYLE:
case PROP_MARGIN:
case PROP_PADDING:
case PROP_BACKGROUND_POSITION:
case PROP_BORDER_TOP:
case PROP_BORDER_RIGHT:
case PROP_BORDER_BOTTOM:
case PROP_BORDER_LEFT:
case PROP_BORDER_COLOR:
case PROP_BORDER_STYLE:
case PROP_BORDER_WIDTH:
break;
default:
aDeclaration.GetValue(propId,value);
if (value.GetUnit() != eHTMLUnit_Null)
{
aConverter.BeginCSSDeclaration();
name = nsCSSProps::kNameTable[propId].name;
value.ToCSSString(str,propId);
aConverter.AddCSSDeclaration(name,str);
aConverter.EndCSSDeclaration();
}
}
}
aConverter.EndCSSDeclarationList();
}
void nsDocument::StyleSheetsToXIF(nsXIFConverter& aConverter)
{
PRInt32 count = GetNumberOfStyleSheets();
nsIURL& docURL = *mDocumentURL;
for (PRInt32 index = 0; index < count; index++)
{
nsIStyleSheet* sheet = GetStyleSheetAt(index);
nsICSSStyleSheet* cssSheet = nsnull;
if (sheet != nsnull)
{
nsIURL& sheetURL = *sheet->GetURL();
if (!(sheetURL == docURL))
break;
nsresult isCss = sheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssSheet);
if ((isCss == NS_OK) && (cssSheet != nsnull))
{
PRInt32 ruleCount = cssSheet->StyleRuleCount();
PRInt32 ruleIndex;
nsICSSStyleRule* rule = nsnull;
aConverter.BeginCSSStyleSheet();
for (ruleIndex = 0; ruleIndex < ruleCount; ruleIndex++)
{
if (NS_OK == cssSheet->GetStyleRuleAt(ruleIndex, rule))
{
aConverter.BeginCSSRule();
if (nsnull != rule)
{
nsCSSSelector* selector = rule->FirstSelector();
if (nsnull != selector)
CSSSelectorToXIF(aConverter,*selector);
nsICSSDeclaration* declaration = rule->GetDeclaration();
if (nsnull != declaration)
CSSDeclarationToXIF(aConverter,*declaration);
NS_IF_RELEASE(declaration);
NS_IF_RELEASE(rule);
} // ruleAt
aConverter.EndCSSRule();
} // for loop
}
aConverter.EndCSSStyleSheet();
NS_RELEASE(cssSheet);
} // css_sheet
NS_RELEASE(sheet);
} // sheet
}
}
void nsDocument::ToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode)
{
nsIContent* content = nsnull;
nsresult isContent = aNode->QueryInterface(kIContentIID, (void**)&content);
nsIDOMElement* element = nsnull;
nsresult isElement = aNode->QueryInterface(kIDOMElementIID, (void**)&element);
PRBool isSynthetic = PR_TRUE;
// Begin Conversion
if (NS_OK == isContent)
{
content->IsSynthetic(isSynthetic);
if (PR_FALSE == isSynthetic)
{
content->BeginConvertToXIF(aConverter);
content->DoConvertToXIF(aConverter);
}
}
// Iterate through the children, convertion child nodes
nsresult result = NS_OK;
nsIDOMNode* node = nsnull;
result = aNode->GetFirstChild(&node);
while ((result == NS_OK) && (node != nsnull))
{
nsIDOMNode* temp = node;
ToXIF(aConverter,node);
result = node->GetNextSibling(&node);
NS_RELEASE(temp);
}
if (NS_OK == isContent && PR_FALSE == isSynthetic)
{
nsIAtom* tag = content->GetTag();
if (tag != nsnull)
{
if (tag != nsnull)
{
nsString str;
tag->ToString(str);
if (str.EqualsIgnoreCase("Head"))
StyleSheetsToXIF(aConverter);
}
}
}
if (NS_OK == isContent)
{
if (PR_FALSE == isSynthetic)
content->FinishConvertToXIF(aConverter);
NS_RELEASE(content);
}
if (NS_OK == isElement)
{
NS_RELEASE(element);
}
}
void nsDocument::ToXIF(nsString & aBuffer, PRBool aUseSelection)
{
nsXIFConverter converter(aBuffer);
nsIDOMNode *root = nsnull;
// call the function
converter.AddStartTag("section");
converter.AddStartTag("section_head");
converter.AddEndTag("section_head");
converter.AddStartTag("section_body");
if (NS_OK == GetFirstChild(&root))
{
ToXIF(converter,root);
NS_RELEASE(root);
}
converter.AddEndTag("section_body");
converter.AddEndTag("section");
converter.Write();
}