From 5185a8d0a022ad02a3b4b39302325a2006158cb1 Mon Sep 17 00:00:00 2001 From: "akkana%netscape.com" Date: Fri, 4 Jun 1999 22:22:53 +0000 Subject: [PATCH] XIF Document Encoder; and partial fix for XIF-to-html conversion of comments --- content/base/src/nsCommentNode.cpp | 191 ++++++++++++++++++++++++++++- layout/base/src/Makefile.in | 1 + layout/base/src/makefile.win | 2 + layout/base/src/nsCommentNode.cpp | 191 ++++++++++++++++++++++++++++- layout/base/src/nsXIFConverter.cpp | 14 ++- layout/build/nsLayoutFactory.cpp | 19 ++- 6 files changed, 407 insertions(+), 11 deletions(-) diff --git a/content/base/src/nsCommentNode.cpp b/content/base/src/nsCommentNode.cpp index 537e59dc1cdb..19462735ebaf 100644 --- a/content/base/src/nsCommentNode.cpp +++ b/content/base/src/nsCommentNode.cpp @@ -23,8 +23,15 @@ #include "nsIContent.h" #include "nsFrame.h" #include "nsLayoutAtoms.h" +#include "nsIDOMSelection.h" +#include "nsXIFConverter.h" +#include "nsIDocument.h" +#include "nsIEnumerator.h" +#include "nsCOMPtr.h" +#include "nsIDOMRange.h" static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID); +static NS_DEFINE_IID(kIEnumeratorIID, NS_IENUMERATOR_IID); class nsCommentNode : public nsIDOMComment, public nsIScriptObjectOwner, @@ -53,7 +60,104 @@ public: NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(mInner) // nsIContent - NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) + //NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) + + NS_IMETHOD GetDocument(nsIDocument*& aResult) const { + return mInner.GetDocument(aResult); + } + NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep) { + return mInner.SetDocument(aDocument, aDeep); + } + NS_IMETHOD GetParent(nsIContent*& aResult) const { + return mInner.GetParent(aResult); + } + NS_IMETHOD SetParent(nsIContent* aParent) { + return mInner.SetParent(aParent); + } + NS_IMETHOD CanContainChildren(PRBool& aResult) const { + return mInner.CanContainChildren(aResult); + } + NS_IMETHOD ChildCount(PRInt32& aResult) const { + return mInner.ChildCount(aResult); + } + NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const { + return mInner.ChildAt(aIndex, aResult); + } + NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aResult) const { + return mInner.IndexOf(aPossibleChild, aResult); + } + NS_IMETHOD InsertChildAt(nsIContent* aKid, PRInt32 aIndex, + PRBool aNotify) { + return mInner.InsertChildAt(aKid, aIndex, aNotify); + } + NS_IMETHOD ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, + PRBool aNotify) { + return mInner.ReplaceChildAt(aKid, aIndex, aNotify); + } + NS_IMETHOD AppendChildTo(nsIContent* aKid, PRBool aNotify) { + return mInner.AppendChildTo(aKid, aNotify); + } + NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) { + return mInner.RemoveChildAt(aIndex, aNotify); + } + NS_IMETHOD IsSynthetic(PRBool& aResult) { + return mInner.IsSynthetic(aResult); + } + NS_IMETHOD GetNameSpaceID(PRInt32& aID) const { + return mInner.GetNameSpaceID(aID); + } + NS_IMETHOD GetTag(nsIAtom*& aResult) const; + NS_IMETHOD ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) { + return mInner.ParseAttributeString(aStr, aName, aNameSpaceID); + } + NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) { + return mInner.GetNameSpacePrefixFromId(aNameSpaceID, aPrefix); + } + NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, + nsString &aResult) const { + return mInner.GetAttribute(aNameSpaceID, aAttribute, aResult); + } + NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, + const nsString& aValue, PRBool aNotify) { + return mInner.SetAttribute(aNameSpaceID, aAttribute, aValue, aNotify); + } + NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, + PRBool aNotify) { + return mInner.UnsetAttribute(aNameSpaceID, aAttribute, aNotify); + } + NS_IMETHOD GetAttributeNameAt(PRInt32 aIndex, + PRInt32& aNameSpaceID, + nsIAtom*& aName) const { + return mInner.GetAttributeNameAt(aIndex, aNameSpaceID, aName); + } + NS_IMETHOD GetAttributeCount(PRInt32& aResult) const { + return mInner.GetAttributeCount(aResult); + } + NS_IMETHOD List(FILE* out, PRInt32 aIndent) const; + NS_IMETHOD BeginConvertToXIF(nsXIFConverter& aConverter) const { + return mInner.BeginConvertToXIF(aConverter); + } + NS_IMETHOD ConvertContentToXIF(nsXIFConverter& aConverter) const; + NS_IMETHOD FinishConvertToXIF(nsXIFConverter& aConverter) const { + return mInner.FinishConvertToXIF(aConverter); + } + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus); + NS_IMETHOD RangeAdd(nsIDOMRange& aRange){ + return mInner.RangeAdd(aRange); + } + NS_IMETHOD RangeRemove(nsIDOMRange& aRange){ + return mInner.RangeRemove(aRange); + } + NS_IMETHOD GetRangeList(nsVoidArray*& aResult) const { + return mInner.GetRangeList(aResult); + } protected: nsGenericDOMDataNode mInner; @@ -147,8 +251,8 @@ nsCommentNode::List(FILE* out, PRInt32 aIndent) const { NS_PRECONDITION(nsnull != mInner.mDocument, "bad content"); - PRInt32 index; - for (index = aIndent; --index >= 0; ) fputs(" ", out); + PRInt32 indx; + for (indx = aIndent; --indx >= 0; ) fputs(" ", out); fprintf(out, "Comment refcount=%d<", mRefCnt); @@ -183,3 +287,84 @@ NS_NewCommentFrame(nsIFrame*& aResult) aResult = frame; return NS_OK; } + +/** + * Translate the content object into the (XIF) XML Interchange Format + * XIF is an intermediate form of the content model, the buffer + * will then be parsed into any number of formats including HTML, TXT, etc. + */ +nsresult +nsCommentNode::ConvertContentToXIF(nsXIFConverter& aConverter) const +{ + const nsIContent* content = this; + nsIDOMSelection* sel = aConverter.GetSelection(); + + nsIDocument* document; + nsresult res; + res = GetDocument(document); + if (!NS_SUCCEEDED(res)) + return res; + + nsTextFragment* textFrag; + PRInt32 numFragments; + res = mInner.GetText(textFrag, numFragments); + if (!NS_SUCCEEDED(res)) + return res; +#ifdef DEBUG_akkana + if (numFragments == 0) + printf("numFragments is zero! Go figure!\n"); +#endif + if (sel != nsnull && document->IsInSelection(sel,content)) + { + nsIEnumerator *enumerator; + if (NS_SUCCEEDED(sel->QueryInterface(kIEnumeratorIID, (void **)&enumerator))) { + for (enumerator->First();NS_OK != enumerator->IsDone(); enumerator->Next()) { + nsIDOMRange* range = nsnull; + if (NS_SUCCEEDED(enumerator->CurrentItem((nsISupports**)&range))) { + + nsCOMPtr startNode; + nsCOMPtr endNode; + PRInt32 startOffset = 0; + PRInt32 endOffset = 0; + + range->GetStartParent(getter_AddRefs(startNode)); + range->GetEndParent(getter_AddRefs(endNode)); + + range->GetStartOffset(&startOffset); + range->GetEndOffset(&endOffset); + + nsCOMPtr startContent; + nsCOMPtr endContent; + startContent = do_QueryInterface(startNode); + endContent = do_QueryInterface(endNode); + + + nsString buffer; + textFrag->AppendTo(buffer); + if (startContent.get() == content || endContent.get() == content) + { + // NOTE: ORDER MATTERS! + // This must go before the Cut + if (endContent.get() == content) + buffer.Truncate(endOffset); + + // This must go after the Trunctate + if (startContent.get() == content) + buffer.Cut(0,startOffset); + } + aConverter.AddComment(buffer); + } + } + } + } + else + { + nsString buffer; + textFrag->AppendTo(buffer); + aConverter.AddComment(buffer); + } + NS_IF_RELEASE(document); + // XXX Possible mem leak: Do we need to delete textFrag? + return NS_OK; +} + diff --git a/layout/base/src/Makefile.in b/layout/base/src/Makefile.in index 1a9c54cbf9cd..82f70e412dbb 100644 --- a/layout/base/src/Makefile.in +++ b/layout/base/src/Makefile.in @@ -34,6 +34,7 @@ CPPSRCS = \ nsContentIterator.cpp \ nsContentList.cpp \ nsDocument.cpp \ + nsDocumentEncoder.cpp \ nsDocumentFragment.cpp \ nsDocumentViewer.cpp \ nsDOMAttribute.cpp \ diff --git a/layout/base/src/makefile.win b/layout/base/src/makefile.win index 513977687177..5bc7e07fb939 100644 --- a/layout/base/src/makefile.win +++ b/layout/base/src/makefile.win @@ -31,6 +31,7 @@ CPPSRCS = \ nsContentList.cpp \ nsContentIterator.cpp \ nsDocument.cpp \ + nsDocumentEncoder.cpp \ nsDocumentFragment.cpp \ nsDocumentViewer.cpp \ nsDOMAttribute.cpp \ @@ -73,6 +74,7 @@ CPP_OBJS= \ .\$(OBJDIR)\nsContentList.obj \ .\$(OBJDIR)\nsContentIterator.obj \ .\$(OBJDIR)\nsDocument.obj \ + .\$(OBJDIR)\nsDocumentEncoder.obj \ .\$(OBJDIR)\nsDocumentFragment.obj \ .\$(OBJDIR)\nsDocumentViewer.obj \ .\$(OBJDIR)\nsDOMAttribute.obj \ diff --git a/layout/base/src/nsCommentNode.cpp b/layout/base/src/nsCommentNode.cpp index 537e59dc1cdb..19462735ebaf 100644 --- a/layout/base/src/nsCommentNode.cpp +++ b/layout/base/src/nsCommentNode.cpp @@ -23,8 +23,15 @@ #include "nsIContent.h" #include "nsFrame.h" #include "nsLayoutAtoms.h" +#include "nsIDOMSelection.h" +#include "nsXIFConverter.h" +#include "nsIDocument.h" +#include "nsIEnumerator.h" +#include "nsCOMPtr.h" +#include "nsIDOMRange.h" static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID); +static NS_DEFINE_IID(kIEnumeratorIID, NS_IENUMERATOR_IID); class nsCommentNode : public nsIDOMComment, public nsIScriptObjectOwner, @@ -53,7 +60,104 @@ public: NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(mInner) // nsIContent - NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) + //NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner) + + NS_IMETHOD GetDocument(nsIDocument*& aResult) const { + return mInner.GetDocument(aResult); + } + NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep) { + return mInner.SetDocument(aDocument, aDeep); + } + NS_IMETHOD GetParent(nsIContent*& aResult) const { + return mInner.GetParent(aResult); + } + NS_IMETHOD SetParent(nsIContent* aParent) { + return mInner.SetParent(aParent); + } + NS_IMETHOD CanContainChildren(PRBool& aResult) const { + return mInner.CanContainChildren(aResult); + } + NS_IMETHOD ChildCount(PRInt32& aResult) const { + return mInner.ChildCount(aResult); + } + NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const { + return mInner.ChildAt(aIndex, aResult); + } + NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aResult) const { + return mInner.IndexOf(aPossibleChild, aResult); + } + NS_IMETHOD InsertChildAt(nsIContent* aKid, PRInt32 aIndex, + PRBool aNotify) { + return mInner.InsertChildAt(aKid, aIndex, aNotify); + } + NS_IMETHOD ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, + PRBool aNotify) { + return mInner.ReplaceChildAt(aKid, aIndex, aNotify); + } + NS_IMETHOD AppendChildTo(nsIContent* aKid, PRBool aNotify) { + return mInner.AppendChildTo(aKid, aNotify); + } + NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) { + return mInner.RemoveChildAt(aIndex, aNotify); + } + NS_IMETHOD IsSynthetic(PRBool& aResult) { + return mInner.IsSynthetic(aResult); + } + NS_IMETHOD GetNameSpaceID(PRInt32& aID) const { + return mInner.GetNameSpaceID(aID); + } + NS_IMETHOD GetTag(nsIAtom*& aResult) const; + NS_IMETHOD ParseAttributeString(const nsString& aStr, + nsIAtom*& aName, + PRInt32& aNameSpaceID) { + return mInner.ParseAttributeString(aStr, aName, aNameSpaceID); + } + NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID, + nsIAtom*& aPrefix) { + return mInner.GetNameSpacePrefixFromId(aNameSpaceID, aPrefix); + } + NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, + nsString &aResult) const { + return mInner.GetAttribute(aNameSpaceID, aAttribute, aResult); + } + NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, + const nsString& aValue, PRBool aNotify) { + return mInner.SetAttribute(aNameSpaceID, aAttribute, aValue, aNotify); + } + NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, + PRBool aNotify) { + return mInner.UnsetAttribute(aNameSpaceID, aAttribute, aNotify); + } + NS_IMETHOD GetAttributeNameAt(PRInt32 aIndex, + PRInt32& aNameSpaceID, + nsIAtom*& aName) const { + return mInner.GetAttributeNameAt(aIndex, aNameSpaceID, aName); + } + NS_IMETHOD GetAttributeCount(PRInt32& aResult) const { + return mInner.GetAttributeCount(aResult); + } + NS_IMETHOD List(FILE* out, PRInt32 aIndent) const; + NS_IMETHOD BeginConvertToXIF(nsXIFConverter& aConverter) const { + return mInner.BeginConvertToXIF(aConverter); + } + NS_IMETHOD ConvertContentToXIF(nsXIFConverter& aConverter) const; + NS_IMETHOD FinishConvertToXIF(nsXIFConverter& aConverter) const { + return mInner.FinishConvertToXIF(aConverter); + } + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus); + NS_IMETHOD RangeAdd(nsIDOMRange& aRange){ + return mInner.RangeAdd(aRange); + } + NS_IMETHOD RangeRemove(nsIDOMRange& aRange){ + return mInner.RangeRemove(aRange); + } + NS_IMETHOD GetRangeList(nsVoidArray*& aResult) const { + return mInner.GetRangeList(aResult); + } protected: nsGenericDOMDataNode mInner; @@ -147,8 +251,8 @@ nsCommentNode::List(FILE* out, PRInt32 aIndent) const { NS_PRECONDITION(nsnull != mInner.mDocument, "bad content"); - PRInt32 index; - for (index = aIndent; --index >= 0; ) fputs(" ", out); + PRInt32 indx; + for (indx = aIndent; --indx >= 0; ) fputs(" ", out); fprintf(out, "Comment refcount=%d<", mRefCnt); @@ -183,3 +287,84 @@ NS_NewCommentFrame(nsIFrame*& aResult) aResult = frame; return NS_OK; } + +/** + * Translate the content object into the (XIF) XML Interchange Format + * XIF is an intermediate form of the content model, the buffer + * will then be parsed into any number of formats including HTML, TXT, etc. + */ +nsresult +nsCommentNode::ConvertContentToXIF(nsXIFConverter& aConverter) const +{ + const nsIContent* content = this; + nsIDOMSelection* sel = aConverter.GetSelection(); + + nsIDocument* document; + nsresult res; + res = GetDocument(document); + if (!NS_SUCCEEDED(res)) + return res; + + nsTextFragment* textFrag; + PRInt32 numFragments; + res = mInner.GetText(textFrag, numFragments); + if (!NS_SUCCEEDED(res)) + return res; +#ifdef DEBUG_akkana + if (numFragments == 0) + printf("numFragments is zero! Go figure!\n"); +#endif + if (sel != nsnull && document->IsInSelection(sel,content)) + { + nsIEnumerator *enumerator; + if (NS_SUCCEEDED(sel->QueryInterface(kIEnumeratorIID, (void **)&enumerator))) { + for (enumerator->First();NS_OK != enumerator->IsDone(); enumerator->Next()) { + nsIDOMRange* range = nsnull; + if (NS_SUCCEEDED(enumerator->CurrentItem((nsISupports**)&range))) { + + nsCOMPtr startNode; + nsCOMPtr endNode; + PRInt32 startOffset = 0; + PRInt32 endOffset = 0; + + range->GetStartParent(getter_AddRefs(startNode)); + range->GetEndParent(getter_AddRefs(endNode)); + + range->GetStartOffset(&startOffset); + range->GetEndOffset(&endOffset); + + nsCOMPtr startContent; + nsCOMPtr endContent; + startContent = do_QueryInterface(startNode); + endContent = do_QueryInterface(endNode); + + + nsString buffer; + textFrag->AppendTo(buffer); + if (startContent.get() == content || endContent.get() == content) + { + // NOTE: ORDER MATTERS! + // This must go before the Cut + if (endContent.get() == content) + buffer.Truncate(endOffset); + + // This must go after the Trunctate + if (startContent.get() == content) + buffer.Cut(0,startOffset); + } + aConverter.AddComment(buffer); + } + } + } + } + else + { + nsString buffer; + textFrag->AppendTo(buffer); + aConverter.AddComment(buffer); + } + NS_IF_RELEASE(document); + // XXX Possible mem leak: Do we need to delete textFrag? + return NS_OK; +} + diff --git a/layout/base/src/nsXIFConverter.cpp b/layout/base/src/nsXIFConverter.cpp index 68001d234226..7381589958a1 100644 --- a/layout/base/src/nsXIFConverter.cpp +++ b/layout/base/src/nsXIFConverter.cpp @@ -307,9 +307,9 @@ void nsXIFConverter::AddContent(const nsString& aContent) void nsXIFConverter::AddComment(const nsString& aContent) { - mBuffer.Append(mBeginComment); +// mBuffer.Append(mBeginComment); mBuffer.Append(aContent); - mBuffer.Append(mEndComment); +// mBuffer.Append(mEndComment); } @@ -456,12 +456,18 @@ void nsXIFConverter::EndCSSDeclaration() void nsXIFConverter::Write() { - - #if defined(WIN32) const char* filename="c:\\temp\\xif.html"; ofstream out(filename); + char* s = mBuffer.ToNewCString(); + out << s; + out.close(); + delete[] s; +#elif defined(XP_UNIX) + const char* filename="/tmp/xif.html"; + ofstream out(filename); + char* s = mBuffer.ToNewCString(); out << s; out.close(); diff --git a/layout/build/nsLayoutFactory.cpp b/layout/build/nsLayoutFactory.cpp index 4ad7bb931a2a..5ccaa388ca51 100644 --- a/layout/build/nsLayoutFactory.cpp +++ b/layout/build/nsLayoutFactory.cpp @@ -45,6 +45,7 @@ #include "nsIEventListenerManager.h" #include "nsILayoutDebugger.h" #include "nsIHTMLElementFactory.h" +#include "nsIDocumentEncoder.h" #include "nsCOMPtr.h" class nsIDocumentLoaderFactory; @@ -77,6 +78,7 @@ static NS_DEFINE_CID(kPrintPreviewContextCID, NS_PRINT_PREVIEW_CONTEXT_CID); static NS_DEFINE_CID(kLayoutDocumentLoaderFactoryCID, NS_LAYOUT_DOCUMENT_LOADER_FACTORY_CID); static NS_DEFINE_CID(kLayoutDebuggerCID, NS_LAYOUT_DEBUGGER_CID); static NS_DEFINE_CID(kHTMLElementFactoryCID, NS_HTML_ELEMENT_FACTORY_CID); +static NS_DEFINE_CID(kHTMLEncoderCID, NS_HTML_ENCODER_CID); extern nsresult NS_NewRangeList(nsIDOMSelection** aResult); extern nsresult NS_NewRange(nsIDOMRange** aResult); @@ -87,6 +89,7 @@ extern nsresult NS_NewFrameUtil(nsIFrameUtil** aResult); extern nsresult NS_NewLayoutDocumentLoaderFactory(nsIDocumentLoaderFactory** aResult); extern nsresult NS_NewLayoutDebugger(nsILayoutDebugger** aResult); extern nsresult NS_NewHTMLElementFactory(nsIHTMLElementFactory** aResult); +extern nsresult NS_NewHTMLEncoder(nsIDocumentEncoder** aResult); //////////////////////////////////////////////////////////// @@ -375,6 +378,14 @@ nsLayoutFactory::CreateInstance(nsISupports *aOuter, } refCounted = PR_TRUE; } + else if (mClassID.Equals(kHTMLEncoderCID)) { + res = NS_NewHTMLEncoder((nsIDocumentEncoder**) &inst); + if (NS_FAILED(res)) { + LOG_NEW_FAILURE("NS_NewHTMLEncoder", res); + return res; + } + refCounted = PR_TRUE; + } else { return NS_NOINTERFACE; } @@ -688,6 +699,12 @@ NSRegisterSelf(nsISupports* aServMgr , const char* aPath) LOG_REGISTER_FAILURE("kHTMLElementFactoryCID", rv); break; } + rv = cm->RegisterComponent(kHTMLEncoderCID, NULL, NULL, aPath, + PR_TRUE, PR_TRUE); + if (NS_FAILED(rv)) { + LOG_REGISTER_FAILURE("kHTMLEncoderCID", rv); + break; + } break; } while (PR_FALSE); @@ -733,7 +750,7 @@ NSUnregisterSelf(nsISupports* aServMgr, const char* aPath) rv = cm->UnregisterComponent(kSubtreeIteratorCID, aPath); rv = cm->UnregisterComponent(kFrameUtilCID, aPath); rv = cm->UnregisterComponent(kLayoutDebuggerCID, aPath); - rv = cm->UnregisterComponent(kHTMLElementFactoryCID, aPath); + rv = cm->UnregisterComponent(kHTMLEncoderCID, aPath); // XXX why the heck are these exported???? bad bad bad bad #if 1