Compare commits

..

14 Commits

Author SHA1 Message Date
waterson%netscape.com
e0ed05d25f Make plugin stuff into a component.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74455 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-19 08:25:10 +00:00
waterson%netscape.com
150cc3fd7e Make it compile cleanly on Linux.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74443 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-19 04:02:14 +00:00
waterson%netscape.com
3259da1fb7 Fix Unix bustage. The X11 headers collide with nsIRegistry because X11 does '#define None'. Boneheads.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74442 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-19 04:00:38 +00:00
waterson%netscape.com
da25d9e235 Add RegisterPlugin() & UnregisterPlugin() APIs to the plugin manager.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74438 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-19 03:05:23 +00:00
waterson%netscape.com
4d0067bc07 Add RegisterPlugin() & UnregisterPlugin() APIs to the plugin manager; juggle registry twiddling code.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74437 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-19 03:05:16 +00:00
waterson%netscape.com
1e14a6a5e9 Remove nsIPlugin implementation. Use generic module instead.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74436 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-19 03:00:34 +00:00
(no author)
9ebe4483d7 This commit was manufactured by cvs2svn to create branch
'PLUGIN_LOVE_2000_07_17_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74435 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-19 02:58:51 +00:00
waterson%netscape.com
56bbf1056f Use CID as the name of plugin subtree instead of some random identifier.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74382 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-18 19:59:31 +00:00
waterson%netscape.com
1cd3b38d83 Use XPCOM registry to identify XPCOM-style plugins.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74381 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-18 19:37:30 +00:00
waterson%netscape.com
9d2145f8fd Clean up tests.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74380 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-18 19:36:47 +00:00
waterson%netscape.com
084268a13c Oops. Get rid of nsPluginFactory.cpp
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74365 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-18 01:27:36 +00:00
waterson%netscape.com
28301a39b1 Move plugin docloader out of layout and into modules/plugin.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74364 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-18 01:25:06 +00:00
waterson%netscape.com
2a68e02f7b Move plugin docloader out of layout and into modules/plugin.
git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74363 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-18 01:18:07 +00:00
(no author)
901ae84da1 This commit was manufactured by cvs2svn to create branch
'PLUGIN_LOVE_2000_07_17_BRANCH'.

git-svn-id: svn://10.0.0.236/branches/PLUGIN_LOVE_2000_07_17_BRANCH@74145 18797224-902f-48f8-a5cc-f745e15eee43
2000-07-13 02:44:15 +00:00
756 changed files with 141141 additions and 104276 deletions

View File

@@ -0,0 +1,549 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIDOMComment.h"
#include "nsGenericDOMDataNode.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIContent.h"
#include "nsFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIDOMSelection.h"
#include "nsIXIFConverter.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);
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
class nsCommentNode : public nsIDOMComment,
public nsIScriptObjectOwner,
public nsITextContent
{
public:
nsCommentNode();
virtual ~nsCommentNode();
// nsISupports
NS_DECL_ISUPPORTS
// nsIDOMNode
NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(mInner)
// nsIDOMCharacterData
NS_IMPL_IDOMCHARACTERDATA_USING_GENERIC_DOM_DATA(mInner)
// nsIDOMComment
// nsIScriptObjectOwner
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(mInner)
// nsIContent
//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, PRBool aCompileEventHandlers) {
return mInner.SetDocument(aDocument, aDeep, aCompileEventHandlers);
}
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 GetNodeInfo(nsINodeInfo*& aResult) const {
aResult = nsnull; return NS_OK;
}
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 GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute,
nsIAtom*& aPrefix, nsString &aResult) const {
return mInner.GetAttribute(aNameSpaceID, aAttribute, aPrefix, aResult);
}
NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
const nsString& aValue, PRBool aNotify) {
return mInner.SetAttribute(aNameSpaceID, aAttribute, aValue, aNotify);
}
NS_IMETHOD SetAttribute(nsINodeInfo* aNodeInfo,
const nsString& aValue, PRBool aNotify) {
return mInner.SetAttribute(aNodeInfo, 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,
nsIAtom*& aPrefix) const {
return mInner.GetAttributeNameAt(aIndex, aNameSpaceID, aName, aPrefix);
}
NS_IMETHOD GetAttributeCount(PRInt32& aResult) const {
return mInner.GetAttributeCount(aResult);
}
NS_IMETHOD List(FILE* out, PRInt32 aIndent) const;
NS_IMETHOD DumpContent(FILE* out = stdout, PRInt32 aIndent = 0,PRBool aDumpAll=PR_TRUE) const {
return NS_OK;
}
NS_IMETHOD BeginConvertToXIF(nsIXIFConverter* aConverter) const {
return mInner.BeginConvertToXIF(aConverter);
}
NS_IMETHOD ConvertContentToXIF(nsIXIFConverter* aConverter) const;
NS_IMETHOD FinishConvertToXIF(nsIXIFConverter* aConverter) const {
return mInner.FinishConvertToXIF(aConverter);
}
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
NS_IMETHOD GetContentID(PRUint32* aID) {
*aID = mContentID;
return NS_OK;
}
NS_IMETHOD SetContentID(PRUint32 aID) {
mContentID = aID;
return NS_OK;
}
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);
}
NS_IMETHOD SetFocus(nsIPresContext* aContext) {
return mInner.SetFocus(aContext);
}
NS_IMETHOD RemoveFocus(nsIPresContext* aContext) {
return mInner.RemoveFocus(aContext);
}
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const {
if (!aResult) {
return NS_ERROR_NULL_POINTER;
}
#ifdef DEBUG
*aResult = sizeof(*this);
#else
*aResult = 0;
#endif
return NS_OK;
}
NS_IMETHOD GetText(const nsTextFragment** aFragmentsResult)
{ return mInner.GetText(aFragmentsResult); }
NS_IMETHOD GetTextLength(PRInt32* aLengthResult) {
return mInner.GetTextLength(aLengthResult);
}
NS_IMETHOD CopyText(nsString& aResult) {
return mInner.CopyText(aResult);
}
NS_IMETHOD SetText(const PRUnichar* aBuffer,
PRInt32 aLength,
PRBool aNotify);
NS_IMETHOD SetText(const char* aBuffer,
PRInt32 aLength,
PRBool aNotify);
NS_IMETHOD IsOnlyWhitespace(PRBool* aResult)
{ return mInner.IsOnlyWhitespace(aResult); }
NS_IMETHOD CloneContent(PRBool aCloneText, nsITextContent** aClone);
protected:
nsGenericDOMDataNode mInner;
PRUint32 mContentID;
};
nsresult
NS_NewCommentNode(nsIContent** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIContent* it = new nsCommentNode();
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIContentIID, (void **) aInstancePtrResult);
}
nsCommentNode::nsCommentNode()
{
NS_INIT_REFCNT();
mContentID = 0;
}
nsCommentNode::~nsCommentNode()
{
}
NS_IMPL_ADDREF(nsCommentNode)
NS_IMPL_RELEASE(nsCommentNode)
NS_IMETHODIMP
nsCommentNode::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_DOM_DATA_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMCommentIID)) {
nsIDOMComment* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kITextContentIID)) {
nsITextContent* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsCommentNode::GetTag(nsIAtom*& aResult) const
{
aResult = nsLayoutAtoms::commentTagName;
NS_ADDREF(aResult);
return NS_OK;
}
NS_IMETHODIMP
nsCommentNode::GetNodeName(nsString& aNodeName)
{
aNodeName.AssignWithConversion("#comment");
return NS_OK;
}
NS_IMETHODIMP
nsCommentNode::GetNodeType(PRUint16* aNodeType)
{
*aNodeType = (PRUint16)nsIDOMNode::COMMENT_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsCommentNode::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsresult result = NS_OK;
nsCommentNode* it = new nsCommentNode();
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
// XXX Increment the ref count before calling any
// methods. If they do a QI and then a Release()
// the instance will be deleted.
result = it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
if (NS_FAILED(result)) {
return result;
}
nsAutoString data;
result = GetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
result = it->SetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
return result;
}
NS_IMETHODIMP
nsCommentNode::CloneContent(PRBool aCloneText, nsITextContent** aReturn)
{
nsresult result = NS_OK;
nsCommentNode* it;
NS_NEWXPCOM(it, nsCommentNode);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
result = it->QueryInterface(kITextContentIID, (void**) aReturn);
if (NS_FAILED(result) || !aCloneText) {
return result;
}
nsAutoString data;
result = GetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
result = it->SetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
return result;
}
NS_IMETHODIMP
nsCommentNode::List(FILE* out, PRInt32 aIndent) const
{
NS_PRECONDITION(nsnull != mInner.mDocument, "bad content");
PRInt32 indx;
for (indx = aIndent; --indx >= 0; ) fputs(" ", out);
fprintf(out, "Comment@%p refcount=%d<!--", this, mRefCnt);
nsAutoString tmp;
mInner.ToCString(tmp, 0, mInner.mText.GetLength());
fputs(tmp, out);
fputs("-->\n", out);
return NS_OK;
}
NS_IMETHODIMP
nsCommentNode::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
nsresult NS_NewCommentFrame(nsIPresShell* aPresShell, nsIFrame*& aResult);
nsresult
NS_NewCommentFrame(nsIPresShell* aPresShell, nsIFrame*& aResult)
{
nsIFrame* frame;
NS_NewEmptyFrame(aPresShell, &frame);
if (nsnull == frame) {
return NS_ERROR_OUT_OF_MEMORY;
}
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(nsIXIFConverter* aConverter) const
{
const nsIContent* content = this;
nsCOMPtr<nsIDOMSelection> sel;
aConverter->GetSelection(getter_AddRefs(sel));
nsIDocument* document;
nsresult res;
res = GetDocument(document);
if (!NS_SUCCEEDED(res))
return res;
const nsTextFragment* textFrag;
// XXX This method is const, but GetText() isn't,
// XXX so cast away the constness of mInner:
nsGenericDOMDataNode* inner = (nsGenericDOMDataNode*)&mInner;
res = inner->GetText(&textFrag);
if (!NS_SUCCEEDED(res))
return res;
if (sel != nsnull && document->IsInSelection(sel,content))
{
nsIEnumerator *enumerator;
if (NS_SUCCEEDED(sel->GetEnumerator(&enumerator))) {
for (enumerator->First();NS_OK != enumerator->IsDone(); enumerator->Next()) {
nsIDOMRange* range = nsnull;
if (NS_SUCCEEDED(enumerator->CurrentItem((nsISupports**)&range))) {
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode;
PRInt32 startOffset = 0;
PRInt32 endOffset = 0;
range->GetStartParent(getter_AddRefs(startNode));
range->GetEndParent(getter_AddRefs(endNode));
range->GetStartOffset(&startOffset);
range->GetEndOffset(&endOffset);
nsCOMPtr<nsIContent> startContent;
nsCOMPtr<nsIContent> 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->AddContentComment(buffer);
}
}
}
}
else
{
nsString buffer;
textFrag->AppendTo(buffer);
aConverter->AddContentComment(buffer);
}
NS_IF_RELEASE(document);
// XXX Possible mem leak: Do we need to delete textFrag?
return NS_OK;
}
#if 0
nsresult
nsCommentNode::BeginConvertToXIF(nsIXIFConverter* aConverter) const
{
return NS_OK;
}
nsresult
nsCommentNode::FinishConvertToXIF(nsIXIFConverter* aConverter) const
{
return NS_OK;
}
#endif
// This would ideally be done by the parser, but for the sake
// of "genericity" it's being done in the comment content code
static void
StripCommentDelimiters(nsString& aCommentString)
{
PRInt32 offset;
static char* kCommentStart = "<!";
static char* kCommentEnd = "->";
static char* kCommentAlternateEnd = "--!>";
static char kMinus = '-';
offset = aCommentString.Find(kCommentStart);
if (-1 != offset) {
// Take up to 2 '-' characters
offset += strlen(kCommentStart);
if (kMinus == aCommentString.CharAt(offset)) {
offset++;
if (kMinus == aCommentString.CharAt(offset)) {
offset++;
}
}
aCommentString.Cut(0, offset);
}
offset = aCommentString.RFind(kCommentEnd);
if (-1 != offset) {
// Take up to 1 more '-'
if (kMinus == aCommentString.CharAt(offset-1)) {
offset--;
}
aCommentString.Cut(offset, aCommentString.Length()-offset);
}
else {
offset = aCommentString.RFind(kCommentAlternateEnd);
if (-1 != offset) {
aCommentString.Cut(offset, aCommentString.Length()-offset);
}
}
}
NS_IMETHODIMP
nsCommentNode::SetText(const PRUnichar* aBuffer,
PRInt32 aLength,
PRBool aNotify)
{
nsAutoString str(aBuffer);
StripCommentDelimiters(str);
return mInner.SetText(this, str.GetUnicode(), str.Length(), aNotify);
}
NS_IMETHODIMP
nsCommentNode::SetText(const char* aBuffer,
PRInt32 aLength,
PRBool aNotify)
{
nsAutoString str; str.AssignWithConversion(aBuffer);
StripCommentDelimiters(str);
return mInner.SetText(this, str.GetUnicode(), str.Length(), aNotify);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,566 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsContentList.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDocument.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsGenericElement.h"
#include "nsLayoutAtoms.h"
#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms
nsContentList::nsContentList(nsIDocument *aDocument)
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
mFunc = nsnull;
mMatchAtom = nsnull;
mDocument = aDocument;
mData = nsnull;
mMatchAll = PR_FALSE;
mRootContent = nsnull;
}
nsContentList::nsContentList(nsIDocument *aDocument,
nsIAtom* aMatchAtom,
PRInt32 aMatchNameSpaceId,
nsIContent* aRootContent)
{
mMatchAtom = aMatchAtom;
NS_IF_ADDREF(mMatchAtom);
if (nsLayoutAtoms::wildcard == mMatchAtom) {
mMatchAll = PR_TRUE;
}
else {
mMatchAll = PR_FALSE;
}
mMatchNameSpaceId = aMatchNameSpaceId;
mFunc = nsnull;
mData = nsnull;
mRootContent = aRootContent;
Init(aDocument);
}
nsContentList::nsContentList(nsIDocument *aDocument,
nsContentListMatchFunc aFunc,
const nsString* aData,
nsIContent* aRootContent)
{
mFunc = aFunc;
if (nsnull != aData) {
mData = new nsString(*aData);
// If this fails, fail silently
}
else {
mData = nsnull;
}
mMatchAtom = nsnull;
mRootContent = aRootContent;
mMatchAll = PR_FALSE;
Init(aDocument);
}
void nsContentList::Init(nsIDocument *aDocument)
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
// We don't reference count the reference to the document
// If the document goes away first, we'll be informed and we
// can drop our reference.
// If we go away first, we'll get rid of ourselves from the
// document's observer list.
mDocument = aDocument;
if (nsnull != mDocument) {
mDocument->AddObserver(this);
}
PopulateSelf();
}
nsContentList::~nsContentList()
{
if (nsnull != mDocument) {
mDocument->RemoveObserver(this);
}
NS_IF_RELEASE(mMatchAtom);
if (nsnull != mData) {
delete mData;
}
}
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
nsresult nsContentList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIDOMNodeListIID)) {
*aInstancePtr = (void*)(nsIDOMNodeList*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMHTMLCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLCollection*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMNodeList*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsContentList)
NS_IMPL_RELEASE(nsContentList)
NS_IMETHODIMP
nsContentList::GetLength(PRUint32* aLength)
{
nsresult result = CheckDocumentExistence();
if (NS_OK == result) {
*aLength = mContent.Count();
}
return result;
}
NS_IMETHODIMP
nsContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
nsresult result = CheckDocumentExistence();
if (NS_OK == result) {
if (nsnull != mDocument) {
mDocument->FlushPendingNotifications(); // Flush pending content changes Bug 4891
}
nsISupports *element = (nsISupports *)mContent.ElementAt(aIndex);
if (nsnull != element) {
result = element->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
else {
*aReturn = nsnull;
}
}
return result;
}
NS_IMETHODIMP
nsContentList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
nsresult result = CheckDocumentExistence();
if (NS_OK == result) {
if (nsnull != mDocument) {
mDocument->FlushPendingNotifications(); // Flush pending content changes Bug 4891
}
PRInt32 i, count = mContent.Count();
for (i = 0; i < count; i++) {
nsIContent *content = (nsIContent *)mContent.ElementAt(i);
if (nsnull != content) {
nsAutoString name;
// XXX Should it be an EqualsIgnoreCase?
if (((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name))) ||
((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name)))) {
return content->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
}
}
}
*aReturn = nsnull;
return result;
}
NS_IMETHODIMP
nsContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = nsGenericElement::GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptHTMLCollection(aContext,
(nsISupports*)(nsIDOMHTMLCollection*)this,
global,
(void**)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return res;
}
NS_IMETHODIMP
nsContentList::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
NS_IMETHODIMP
nsContentList::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
PRInt32 i, count;
aContainer->ChildCount(count);
if ((count > 0) && IsDescendantOfRoot(aContainer)) {
PRBool repopulate = PR_FALSE;
for (i = aNewIndexInContainer; i <= count-1; i++) {
nsIContent *content;
aContainer->ChildAt(i, content);
if (mMatchAll || MatchSelf(content)) {
repopulate = PR_TRUE;
}
NS_RELEASE(content);
}
if (repopulate) {
PopulateSelf();
}
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
if (IsDescendantOfRoot(aContainer)) {
if (mMatchAll || MatchSelf(aChild)) {
PopulateSelf();
}
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
if (IsDescendantOfRoot(aContainer)) {
if (mMatchAll || MatchSelf(aOldChild) || MatchSelf(aNewChild)) {
PopulateSelf();
}
}
else if (ContainsRoot(aOldChild)) {
DisconnectFromDocument();
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
if (IsDescendantOfRoot(aContainer) && MatchSelf(aChild)) {
PopulateSelf();
}
else if (ContainsRoot(aChild)) {
DisconnectFromDocument();
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::DocumentWillBeDestroyed(nsIDocument *aDocument)
{
if (nsnull != mDocument) {
aDocument->RemoveObserver(this);
mDocument = nsnull;
}
Reset();
return NS_OK;
}
// Returns whether the content element matches the
// criterion
nsresult
nsContentList::Match(nsIContent *aContent, PRBool *aMatch)
{
*aMatch = PR_FALSE;
if (!aContent) {
return NS_OK;
}
if (mMatchAtom) {
nsCOMPtr<nsINodeInfo> ni;
aContent->GetNodeInfo(*getter_AddRefs(ni));
if (!ni)
return NS_OK;
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aContent));
if (!node)
return NS_OK;
PRUint16 type;
node->GetNodeType(&type);
if (type != nsIDOMNode::ELEMENT_NODE)
return NS_OK;
if (mMatchNameSpaceId == kNameSpaceID_Unknown) {
if (mMatchAll || ni->Equals(mMatchAtom)) {
*aMatch = PR_TRUE;
}
} else if ((mMatchAll && ni->NamespaceEquals(mMatchNameSpaceId)) ||
ni->Equals(mMatchAtom, mMatchNameSpaceId)) {
*aMatch = PR_TRUE;
}
}
else if (nsnull != mFunc) {
*aMatch = (*mFunc)(aContent, mData);
}
return NS_OK;
}
nsresult
nsContentList::Add(nsIContent *aContent)
{
// Shouldn't hold a reference since we'll be
// told when the content leaves the document or
// the document will be destroyed.
mContent.AppendElement(aContent);
return NS_OK;
}
nsresult
nsContentList::Remove(nsIContent *aContent)
{
mContent.RemoveElement(aContent);
return NS_OK;
}
nsresult
nsContentList::IndexOf(nsIContent *aContent, PRInt32& aIndex)
{
aIndex = mContent.IndexOf(aContent);
return NS_OK;
}
nsresult
nsContentList::Reset()
{
mContent.Clear();
return NS_OK;
}
// If we were created outside the context of a document and we
// have root content, then check if our content has been added
// to a document yet. If so, we'll become an observer of the document.
nsresult
nsContentList::CheckDocumentExistence()
{
nsresult result = NS_OK;
if ((nsnull == mDocument) && (nsnull != mRootContent)) {
result = mRootContent->GetDocument(mDocument);
if (nsnull != mDocument) {
mDocument->AddObserver(this);
PopulateSelf();
}
}
return result;
}
// Match recursively. See if anything in the subtree
// matches the criterion.
PRBool
nsContentList::MatchSelf(nsIContent *aContent)
{
PRBool match;
PRInt32 i, count;
Match(aContent, &match);
if (match) {
return PR_TRUE;
}
aContent->ChildCount(count);
for (i = 0; i < count; i++) {
nsIContent *child;
aContent->ChildAt(i, child);
if (MatchSelf(child)) {
NS_RELEASE(child);
return PR_TRUE;
}
NS_RELEASE(child);
}
return PR_FALSE;
}
// Add all elements in this subtree that match to
// our list.
void
nsContentList::PopulateWith(nsIContent *aContent, PRBool aIncludeRoot)
{
PRBool match;
PRInt32 i, count;
if (aIncludeRoot) {
Match(aContent, &match);
if (match) {
Add(aContent);
}
}
aContent->ChildCount(count);
for (i = 0; i < count; i++) {
nsIContent *child;
aContent->ChildAt(i, child);
PopulateWith(child, PR_TRUE);
NS_RELEASE(child);
}
}
// Clear out our old list and build up a new one
void
nsContentList::PopulateSelf()
{
Reset();
if (nsnull != mRootContent) {
PopulateWith(mRootContent, PR_FALSE);
}
else if (nsnull != mDocument) {
nsIContent *root;
root = mDocument->GetRootContent();
PopulateWith(root, PR_TRUE);
NS_RELEASE(root);
}
}
// Is the specified element a descendant of the root? If there
// is no root, then yes. Otherwise keep tracing up the tree from
// the element till we find our root, or until we reach the
// document root.
PRBool
nsContentList::IsDescendantOfRoot(nsIContent* aContainer)
{
if (nsnull == mRootContent) {
return PR_TRUE;
}
else if (mRootContent == aContainer) {
return PR_TRUE;
}
else if (nsnull == aContainer) {
return PR_FALSE;
}
else {
nsIContent* parent;
PRBool ret;
aContainer->GetParent(parent);
ret = IsDescendantOfRoot(parent);
NS_IF_RELEASE(parent);
return ret;
}
}
// Does this subtree contain the root?
PRBool
nsContentList::ContainsRoot(nsIContent* aContent)
{
if (nsnull == mRootContent) {
return PR_FALSE;
}
else if (mRootContent == aContent) {
return PR_TRUE;
}
else {
PRInt32 i, count;
aContent->ChildCount(count);
for (i = 0; i < count; i++) {
nsIContent *child;
aContent->ChildAt(i, child);
if (ContainsRoot(child)) {
NS_RELEASE(child);
return PR_TRUE;
}
NS_RELEASE(child);
}
return PR_FALSE;
}
}
// Our root content has been disconnected from the
// document, so stop observing. The list then becomes
// a snapshot rather than a dynamic list.
void
nsContentList::DisconnectFromDocument()
{
if (nsnull != mDocument) {
mDocument->RemoveObserver(this);
mDocument = nsnull;
}
}

View File

@@ -0,0 +1,148 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsContentList_h___
#define nsContentList_h___
#include "nsISupports.h"
#include "nsVoidArray.h"
#include "nsString.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMNodeList.h"
#include "nsIDocumentObserver.h"
#include "nsIScriptObjectOwner.h"
typedef PRBool (*nsContentListMatchFunc)(nsIContent* aContent, nsString* aData);
class nsIDocument;
class nsContentList : public nsIDOMNodeList,
public nsIDOMHTMLCollection,
public nsIScriptObjectOwner,
public nsIDocumentObserver {
public:
nsContentList(nsIDocument *aDocument);
nsContentList(nsIDocument *aDocument,
nsIAtom* aMatchAtom,
PRInt32 aMatchNameSpaceId,
nsIContent* aRootContent=nsnull);
nsContentList(nsIDocument *aDocument,
nsContentListMatchFunc aFunc,
const nsString* aData,
nsIContent* aRootContent=nsnull);
virtual ~nsContentList();
NS_DECL_ISUPPORTS
// nsIDOMHTMLCollection
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn);
// nsIScriptObjectOwner
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIDocumentObserver
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD EndReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent1,
nsIContent* aContent2) { return NS_OK; }
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint) { return NS_OK; }
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
PRBool aDisabled) { return NS_OK; }
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint) { return NS_OK; }
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
nsresult Add(nsIContent *aContent);
nsresult Remove(nsIContent *aContent);
nsresult IndexOf(nsIContent *aContent, PRInt32& aIndex);
protected:
nsresult Match(nsIContent *aContent, PRBool *aMatch);
nsresult Reset();
void Init(nsIDocument *aDocument);
void PopulateWith(nsIContent *aContent, PRBool aIncludeRoot);
PRBool MatchSelf(nsIContent *aContent);
void PopulateSelf();
void DisconnectFromDocument();
PRBool IsDescendantOfRoot(nsIContent* aContainer);
PRBool ContainsRoot(nsIContent* aContent);
nsresult CheckDocumentExistence();
nsIAtom* mMatchAtom;
PRInt32 mMatchNameSpaceId;
nsContentListMatchFunc mFunc;
nsString* mData;
nsVoidArray mContent;
void *mScriptObject;
nsIDocument* mDocument;
nsIContent* mRootContent;
PRBool mMatchAll;
};
#endif // nsContentList_h___

View File

@@ -0,0 +1,176 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla code.
*
* The Initial Developer of the Original Code is Zero-Knowledge Systems,
* Inc. Portions created by Zero-Knowledge are Copyright (C) 2000
* Zero-Knowledge Systems, Inc. All Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.h"
#include "nsISupportsPrimitives.h"
#include "nsXPIDLString.h"
#include "nsContentPolicyUtils.h"
#include "nsContentPolicy.h"
#include "nsICategoryManager.h"
NS_IMPL_ISUPPORTS1(nsContentPolicy, nsIContentPolicy)
nsresult
NS_NewContentPolicy(nsIContentPolicy **aResult)
{
*aResult = new nsContentPolicy;
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
/*
* This constructor does far too much. I wish there was a way to get
* an Init method called by the service manager after the factory
* returned the new object, so that errors could be propagated back to
* the caller correctly.
*/
nsContentPolicy::nsContentPolicy()
{
NS_INIT_REFCNT();
nsresult rv;
NS_WITH_SERVICE(nsICategoryManager, catman, NS_CATEGORYMANAGER_PROGID, &rv);
if (NS_FAILED(rv))
/* log an error? */
return;
/*
* I'd like to use GetCategoryContents, so that I can size the array
* correctly on the first go and avoid the enumerator overhead, but it's
* not yet implemented (see nsCategoryManager.cpp). No biggie, I guess.
*/
nsCOMPtr<nsISimpleEnumerator> catEnum;
if (NS_FAILED(catman->EnumerateCategory(NS_CONTENTPOLICY_CATEGORY,
getter_AddRefs(catEnum)))) {
/* no category, no problem */
return;
}
PRBool hasMore;
if (NS_FAILED(catEnum->HasMoreElements(&hasMore)) || !hasMore ||
NS_FAILED(NS_NewISupportsArray(getter_AddRefs(mPolicies)))) {
return;
}
/*
* Populate mPolicies with policy services named by progids in the
* "content-policy" category.
*/
nsCOMPtr<nsISupports> item;
while (NS_SUCCEEDED(catEnum->GetNext(getter_AddRefs(item)))) {
nsCOMPtr<nsISupportsString> string = do_QueryInterface(item, &rv);
if (NS_FAILED(rv))
continue;
nsXPIDLCString progid;
if (NS_FAILED(string->GetData(getter_Copies(progid))))
continue;
#ifdef DEBUG_shaver
fprintf(stderr, "POLICY: loading %s\n", (const char *)progid);
#endif
/*
* Create this policy service and add to mPolicies.
*
* Should we try to parse as a CID, in case the component prefers to be
* registered that way?
*/
nsCOMPtr<nsISupports> policy = do_GetService(progid, &rv);
if (NS_SUCCEEDED(rv))
mPolicies->AppendElement(policy);
}
}
nsContentPolicy::~nsContentPolicy()
{
}
#define POLICY_LOAD 0
#define POLICY_PROCESS 1
NS_IMETHODIMP
nsContentPolicy::CheckPolicy(PRInt32 policyType, PRInt32 contentType,
nsIDOMElement *element,
const PRUnichar *contentLocation,
PRBool *shouldProceed)
{
*shouldProceed = PR_TRUE;
if (!mPolicies)
return NS_OK;
/*
* Enumerate mPolicies and ask each of them, taking the logical AND of
* their permissions.
*/
nsresult rv;
nsCOMPtr<nsIContentPolicy> policy;
PRUint32 count;
if (NS_FAILED(rv = mPolicies->Count(&count)))
return NS_OK;
for (PRUint32 i = 0; i < count; i++) {
rv = mPolicies->QueryElementAt(i, NS_GET_IID(nsIContentPolicy),
getter_AddRefs(policy));
if (NS_FAILED(rv))
continue;
/* check the appropriate policy */
if (policyType == POLICY_LOAD)
rv = policy->ShouldLoad(contentType, element, contentLocation,
shouldProceed);
else
rv = policy->ShouldProcess(contentType, element, contentLocation,
shouldProceed);
if (NS_SUCCEEDED(rv) && !*shouldProceed)
/* policy says no, no point continuing to check */
return NS_OK;
}
/*
* One of the policy objects might be misbehaving and setting shouldProceed
* to PR_FALSE before returning an error, so force it back to PR_TRUE
* here.
*/
*shouldProceed = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsContentPolicy::ShouldLoad(PRInt32 contentType, nsIDOMElement *element,
const PRUnichar *contentLocation,
PRBool *shouldLoad)
{
return CheckPolicy(POLICY_LOAD, contentType, element, contentLocation,
shouldLoad);
}
NS_IMETHODIMP
nsContentPolicy::ShouldProcess(PRInt32 contentType, nsIDOMElement *element,
const PRUnichar *contentLocation,
PRBool *shouldProcess)
{
return CheckPolicy(POLICY_PROCESS, contentType, element, contentLocation,
shouldProcess);
}

View File

@@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla code.
*
* The Initial Developer of the Original Code is Zero-Knowledge Systems,
* Inc. Portions created by Zero-Knowledge are Copyright (C) 2000
* Zero-Knowledge Systems, Inc. All Rights Reserved.
*
* Contributor(s):
*/
#include "nsIContentPolicy.h"
#include "nsISupportsArray.h"
#ifndef __nsContentPolicy_h__
#define __nsContentPolicy_h__
class nsContentPolicy : public nsIContentPolicy
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICONTENTPOLICY
nsContentPolicy();
virtual ~nsContentPolicy();
private:
nsCOMPtr<nsISupportsArray> mPolicies;
NS_IMETHOD CheckPolicy(PRInt32 policyType, PRInt32 contentType,
nsIDOMElement *element,
const PRUnichar *contentLocation,
PRBool *shouldProceed);
};
nsresult
NS_NewContentPolicy(nsIContentPolicy **aResult);
#endif /* __nsContentPolicy_h__ */

View File

@@ -0,0 +1,568 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsDOMAttribute.h"
#include "nsGenericElement.h"
#include "nsIContent.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsITextContent.h"
#include "nsINameSpaceManager.h"
static NS_DEFINE_IID(kIDOMAttrIID, NS_IDOMATTR_IID);
static NS_DEFINE_IID(kIDOMAttributePrivateIID, NS_IDOMATTRIBUTEPRIVATE_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
//----------------------------------------------------------------------
nsDOMAttribute::nsDOMAttribute(nsIContent* aContent,
nsINodeInfo *aNodeInfo,
const nsString& aValue)
: mNodeInfo(aNodeInfo), mValue(aValue)
{
NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
NS_INIT_REFCNT();
// We don't add a reference to our content. It will tell us
// to drop our reference when it goes away.
mContent = aContent;
mScriptObject = nsnull;
mChild = nsnull;
mChildList = nsnull;
}
nsDOMAttribute::~nsDOMAttribute()
{
NS_IF_RELEASE(mChild);
NS_IF_RELEASE(mChildList);
}
nsresult
nsDOMAttribute::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIDOMAttrIID)) {
nsIDOMAttr* tmp = this;
*aInstancePtr = (void*)tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
nsIScriptObjectOwner* tmp = this;
*aInstancePtr = (void*)tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMAttributePrivateIID)) {
nsIDOMAttributePrivate* tmp = this;
*aInstancePtr = (void*)tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMNodeIID)) {
nsIDOMNode* tmp = this;
*aInstancePtr = (void*)tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
nsIDOMAttr* tmp1 = this;
nsISupports* tmp2 = tmp1;
*aInstancePtr = (void*)tmp2;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsDOMAttribute)
NS_IMPL_RELEASE(nsDOMAttribute)
NS_IMETHODIMP
nsDOMAttribute::DropReference()
{
mContent = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::SetContent(nsIContent* aContent)
{
mContent = aContent;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetContent(nsIContent** aContent)
{
*aContent = mContent;
NS_IF_ADDREF(*aContent);
return NS_OK;
}
nsresult
nsDOMAttribute::GetScriptObject(nsIScriptContext *aContext,
void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = nsGenericElement::GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptAttr(aContext,
(nsISupports *)(nsIDOMAttr *)this,
(nsISupports *)mContent,
(void **)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
return res;
}
nsresult
nsDOMAttribute::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
nsresult
nsDOMAttribute::GetName(nsString& aName)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
return mNodeInfo->GetQualifiedName(aName);
}
nsresult
nsDOMAttribute::GetValue(nsString& aValue)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
nsresult result = NS_OK;
if (nsnull != mContent) {
nsresult attrResult;
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> name;
mNodeInfo->GetNameAtom(*getter_AddRefs(name));
mNodeInfo->GetNamespaceID(nameSpaceID);
nsAutoString tmpValue;
attrResult = mContent->GetAttribute(nameSpaceID, name, tmpValue);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult) {
mValue = tmpValue;
}
}
aValue=mValue;
return result;
}
nsresult
nsDOMAttribute::SetValue(const nsString& aValue)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
nsresult result = NS_OK;
if (nsnull != mContent) {
result = mContent->SetAttribute(mNodeInfo, aValue, PR_TRUE);
}
mValue=aValue;
return result;
}
nsresult
nsDOMAttribute::GetSpecified(PRBool* aSpecified)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
NS_ENSURE_ARG_POINTER(aSpecified);
nsresult result = NS_OK;
if (nsnull == mContent) {
*aSpecified = PR_FALSE;
} else {
nsAutoString value;
nsresult attrResult;
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> name;
mNodeInfo->GetNameAtom(*getter_AddRefs(name));
mNodeInfo->GetNamespaceID(nameSpaceID);
attrResult = mContent->GetAttribute(nameSpaceID, name, value);
if (NS_CONTENT_ATTR_HAS_VALUE == attrResult) {
*aSpecified = PR_TRUE;
}
else {
*aSpecified = PR_FALSE;
}
}
return result;
}
NS_IMETHODIMP
nsDOMAttribute::GetOwnerElement(nsIDOMElement** aOwnerElement)
{
NS_ENSURE_ARG_POINTER(aOwnerElement);
if (mContent) {
return mContent->QueryInterface(NS_GET_IID(nsIDOMElement),
(void **)aOwnerElement);
}
*aOwnerElement = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetNodeName(nsString& aNodeName)
{
return GetName(aNodeName);
}
NS_IMETHODIMP
nsDOMAttribute::GetNodeValue(nsString& aNodeValue)
{
return GetValue(aNodeValue);
}
NS_IMETHODIMP
nsDOMAttribute::SetNodeValue(const nsString& aNodeValue)
{
return SetValue(aNodeValue);
}
NS_IMETHODIMP
nsDOMAttribute::GetNodeType(PRUint16* aNodeType)
{
NS_ENSURE_ARG_POINTER(aNodeType);
*aNodeType = (PRUint16)nsIDOMNode::ATTRIBUTE_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetParentNode(nsIDOMNode** aParentNode)
{
NS_ENSURE_ARG_POINTER(aParentNode);
*aParentNode = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetChildNodes(nsIDOMNodeList** aChildNodes)
{
if (nsnull == mChildList) {
mChildList = new nsAttributeChildList(this);
if (nsnull == mChildList) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mChildList);
}
return mChildList->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes);
}
NS_IMETHODIMP
nsDOMAttribute::HasChildNodes(PRBool* aHasChildNodes)
{
*aHasChildNodes = PR_FALSE;
if (nsnull != mChild) {
*aHasChildNodes = PR_TRUE;
}
else if (nsnull != mContent) {
nsAutoString value;
GetValue(value);
if (0 < value.Length()) {
*aHasChildNodes = PR_TRUE;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetFirstChild(nsIDOMNode** aFirstChild)
{
nsAutoString value;
nsresult result;
result = GetValue(value);
if (NS_OK != result) {
return result;
}
if (0 < value.Length()) {
if (nsnull == mChild) {
nsIContent* content;
result = NS_NewTextNode(&content);
if (NS_OK != result) {
return result;
}
result = content->QueryInterface(kIDOMTextIID, (void**)&mChild);
NS_RELEASE(content);
}
mChild->SetData(value);
result = mChild->QueryInterface(kIDOMNodeIID, (void**)aFirstChild);
}
else {
*aFirstChild = nsnull;
}
return result;
}
NS_IMETHODIMP
nsDOMAttribute::GetLastChild(nsIDOMNode** aLastChild)
{
return GetFirstChild(aLastChild);
}
NS_IMETHODIMP
nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
{
NS_ENSURE_ARG_POINTER(aPreviousSibling);
*aPreviousSibling = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling)
{
NS_ENSURE_ARG_POINTER(aNextSibling);
*aNextSibling = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
{
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMAttribute::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMAttribute::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMAttribute::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMAttribute::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsDOMAttribute* newAttr;
if (nsnull != mContent) {
nsAutoString value;
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> name;
mNodeInfo->GetNameAtom(*getter_AddRefs(name));
mNodeInfo->GetNamespaceID(nameSpaceID);
mContent->GetAttribute(nameSpaceID, name, value);
newAttr = new nsDOMAttribute(nsnull, mNodeInfo, value);
}
else {
newAttr = new nsDOMAttribute(nsnull, mNodeInfo, mValue);
}
if (nsnull == newAttr) {
return NS_ERROR_OUT_OF_MEMORY;
}
return newAttr->QueryInterface(kIDOMNodeIID, (void**)aReturn);
}
NS_IMETHODIMP
nsDOMAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
{
nsresult result = NS_OK;
if (nsnull != mContent) {
nsIDOMNode* node;
result = mContent->QueryInterface(kIDOMNodeIID, (void**)&node);
if (NS_SUCCEEDED(result)) {
result = node->GetOwnerDocument(aOwnerDocument);
NS_RELEASE(node);
}
}
else {
*aOwnerDocument = nsnull;
}
return result;
}
NS_IMETHODIMP
nsDOMAttribute::GetNamespaceURI(nsString& aNamespaceURI)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
return mNodeInfo->GetNamespaceURI(aNamespaceURI);
}
NS_IMETHODIMP
nsDOMAttribute::GetPrefix(nsString& aPrefix)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
return mNodeInfo->GetPrefix(aPrefix);
}
NS_IMETHODIMP
nsDOMAttribute::SetPrefix(const nsString& aPrefix)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfo> newNodeInfo;
nsCOMPtr<nsIAtom> prefix;
nsresult rv = NS_OK;
if (aPrefix.Length())
prefix = dont_AddRef(NS_NewAtom(aPrefix));
rv = mNodeInfo->PrefixChanged(prefix, *getter_AddRefs(newNodeInfo));
NS_ENSURE_SUCCESS(rv, rv);
if (mContent) {
nsCOMPtr<nsIAtom> name;
PRInt32 nameSpaceID;
nsAutoString tmpValue;
mNodeInfo->GetNameAtom(*getter_AddRefs(name));
mNodeInfo->GetNamespaceID(nameSpaceID);
rv = mContent->GetAttribute(nameSpaceID, name, tmpValue);
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
mContent->UnsetAttribute(nameSpaceID, name, PR_TRUE);
mContent->SetAttribute(newNodeInfo, tmpValue, PR_TRUE);
}
}
mNodeInfo = newNodeInfo;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetLocalName(nsString& aLocalName)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
return mNodeInfo->GetLocalName(aLocalName);
}
NS_IMETHODIMP
nsDOMAttribute::Normalize()
{
// Nothing to do here
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::Supports(const nsString& aFeature, const nsString& aVersion,
PRBool* aReturn)
{
return nsGenericElement::InternalSupports(aFeature, aVersion, aReturn);
}
//----------------------------------------------------------------------
nsAttributeChildList::nsAttributeChildList(nsDOMAttribute* aAttribute)
{
// Don't increment the reference count. The attribute will tell
// us when it's going away
mAttribute = aAttribute;
}
nsAttributeChildList::~nsAttributeChildList()
{
}
NS_IMETHODIMP
nsAttributeChildList::GetLength(PRUint32* aLength)
{
nsAutoString value;
*aLength = 0;
if (nsnull != mAttribute) {
mAttribute->GetValue(value);
if (0 < value.Length()) {
*aLength = 1;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsAttributeChildList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
*aReturn = nsnull;
if ((nsnull != mAttribute) && (0 == aIndex)) {
mAttribute->GetFirstChild(aReturn);
}
return NS_OK;
}
void
nsAttributeChildList::DropReference()
{
mAttribute = nsnull;
}

View File

@@ -0,0 +1,105 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDOMAttribute_h___
#define nsDOMAttribute_h___
#include "nsIDOMAttr.h"
#include "nsIDOMText.h"
#include "nsIDOMNodeList.h"
#include "nsIScriptObjectOwner.h"
#include "nsGenericDOMNodeList.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsINodeInfo.h"
class nsIContent;
class nsDOMAttribute;
#define NS_IDOMATTRIBUTEPRIVATE_IID \
{0xa6cf90dd, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
class nsIDOMAttributePrivate : public nsISupports {
public:
NS_IMETHOD DropReference() = 0;
NS_IMETHOD SetContent(nsIContent* aContent) = 0;
NS_IMETHOD GetContent(nsIContent** aContent) = 0;
};
// bogus child list for an attribute
class nsAttributeChildList : public nsGenericDOMNodeList
{
public:
nsAttributeChildList(nsDOMAttribute* aAttribute);
virtual ~nsAttributeChildList();
// interface nsIDOMNodeList
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
void DropReference();
protected:
nsDOMAttribute* mAttribute;
};
// Attribute helper class used to wrap up an attribute with a dom
// object that implements nsIDOMAttr and nsIDOMNode and
// nsIScriptObjectOwner
class nsDOMAttribute : public nsIDOMAttr,
public nsIScriptObjectOwner,
public nsIDOMAttributePrivate
{
public:
nsDOMAttribute(nsIContent* aContent, nsINodeInfo *aNodeInfo,
const nsString& aValue);
virtual ~nsDOMAttribute();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIDOMAttr interface
NS_DECL_IDOMATTR
// nsIDOMNode interface
NS_DECL_IDOMNODE
// nsIDOMAttributePrivate interface
NS_IMETHOD DropReference();
NS_IMETHOD SetContent(nsIContent* aContent);
NS_IMETHOD GetContent(nsIContent** aContent);
private:
nsIContent* mContent;
nsCOMPtr<nsINodeInfo> mNodeInfo;
nsString mValue;
// XXX For now, there's only a single child - a text
// element representing the value
nsIDOMText* mChild;
nsAttributeChildList* mChildList;
void* mScriptObject;
};
#endif /* nsDOMAttribute_h___ */

View File

@@ -0,0 +1,531 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsDOMAttributeMap.h"
#include "nsDOMAttribute.h"
#include "nsGenericElement.h"
#include "nsIContent.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsINameSpaceManager.h"
#include "nsDOMError.h"
//----------------------------------------------------------------------
nsDOMAttributeMap::nsDOMAttributeMap(nsIContent* aContent)
: mContent(aContent)
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
// We don't add a reference to our content. If it goes away,
// we'll be told to drop our reference
}
nsDOMAttributeMap::~nsDOMAttributeMap()
{
}
void
nsDOMAttributeMap::DropReference()
{
mContent = nsnull;
}
NS_INTERFACE_MAP_BEGIN(nsDOMAttributeMap)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNamedNodeMap)
NS_INTERFACE_MAP_ENTRY(nsIDOMNamedNodeMap)
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectOwner)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsDOMAttributeMap)
NS_IMPL_RELEASE(nsDOMAttributeMap)
nsresult
nsDOMAttributeMap::GetScriptObject(nsIScriptContext *aContext,
void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = nsGenericElement::GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptNamedNodeMap(aContext,
(nsISupports *)(nsIDOMNamedNodeMap *)this,
(nsISupports *)mContent,
(void**)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
return res;
}
nsresult
nsDOMAttributeMap::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
nsresult
nsDOMAttributeMap::GetNamedItem(const nsString &aAttrName,
nsIDOMNode** aAttribute)
{
NS_ENSURE_ARG_POINTER(aAttribute);
*aAttribute = nsnull;
nsresult rv = NS_OK;
if (mContent) {
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aAttrName)));
nsCOMPtr<nsIAtom> prefix;
nsresult attrResult;
nsAutoString value;
attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom,
*getter_AddRefs(prefix), value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
PRInt32 nameSpaceID = kNameSpaceID_None;
if (prefix) {
nsCOMPtr<nsIAtom> tmpName, tmpPrefix;
PRInt32 tmpNameSpaceID, attrCount;
mContent->GetAttributeCount(attrCount);
while (attrCount--) {
mContent->GetAttributeNameAt(attrCount, tmpNameSpaceID,
*getter_AddRefs(tmpName),
*getter_AddRefs(tmpPrefix));
if (tmpName == nameAtom && tmpPrefix == prefix) {
nameSpaceID = tmpNameSpaceID;
break;
}
}
}
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID,
*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute;
domAttribute = new nsDOMAttribute(mContent, ni, value);
NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY);
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aAttribute);
}
}
return rv;
}
nsresult
nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
if (!aNode) {
return NS_ERROR_NULL_POINTER;
}
nsresult rv = NS_OK;
*aReturn = nsnull;
if (mContent) {
nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aNode));
if (!attribute) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
nsAutoString name, value;
nsCOMPtr<nsIAtom> nameAtom;
attribute->GetName(name);
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(name, nsnull, kNameSpaceID_None, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
ni->GetNameAtom(*getter_AddRefs(nameAtom));
nsresult attrResult = mContent->GetAttribute(kNameSpaceID_Unknown,
nameAtom, value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
nsDOMAttribute* domAttribute;
// We pass a null content here since the attr node we return isn't
// tied to this content anymore.
domAttribute = new nsDOMAttribute(nsnull, ni, value);
if (!domAttribute) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
}
attribute->GetValue(value);
rv = mContent->SetAttribute(kNameSpaceID_None, nameAtom, value, PR_TRUE);
}
return rv;
}
NS_IMETHODIMP
nsDOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
nsresult rv = NS_OK;
if (mContent) {
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aName)));
PRInt32 nameSpaceID = kNameSpaceID_None;
nsCOMPtr<nsIDOMNode> attribute;
nsCOMPtr<nsIAtom> prefix;
nsresult attrResult;
nsAutoString value;
attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom,
*getter_AddRefs(prefix), value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
if (prefix) {
nsCOMPtr<nsIAtom> tmpName, tmpPrefix;
PRInt32 tmpNameSpaceID, attrCount;
mContent->GetAttributeCount(attrCount);
while (attrCount--) {
mContent->GetAttributeNameAt(attrCount, tmpNameSpaceID,
*getter_AddRefs(tmpName),
*getter_AddRefs(tmpPrefix));
if (tmpName == nameAtom && tmpPrefix == prefix) {
nameSpaceID = tmpNameSpaceID;
break;
}
}
}
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute;
domAttribute = new nsDOMAttribute(nsnull, ni, value);
if (!domAttribute) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
} else {
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
rv = mContent->UnsetAttribute(nameSpaceID, nameAtom, PR_TRUE);
}
return rv;
}
nsresult
nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> nameAtom, prefix;
nsresult rv = NS_OK;
if (mContent &&
NS_SUCCEEDED(mContent->GetAttributeNameAt(aIndex,
nameSpaceID,
*getter_AddRefs(nameAtom),
*getter_AddRefs(prefix)))) {
nsAutoString value, name;
mContent->GetAttribute(nameSpaceID, nameAtom, value);
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute = new nsDOMAttribute(mContent, ni, value);
NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY);
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
}
else {
*aReturn = nsnull;
rv = NS_ERROR_DOM_INDEX_SIZE_ERR;
}
return rv;
}
nsresult
nsDOMAttributeMap::GetLength(PRUint32 *aLength)
{
NS_ENSURE_ARG_POINTER(aLength);
PRInt32 n;
nsresult rv = NS_OK;
if (nsnull != mContent) {
rv = mContent->GetAttributeCount(n);
*aLength = PRUint32(n);
} else {
*aLength = 0;
}
return rv;
}
nsresult
nsDOMAttributeMap::GetNamedItemNS(const nsString& aNamespaceURI,
const nsString& aLocalName,
nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
nsresult rv = NS_OK;
if (mContent) {
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aLocalName)));
PRInt32 nameSpaceID = kNameSpaceID_None;
nsCOMPtr<nsIAtom> prefix;
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
if (aNamespaceURI.Length()) {
nsCOMPtr<nsINameSpaceManager> nsmgr;
nimgr->GetNamespaceManager(*getter_AddRefs(nsmgr));
NS_ENSURE_TRUE(nsmgr, NS_ERROR_FAILURE);
nsmgr->GetNameSpaceID(aNamespaceURI, nameSpaceID);
if (nameSpaceID == kNameSpaceID_Unknown)
return NS_OK;
}
nsresult attrResult;
nsAutoString value;
attrResult = mContent->GetAttribute(nameSpaceID, nameAtom,
*getter_AddRefs(prefix), value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute;
domAttribute = new nsDOMAttribute(mContent, ni, value);
NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY);
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
}
}
return rv;
}
nsresult
nsDOMAttributeMap::SetNamedItemNS(nsIDOMNode* aArg, nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
nsresult rv = NS_OK;
*aReturn = nsnull;
if (mContent) {
nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aArg));
if (!attribute) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
nsAutoString name, nsURI, value;
nsCOMPtr<nsIAtom> nameAtom;
PRInt32 nameSpaceID;
attribute->GetName(name);
attribute->GetNamespaceURI(nsURI);
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(name, nsURI, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
ni->GetNameAtom(*getter_AddRefs(nameAtom));
ni->GetNamespaceID(nameSpaceID);
nsresult attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
nsDOMAttribute* domAttribute;
// We pass a null content here since the attr node we return isn't
// tied to this content anymore.
domAttribute = new nsDOMAttribute(nsnull, ni, value);
if (!domAttribute) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
}
attribute->GetValue(value);
rv = mContent->SetAttribute(ni, value, PR_TRUE);
}
return rv;
}
nsresult
nsDOMAttributeMap::RemoveNamedItemNS(const nsString& aNamespaceURI,
const nsString& aLocalName,
nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
nsresult rv = NS_OK;
if (mContent) {
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aLocalName)));
PRInt32 nameSpaceID = kNameSpaceID_None;
nsCOMPtr<nsIDOMNode> attribute;
nsCOMPtr<nsIAtom> prefix;
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
if (aNamespaceURI.Length()) {
nsCOMPtr<nsINameSpaceManager> nsmgr;
nimgr->GetNamespaceManager(*getter_AddRefs(nsmgr));
NS_ENSURE_TRUE(nsmgr, NS_ERROR_FAILURE);
nsmgr->GetNameSpaceID(aNamespaceURI, nameSpaceID);
if (nameSpaceID == kNameSpaceID_Unknown)
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
nsresult attrResult;
nsAutoString value;
attrResult = mContent->GetAttribute(nameSpaceID, nameAtom,
*getter_AddRefs(prefix), value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute;
domAttribute = new nsDOMAttribute(nsnull, ni, value);
if (!domAttribute) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
} else {
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
rv = mContent->UnsetAttribute(nameSpaceID, nameAtom, PR_TRUE);
}
return rv;
}
#ifdef DEBUG
nsresult
nsDOMAttributeMap::SizeOfNamedNodeMap(nsIDOMNamedNodeMap* aMap,
nsISizeOfHandler* aSizer,
PRUint32* aResult)
{
if (!aResult) return NS_ERROR_NULL_POINTER;
nsDOMAttributeMap* map = (nsDOMAttributeMap*) aMap;
PRUint32 sum = sizeof(nsDOMAttributeMap);
*aResult = sum;
return NS_OK;
}
#endif

View File

@@ -0,0 +1,72 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDOMAttributeMap_h___
#define nsDOMAttributeMap_h___
#include "nsIDOMNamedNodeMap.h"
#include "nsIScriptObjectOwner.h"
#include "nsVoidArray.h"
#include "nsString.h"
#include "plhash.h"
class nsIContent;
// Helper class that implements the nsIDOMNamedNodeMap interface.
class nsDOMAttributeMap : public nsIDOMNamedNodeMap,
public nsIScriptObjectOwner
{
public:
nsDOMAttributeMap(nsIContent* aContent);
virtual ~nsDOMAttributeMap();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIDOMNamedNodeMap interface
NS_IMETHOD GetLength(PRUint32* aSize);
NS_IMETHOD GetNamedItem(const nsString& aName, nsIDOMNode** aReturn);
NS_IMETHOD SetNamedItem(nsIDOMNode* aNode, nsIDOMNode** aReturn);
NS_IMETHOD RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
NS_IMETHOD GetNamedItemNS(const nsString& aNamespaceURI,
const nsString& aLocalName, nsIDOMNode** aReturn);
NS_IMETHOD SetNamedItemNS(nsIDOMNode* aArg, nsIDOMNode** aReturn);
NS_IMETHOD RemoveNamedItemNS(const nsString& aNamespaceURI,
const nsString&aLocalName, nsIDOMNode** aReturn);
void DropReference();
#ifdef DEBUG
static nsresult SizeOfNamedNodeMap(nsIDOMNamedNodeMap* aMap,
nsISizeOfHandler* aSizer,
PRUint32* aResult);
#endif
private:
nsIContent* mContent;
void* mScriptObject;
};
#endif /* nsDOMAttributeMap_h___ */

View File

@@ -0,0 +1,268 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsDOMDocumentType.h"
#include "nsDOMAttributeMap.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsLayoutAtoms.h"
#include "nsCOMPtr.h"
nsresult
NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
const nsString& aName,
nsIDOMNamedNodeMap *aEntities,
nsIDOMNamedNodeMap *aNotations,
const nsString& aPublicId,
const nsString& aSystemId,
const nsString& aInternalSubset)
{
NS_ENSURE_ARG_POINTER(aDocType);
*aDocType = new nsDOMDocumentType(aName, aEntities, aNotations,
aPublicId, aSystemId, aInternalSubset);
if (!*aDocType) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(*aDocType);
return NS_OK;
}
nsDOMDocumentType::nsDOMDocumentType(const nsString& aName,
nsIDOMNamedNodeMap *aEntities,
nsIDOMNamedNodeMap *aNotations,
const nsString& aPublicId,
const nsString& aSystemId,
const nsString& aInternalSubset) :
mName(aName),
mPublicId(aPublicId),
mSystemId(aSystemId),
mInternalSubset(aInternalSubset)
{
NS_INIT_REFCNT();
mEntities = aEntities;
mNotations = aNotations;
NS_IF_ADDREF(mEntities);
NS_IF_ADDREF(mNotations);
}
nsDOMDocumentType::~nsDOMDocumentType()
{
NS_IF_RELEASE(mEntities);
NS_IF_RELEASE(mNotations);
}
NS_IMPL_ADDREF(nsDOMDocumentType)
NS_IMPL_RELEASE(nsDOMDocumentType)
NS_INTERFACE_MAP_BEGIN(nsDOMDocumentType)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDocumentType)
NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentType)
NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
NS_INTERFACE_MAP_ENTRY(nsIContent)
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectOwner)
NS_INTERFACE_MAP_END_THREADSAFE
NS_IMETHODIMP
nsDOMDocumentType::GetName(nsString& aName)
{
aName=mName;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetEntities(nsIDOMNamedNodeMap** aEntities)
{
NS_ENSURE_ARG_POINTER(aEntities);
*aEntities = mEntities;
NS_IF_ADDREF(*aEntities);
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetNotations(nsIDOMNamedNodeMap** aNotations)
{
NS_ENSURE_ARG_POINTER(aNotations);
*aNotations = mNotations;
NS_IF_ADDREF(*aNotations);
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetPublicId(nsString& aPublicId)
{
aPublicId = mPublicId;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetSystemId(nsString& aSystemId)
{
aSystemId = mSystemId;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetInternalSubset(nsString& aInternalSubset)
{
aInternalSubset = mInternalSubset;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetTag(nsIAtom*& aResult) const
{
aResult = NS_NewAtom(mName.GetUnicode());
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetNodeInfo(nsINodeInfo*& aResult) const
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetNodeName(nsString& aNodeName)
{
aNodeName=mName;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetNodeType(PRUint16* aNodeType)
{
*aNodeType = nsIDOMNode::DOCUMENT_TYPE_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsDOMDocumentType* it = new nsDOMDocumentType(mName,
mEntities,
mNotations,
mPublicId,
mSystemId,
mInternalSubset);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
}
NS_IMETHODIMP
nsDOMDocumentType::List(FILE* out, PRInt32 aIndent) const
{
NS_PRECONDITION(nsnull != mInner.mDocument, "bad content");
PRInt32 index;
for (index = aIndent; --index >= 0; ) fputs(" ", out);
fprintf(out, "Document type refcount: %d\n", mRefCnt);
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::DumpContent(FILE* out = stdout, PRInt32 aIndent = 0,PRBool aDumpAll=PR_TRUE) const {
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
// We should never be getting events
NS_ASSERTION(0, "event handler called for document type");
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
NS_IMETHODIMP
nsDOMDocumentType::GetContentID(PRUint32* aID)
{
NS_ENSURE_ARG_POINTER(aID);
*aID = 0;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDOMDocumentType::SetContentID(PRUint32 aID)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDOMDocumentType::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const
{
NS_ENSURE_ARG_POINTER(aResult);
#ifdef DEBUG
PRUint32 sum;
mInner.SizeOf(aSizer, &sum, sizeof(*this));
PRUint32 ssize;
mName.SizeOf(aSizer, &ssize);
sum = sum - sizeof(mName) + ssize;
if (mEntities) {
PRBool recorded;
aSizer->RecordObject((void*) mEntities, &recorded);
if (!recorded) {
PRUint32 size;
nsDOMAttributeMap::SizeOfNamedNodeMap(mEntities, aSizer, &size);
aSizer->AddSize(nsLayoutAtoms::xml_document_entities, size);
}
}
if (mNotations) {
PRBool recorded;
aSizer->RecordObject((void*) mNotations, &recorded);
if (!recorded) {
PRUint32 size;
nsDOMAttributeMap::SizeOfNamedNodeMap(mNotations, aSizer, &size);
aSizer->AddSize(nsLayoutAtoms::xml_document_notations, size);
}
}
#endif
return NS_OK;
}

View File

@@ -0,0 +1,88 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDOMDocumentType_h___
#define nsDOMDocumentType_h___
#include "nsIDOMDocumentType.h"
#include "nsIScriptObjectOwner.h"
#include "nsIContent.h"
#include "nsGenericDOMDataNode.h"
#include "nsString.h"
#include "nsISizeOfHandler.h"
class nsIDOMNamedNodeMap;
class nsDOMDocumentType : public nsIDOMDocumentType,
public nsIScriptObjectOwner,
public nsIContent
{
public:
nsDOMDocumentType(const nsString& aName,
nsIDOMNamedNodeMap *aEntities,
nsIDOMNamedNodeMap *aNotations,
const nsString& aPublicId,
const nsString& aSystemId,
const nsString& aInternalSubset);
virtual ~nsDOMDocumentType();
// nsISupports
NS_DECL_ISUPPORTS
// nsIDOMNode
NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(mInner)
// nsIDOMDocumentType
NS_DECL_IDOMDOCUMENTTYPE
// nsIScriptObjectOwner interface
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(mInner);
// nsIContent
NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner)
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
protected:
// XXX DocumentType is currently implemented by using the generic
// CharacterData inner object, even though DocumentType is not
// character data. This is done simply for convenience and should
// be changed if this restricts what should be done for character data.
nsGenericDOMDataNode mInner;
nsString mName;
nsIDOMNamedNodeMap* mEntities;
nsIDOMNamedNodeMap* mNotations;
nsString mPublicId;
nsString mSystemId;
nsString mInternalSubset;
};
extern nsresult NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
const nsString& aName,
nsIDOMNamedNodeMap *aEntities,
nsIDOMNamedNodeMap *aNotations,
const nsString& aPublicId,
const nsString& aSystemId,
const nsString& aInternalSubset);
#endif // nsDOMDocument_h___

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,530 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDocument_h___
#define nsDocument_h___
#include "nsIDocument.h"
#include "nsWeakReference.h"
#include "nsWeakPtr.h"
#include "nsVoidArray.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentView.h"
#include "nsIDOMDocumentXBL.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMDocumentStyle.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDiskDocument.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMEventTarget.h"
#include "nsIXIFConverter.h"
#include "nsIJSScriptObject.h"
#include "nsIContent.h"
#include "nsGenericDOMNodeList.h"
#include "nsIPrincipal.h"
#include "nsIBindingManager.h"
#include "nsINodeInfo.h"
#include "nsIDOMDocumentEvent.h"
#include "nsISupportsArray.h"
class nsIEventListenerManager;
class nsDOMStyleSheetList;
class nsIOutputStream;
class nsDocument;
#if 0
class nsPostData : public nsIPostData {
public:
nsPostData(PRBool aIsFile, char* aData);
NS_DECL_ISUPPORTS
virtual PRBool IsFile();
virtual const char* GetData();
virtual PRInt32 GetDataLength();
protected:
virtual ~nsPostData();
PRBool mIsFile;
char* mData;
PRInt32 mDataLen;
};
#endif
class nsDocHeaderData
{
public:
nsDocHeaderData(nsIAtom* aField, const nsString& aData)
{
mField = aField;
NS_IF_ADDREF(mField);
mData.Assign(aData);
mNext = nsnull;
}
~nsDocHeaderData(void)
{
NS_IF_RELEASE(mField);
if (nsnull != mNext) {
delete mNext;
mNext = nsnull;
}
}
nsIAtom* mField;
nsAutoString mData;
nsDocHeaderData* mNext;
};
// Represents the children of a document (prolog, epilog and
// document element)
class nsDocumentChildNodes : public nsGenericDOMNodeList
{
public:
nsDocumentChildNodes(nsIDocument* aDocument);
~nsDocumentChildNodes();
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
void DropReference();
protected:
nsIDocument* mDocument;
};
class nsAnonymousContentList : public nsGenericDOMNodeList
{
public:
nsAnonymousContentList(nsISupportsArray* aElements);
virtual ~nsAnonymousContentList();
// nsIDOMNodeList interface
NS_DECL_IDOMNODELIST
private:
nsISupportsArray* mElements;
};
// Base class for our document implementations
class nsDocument : public nsIDocument,
public nsIDOMDocument,
public nsIDOMNSDocument,
public nsIDOMDocumentEvent,
public nsIDOMDocumentStyle,
public nsIDOMDocumentView,
public nsIDOMDocumentXBL,
public nsIDiskDocument,
public nsIJSScriptObject,
public nsSupportsWeakReference,
public nsIDOMEventReceiver,
public nsIScriptObjectPrincipal
{
public:
NS_DECL_ISUPPORTS
virtual nsIArena* GetArena();
NS_IMETHOD StartDocumentLoad(const char* aCommand,
nsIChannel* aChannel,
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset = PR_TRUE);
NS_IMETHOD StopDocumentLoad();
/**
* Return the title of the document. May return null.
*/
virtual const nsString* GetDocumentTitle() const;
/**
* Return the URL for the document. May return null.
*/
virtual nsIURI* GetDocumentURL() const;
/**
* Return the principal responsible for this document.
*/
NS_IMETHOD GetPrincipal(nsIPrincipal **aPrincipal);
/**
* Update principal responsible for this document to the intersection
* of its previous value and aPrincipal, and return its new value.
*/
NS_IMETHOD AddPrincipal(nsIPrincipal *aPrincipal);
/**
* Return the content (mime) type of this document.
*/
NS_IMETHOD GetContentType(nsString& aContentType) const;
/**
* Return the LoadGroup for the document. May return null.
*/
NS_IMETHOD GetDocumentLoadGroup(nsILoadGroup **aGroup) const;
/**
* Return the base URL for realtive URLs in the document. May return null (or the document URL).
*/
NS_IMETHOD GetBaseURL(nsIURI*& aURL) const;
/**
* Return a standard name for the document's character set. This will
* trigger a startDocumentLoad if necessary to answer the question.
*/
NS_IMETHOD GetDocumentCharacterSet(nsString& oCharsetID);
NS_IMETHOD SetDocumentCharacterSet(const nsString& aCharSetID);
/**
* Add an observer that gets notified whenever the charset changes.
*/
NS_IMETHOD AddCharSetObserver(nsIObserver* aObserver);
/**
* Remove a charset observer.
*/
NS_IMETHOD RemoveCharSetObserver(nsIObserver* aObserver);
/**
* Return the Line Breaker for the document
*/
NS_IMETHOD GetLineBreaker(nsILineBreaker** aResult) ;
NS_IMETHOD SetLineBreaker(nsILineBreaker* aLineBreaker) ;
NS_IMETHOD GetWordBreaker(nsIWordBreaker** aResult) ;
NS_IMETHOD SetWordBreaker(nsIWordBreaker* aWordBreaker) ;
/**
* Access HTTP header data (this may also get set from other sources, like
* HTML META tags).
*/
NS_IMETHOD GetHeaderData(nsIAtom* aHeaderField, nsString& aData) const;
NS_IMETHOD SetHeaderData(nsIAtom* aheaderField, const nsString& aData);
/**
* Create a new presentation shell that will use aContext for
* it's presentation context (presentation context's <b>must not</b> be
* shared among multiple presentation shell's).
*/
#if 0
// XXX Temp hack: moved to nsMarkupDocument
NS_IMETHOD CreateShell(nsIPresContext* aContext,
nsIViewManager* aViewManager,
nsIStyleSet* aStyleSet,
nsIPresShell** aInstancePtrResult);
#endif
virtual PRBool DeleteShell(nsIPresShell* aShell);
virtual PRInt32 GetNumberOfShells();
virtual nsIPresShell* GetShellAt(PRInt32 aIndex);
/**
* Return the parent document of this document. Will return null
* unless this document is within a compound document and has a parent.
*/
virtual nsIDocument* GetParentDocument();
virtual void SetParentDocument(nsIDocument* aParent);
virtual void AddSubDocument(nsIDocument* aSubDoc);
virtual PRInt32 GetNumberOfSubDocuments();
virtual nsIDocument* GetSubDocumentAt(PRInt32 aIndex);
/**
* Return the root content object for this document.
*/
virtual nsIContent* GetRootContent();
virtual void SetRootContent(nsIContent* aRoot);
/**
* Methods to append to the prolog and epilog of
* a document. The prolog is the content before the document
* element, the epilog after.
*/
NS_IMETHOD AppendToProlog(nsIContent* aContent);
NS_IMETHOD AppendToEpilog(nsIContent* aContent);
/**
* Get the direct children of the document - content in
* the prolog, the root content and content in the epilog.
*/
NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const;
NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const;
NS_IMETHOD GetChildCount(PRInt32& aCount);
/**
* Get the style sheets owned by this document.
* These are ordered, highest priority last
*/
virtual PRInt32 GetNumberOfStyleSheets();
virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex);
virtual PRInt32 GetIndexOfStyleSheet(nsIStyleSheet* aSheet);
virtual void AddStyleSheet(nsIStyleSheet* aSheet);
virtual void RemoveStyleSheet(nsIStyleSheet* aSheet);
NS_IMETHOD UpdateStyleSheets(nsISupportsArray* aOldSheets, nsISupportsArray* aNewSheets);
virtual void AddStyleSheetToStyleSets(nsIStyleSheet* aSheet);
virtual void RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet);
NS_IMETHOD InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool aNotify);
virtual void SetStyleSheetDisabledState(nsIStyleSheet* aSheet,
PRBool mDisabled);
/**
* Set the object from which a document can get a script context.
* This is the context within which all scripts (during document
* creation and during event handling) will run.
*/
NS_IMETHOD GetScriptGlobalObject(nsIScriptGlobalObject** aGlobalObject);
NS_IMETHOD SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject);
/**
* Get the name space manager for this document
*/
NS_IMETHOD GetNameSpaceManager(nsINameSpaceManager*& aManager);
/**
* Add a new observer of document change notifications. Whenever
* content is changed, appended, inserted or removed the observers are
* informed.
*/
virtual void AddObserver(nsIDocumentObserver* aObserver);
/**
* Remove an observer of document change notifications. This will
* return false if the observer cannot be found.
*/
virtual PRBool RemoveObserver(nsIDocumentObserver* aObserver);
// Observation hooks used by content nodes to propagate
// notifications to document observers.
NS_IMETHOD BeginUpdate();
NS_IMETHOD EndUpdate();
NS_IMETHOD BeginLoad();
NS_IMETHOD EndLoad();
NS_IMETHOD ContentChanged(nsIContent* aContent,
nsISupports* aSubContent);
NS_IMETHOD ContentStatesChanged(nsIContent* aContent1, nsIContent* aContent2);
NS_IMETHOD AttributeChanged(nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD StyleRuleChanged(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint); // See nsStyleConsts fot hint values
NS_IMETHOD StyleRuleAdded(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule);
NS_IMETHOD StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule);
/**
* Finds text in content
*/
NS_IMETHOD FindNext(const nsString &aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound);
/**
* Converts the document or a selection of the
* document to XIF (XML Interchange Format)
* and places the result in aBuffer.
*/
NS_IMETHOD CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection);
NS_IMETHOD ToXIF(nsIXIFConverter * aConverter, nsIDOMNode* aNode);
virtual void BeginConvertToXIF(nsIXIFConverter * aConverter, nsIDOMNode* aNode);
virtual void ConvertChildrenToXIF(nsIXIFConverter * aConverter, nsIDOMNode* aNode);
virtual void FinishConvertToXIF(nsIXIFConverter * aConverter, nsIDOMNode* aNode);
NS_IMETHOD FlushPendingNotifications();
NS_IMETHOD GetAndIncrementContentID(PRInt32* aID);
NS_IMETHOD GetBindingManager(nsIBindingManager** aResult);
NS_IMETHOD GetNodeInfoManager(nsINodeInfoManager*& aNodeInfoManager);
public:
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIDOMDocument interface
NS_IMETHOD GetDoctype(nsIDOMDocumentType** aDoctype);
NS_IMETHOD GetImplementation(nsIDOMDOMImplementation** aImplementation);
NS_IMETHOD GetDocumentElement(nsIDOMElement** aDocumentElement);
NS_IMETHOD CreateElement(const nsString& aTagName, nsIDOMElement** aReturn);
NS_IMETHOD CreateDocumentFragment(nsIDOMDocumentFragment** aReturn);
NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn);
NS_IMETHOD CreateComment(const nsString& aData, nsIDOMComment** aReturn);
NS_IMETHOD CreateCDATASection(const nsString& aData, nsIDOMCDATASection** aReturn);
NS_IMETHOD CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn);
NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn);
NS_IMETHOD CreateEntityReference(const nsString& aName, nsIDOMEntityReference** aReturn);
NS_IMETHOD GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn);
NS_IMETHOD GetElementsByTagNameNS(const nsString& aNamespaceURI, const nsString& aLocalName, nsIDOMNodeList** aReturn);
NS_IMETHOD GetStyleSheets(nsIDOMStyleSheetList** aStyleSheets);
NS_IMETHOD GetCharacterSet(nsString& aCharacterSet);
NS_IMETHOD ImportNode(nsIDOMNode* aImportedNode,
PRBool aDeep,
nsIDOMNode** aReturn);
NS_IMETHOD CreateElementWithNameSpace(const nsString& aTagName,
const nsString& aNameSpace,
nsIDOMElement** aReturn);
NS_IMETHOD CreateRange(nsIDOMRange** aReturn);
NS_IMETHOD GetWidth(PRInt32* aWidth);
NS_IMETHOD GetHeight(PRInt32* aHeight);
NS_IMETHOD Load (const nsString& aUrl);
NS_IMETHOD GetPlugins(nsIDOMPluginArray** aPlugins);
// nsIDOMNode interface
NS_DECL_IDOMNODE
// nsIDOMDocumentView
NS_DECL_IDOMDOCUMENTVIEW
// nsIDOMDocumentXBL
NS_DECL_IDOMDOCUMENTXBL
// nsIDOMDocumentEvent
NS_DECL_IDOMDOCUMENTEVENT
// nsIDOMEventReceiver interface
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager **aInstancePtrResult);
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
// nsIDiskDocument inteface
NS_IMETHOD InitDiskDocument(nsFileSpec *aFileSpec);
NS_IMETHOD SaveFile(nsFileSpec* aFileSpec,
PRBool aReplaceExisting,
PRBool aSaveCopy,
const nsString& aSaveFileType,
const nsString& aSaveCharset,
PRUint32 aFlags);
NS_IMETHOD GetFileSpec(nsFileSpec& aFileSpec);
NS_IMETHOD GetModCount(PRInt32 *outModCount);
NS_IMETHOD ResetModCount();
NS_IMETHOD IncrementModCount(PRInt32 aNumMods);
// nsIDOMEventTarget interface
NS_IMETHOD AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aUseCapture);
NS_IMETHOD RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aUseCapture);
NS_IMETHOD DispatchEvent(nsIDOMEvent* aEvent);
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
virtual PRBool IsInSelection(nsIDOMSelection* aSelection, const nsIContent *aContent) const;
virtual nsIContent* GetPrevContent(const nsIContent *aContent) const;
virtual nsIContent* GetNextContent(const nsIContent *aContent) const;
// nsIJSScriptObject interface
virtual PRBool AddProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool DeleteProperty(JSContext *aContext,
JSObject *aObj, jsval aID, jsval *aVp);
virtual PRBool GetProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool SetProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool EnumerateProperty(JSContext *aContext, JSObject *aObj);
virtual PRBool Resolve(JSContext *aContext, JSObject *aObj, jsval aID);
virtual PRBool Convert(JSContext *aContext, JSObject *aObj, jsval aID);
virtual void Finalize(JSContext *aContext, JSObject *aObj);
virtual nsresult Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup);
virtual nsresult SetDocumentURL(nsIURI* aURI);
protected:
nsIContent* FindContent(const nsIContent* aStartNode,
const nsIContent* aTest1,
const nsIContent* aTest2) const;
nsresult GetPixelDimensions(nsIPresShell* aShell,
PRInt32* aWidth,
PRInt32* aHeight);
protected:
virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet); // subclass hooks for sheet ordering
virtual void InternalInsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex);
nsDocument();
virtual ~nsDocument();
nsresult Init();
nsIArena* mArena;
nsString* mDocumentTitle;
nsIURI* mDocumentURL;
nsIPrincipal* mPrincipal;
nsWeakPtr mDocumentLoadGroup;
nsString mCharacterSet;
nsVoidArray mCharSetObservers;
nsIDocument* mParentDocument;
nsVoidArray mSubDocuments;
nsVoidArray mPresShells;
nsIContent* mRootContent;
nsVoidArray mStyleSheets;
nsVoidArray mObservers;
void* mScriptObject;
nsCOMPtr<nsIScriptGlobalObject> mScriptGlobalObject;
nsIEventListenerManager* mListenerManager;
PRInt8 mDisplaySelection;
PRBool mInDestructor;
nsDOMStyleSheetList *mDOMStyleSheets;
nsINameSpaceManager* mNameSpaceManager;
nsDocHeaderData* mHeaderData;
nsILineBreaker* mLineBreaker;
nsVoidArray *mProlog;
nsVoidArray *mEpilog;
nsDocumentChildNodes* mChildNodes;
nsIWordBreaker* mWordBreaker;
// A content ID counter used to give a monotonically increasing ID to the content
// objects in the document's content model
PRInt32 mNextContentID;
// disk file members
nsFileSpec* mFileSpec;
PRInt32 mModCount;
nsCOMPtr<nsIBindingManager> mBindingManager;
nsCOMPtr<nsINodeInfoManager> mNodeInfoManager; // OWNER
};
#endif /* nsDocument_h___ */

View File

@@ -0,0 +1,365 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsIDocumentEncoder.h"
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIDocument.h"
#include "nsIDOMSelection.h"
#include "nsIPresShell.h"
#include "nsXIFDTD.h"
#include "nsParserCIID.h"
#include "nsIParser.h"
#include "nsHTMLContentSinkStream.h"
#include "nsHTMLToTXTSinkStream.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kCTextEncoderCID, NS_TEXT_ENCODER_CID);
static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID);
static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID);
class nsTextEncoder : public nsIDocumentEncoder
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IDOCUMENT_ENCODER_IID; return iid; }
nsTextEncoder();
virtual ~nsTextEncoder();
NS_IMETHOD Init(nsIDocument* aDocument, const nsString& aMimeType, PRUint32 aFlags);
/* Interfaces for addref and release and queryinterface */
NS_DECL_ISUPPORTS
// Inherited methods from nsIDocumentEncoder
NS_IMETHOD SetSelection(nsIDOMSelection* aSelection);
NS_IMETHOD SetWrapColumn(PRUint32 aWC);
NS_IMETHOD SetCharset(const nsString& aCharset);
NS_IMETHOD EncodeToStream(nsIOutputStream* aStream);
NS_IMETHOD EncodeToString(nsString& aOutputString);
protected:
// Local methods to the text encoder -- used to be in nsITextEncoder,
// but that interface is obsolete now.
//NS_IMETHOD PrettyPrint(PRBool aYes);
//NS_IMETHOD AddHeader(PRBool aYes);
nsIDocument* mDocument;
nsIDOMSelection* mSelection;
nsString mMimeType;
nsString mCharset;
PRUint32 mFlags;
PRUint32 mWrapColumn;
};
NS_IMPL_ADDREF(nsTextEncoder)
NS_IMPL_RELEASE(nsTextEncoder)
nsTextEncoder::nsTextEncoder()
{
NS_INIT_REFCNT();
mMimeType.AssignWithConversion("text/plain");
mDocument = 0;
mSelection = 0;
mFlags = 0;
mWrapColumn = 72;
}
nsTextEncoder::~nsTextEncoder()
{
NS_IF_RELEASE(mDocument);
//NS_IF_RELEASE(mSelection); // no. we never addref'd it.
}
NS_IMETHODIMP
nsTextEncoder::Init(nsIDocument* aDocument, const nsString& aMimeType, PRUint32 aFlags)
{
if (!aDocument)
return NS_ERROR_INVALID_ARG;
mDocument = aDocument;
NS_ADDREF(mDocument);
mMimeType = aMimeType;
mFlags = aFlags;
return NS_OK;
}
nsresult nsTextEncoder::QueryInterface(REFNSIID aIID,
void **aInstancePtr)
{
if (nsnull == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = 0;
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void *)(nsISupports*)this;
} else if (aIID.Equals(NS_GET_IID(nsIDocumentEncoder))) {
*aInstancePtr = (void *)(nsIDocumentEncoder*)this;
}
if (nsnull == *aInstancePtr)
return NS_NOINTERFACE;
NS_ADDREF_THIS();
return NS_OK;
}
NS_IMETHODIMP
nsTextEncoder::SetWrapColumn(PRUint32 aWC)
{
mWrapColumn = aWC;
return NS_OK;
}
NS_IMETHODIMP
nsTextEncoder::SetSelection(nsIDOMSelection* aSelection)
{
mSelection = aSelection;
return NS_OK;
}
NS_IMETHODIMP
nsTextEncoder::SetCharset(const nsString& aCharset)
{
mCharset = aCharset;
return NS_OK;
}
NS_IMETHODIMP
nsTextEncoder::EncodeToString(nsString& aOutputString)
{
nsresult rv;
if (!mDocument)
return NS_ERROR_NOT_INITIALIZED;
// xxx Also make sure mString is a mime type "text/html" or "text/plain"
if (mDocument)
{
nsString buffer;
if (mMimeType.EqualsWithConversion("text/xif"))
{
mDocument->CreateXIF(aOutputString, mSelection);
return NS_OK;
}
mDocument->CreateXIF(buffer, mSelection);
nsIParser* parser;
rv = nsComponentManager::CreateInstance(kCParserCID,
nsnull,
kCParserIID,
(void **)&parser);
if (NS_SUCCEEDED(rv))
{
nsIHTMLContentSink* sink = nsnull;
if (mMimeType.EqualsWithConversion("text/html"))
rv = NS_New_HTML_ContentSinkStream(&sink, &aOutputString, mFlags);
else // default to text/plain
rv = NS_New_HTMLToTXT_SinkStream(&sink, &aOutputString,
mWrapColumn, mFlags);
if (sink && NS_SUCCEEDED(rv))
{
parser->SetContentSink(sink);
nsIDTD* dtd = nsnull;
rv = NS_NewXIFDTD(&dtd);
if (NS_SUCCEEDED(rv))
{
parser->RegisterDTD(dtd);
parser->Parse(buffer, 0, NS_ConvertToString("text/xif"), PR_FALSE, PR_TRUE);
}
NS_IF_RELEASE(dtd);
NS_IF_RELEASE(sink);
}
NS_RELEASE(parser);
}
}
return rv;
}
NS_IMETHODIMP
nsTextEncoder::EncodeToStream(nsIOutputStream* aStream)
{
nsresult rv;
if (!mDocument)
return NS_ERROR_NOT_INITIALIZED;
// xxx Also make sure mString is a mime type "text/html" or "text/plain"
if (mDocument)
{
nsString buffer;
mDocument->CreateXIF(buffer,mSelection);
nsString* charset = nsnull;
nsAutoString defaultCharset; defaultCharset.AssignWithConversion("ISO-8859-1");
if (!mCharset.EqualsWithConversion("null") && !mCharset.IsEmpty())
charset = &mCharset;
nsIParser* parser;
rv = nsComponentManager::CreateInstance(kCParserCID,
nsnull,
kCParserIID,
(void **)&parser);
if (NS_SUCCEEDED(rv)) {
nsIHTMLContentSink* sink = nsnull;
if (mMimeType.EqualsWithConversion("text/html"))
rv = NS_New_HTML_ContentSinkStream(&sink, aStream, charset, mFlags);
else
rv = NS_New_HTMLToTXT_SinkStream(&sink, aStream, charset,
mWrapColumn, mFlags);
if (NS_SUCCEEDED(rv))
{
parser->SetContentSink(sink);
nsIDTD* dtd = nsnull;
rv = NS_NewXIFDTD(&dtd);
if (NS_SUCCEEDED(rv))
{
parser->RegisterDTD(dtd);
parser->Parse(buffer, 0, NS_ConvertToString("text/xif"), PR_FALSE, PR_TRUE);
}
NS_IF_RELEASE(dtd);
NS_IF_RELEASE(sink);
}
NS_RELEASE(parser);
}
}
return rv;
}
nsresult
NS_NewTextEncoder(nsIDocumentEncoder** aResult)
{
*aResult = new nsTextEncoder;
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
class nsDocumentEncoderFactory : public nsIFactory
{
public:
nsDocumentEncoderFactory();
virtual ~nsDocumentEncoderFactory();
// nsISupports methods
NS_DECL_ISUPPORTS
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult);
};
MOZ_DECL_CTOR_COUNTER(nsDocumentEncoderFactory);
nsDocumentEncoderFactory::nsDocumentEncoderFactory()
{
MOZ_COUNT_CTOR(nsDocumentEncoderFactory);
mRefCnt = 0;
}
nsDocumentEncoderFactory::~nsDocumentEncoderFactory()
{
MOZ_COUNT_DTOR(nsDocumentEncoderFactory);
}
NS_IMPL_ADDREF(nsDocumentEncoderFactory)
NS_IMPL_RELEASE(nsDocumentEncoderFactory)
nsresult nsDocumentEncoderFactory::QueryInterface(REFNSIID aIID,
void **aInstancePtr)
{
if (nsnull == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = 0;
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void *)(nsISupports*)this;
} else if (aIID.Equals(kIFactoryIID)) {
*aInstancePtr = (void *)(nsIFactory*)this;
}
if (nsnull == *aInstancePtr)
return NS_NOINTERFACE;
NS_ADDREF_THIS();
return NS_OK;
}
nsresult
nsDocumentEncoderFactory::CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult)
{
if (!aResult)
return NS_ERROR_NULL_POINTER;
*aResult = 0;
if (aIID.Equals(kCTextEncoderCID))
*aResult = new nsTextEncoder;
else
return NS_NOINTERFACE;
if (*aResult == NULL)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}

View File

@@ -0,0 +1,471 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.h"
#include "nsIContent.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIScriptObjectOwner.h"
#include "nsGenericElement.h"
#include "nsINameSpaceManager.h"
#include "nsINodeInfo.h"
#include "nsNodeInfoManager.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsDOMError.h"
static NS_DEFINE_IID(kIDOMDocumentFragmentIID, NS_IDOMDOCUMENTFRAGMENT_IID);
static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID);
class nsDocumentFragment : public nsIContent,
public nsIDOMDocumentFragment,
public nsIScriptObjectOwner
{
public:
nsDocumentFragment(nsIDocument* aOwnerDocument, nsINodeInfo *aNodeInfo);
virtual ~nsDocumentFragment();
// nsISupports
NS_DECL_ISUPPORTS
// interface nsIDOMDocumentFragment
NS_IMETHOD GetNodeName(nsString& aNodeName);
NS_IMETHOD GetNodeValue(nsString& aNodeValue);
NS_IMETHOD SetNodeValue(const nsString& aNodeValue);
NS_IMETHOD GetNodeType(PRUint16* aNodeType);
NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode)
{
*aParentNode = nsnull;
return NS_OK;
}
NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes)
{ return mInner.GetChildNodes(aChildNodes); }
NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild)
{ return mInner.GetFirstChild(aFirstChild); }
NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild)
{ return mInner.GetLastChild(aLastChild); }
NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling)
{
*aPreviousSibling = nsnull;
return NS_OK;
}
NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling)
{
*aNextSibling = nsnull;
return NS_OK;
}
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes)
{
*aAttributes = nsnull;
return NS_OK;
}
NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument);
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
nsIDOMNode** aReturn)
{ return mInner.InsertBefore(aNewChild, aRefChild, aReturn); }
NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
nsIDOMNode** aReturn)
{ return mInner.ReplaceChild(aNewChild, aOldChild, aReturn); }
NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{ return mInner.RemoveChild(aOldChild, aReturn); }
NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
{ return mInner.AppendChild(aNewChild, aReturn); }
NS_IMETHOD HasChildNodes(PRBool* aReturn)
{ return mInner.HasChildNodes(aReturn); }
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
NS_IMETHOD GetPrefix(nsString& aPrefix);
NS_IMETHOD SetPrefix(const nsString& aPrefix);
NS_IMETHOD GetNamespaceURI(nsString& aNamespaceURI);
NS_IMETHOD GetLocalName(nsString& aLocalName);
NS_IMETHOD Normalize();
NS_IMETHOD Supports(const nsString& aFeature, const nsString& aVersion,
PRBool* aReturn);
// interface nsIScriptObjectOwner
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void* aScriptObject);
// interface nsIContent
NS_IMETHOD ParseAttributeString(const nsString& aStr,
nsIAtom*& aName,
PRInt32& aNameSpaceID)
{ aName = nsnull;
aNameSpaceID = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID,
nsIAtom*& aPrefix)
{
aPrefix = nsnull;
return NS_OK;
}
NS_IMETHOD GetDocument(nsIDocument*& aResult) const
{ return mInner.GetDocument(aResult); }
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep, PRBool aCompileEventHandlers)
{ return mInner.SetDocument(aDocument, aDeep, aCompileEventHandlers); }
NS_IMETHOD GetParent(nsIContent*& aResult) const
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD SetParent(nsIContent* aParent)
{ return NS_OK; }
NS_IMETHOD GetNameSpaceID(PRInt32& aResult) const
{
aResult = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD GetTag(nsIAtom*& aResult) const
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD GetNodeInfo(nsINodeInfo*& aResult) const
{
aResult = nsnull;
return NS_OK;
}
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& aIndex) const
{ return mInner.IndexOf(aPossibleChild, aIndex); }
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 SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsString& aValue,
PRBool aNotify)
{ return NS_OK; }
NS_IMETHOD SetAttribute(nsINodeInfo* aNodeInfo,
const nsString& aValue,
PRBool aNotify)
{ return NS_OK; }
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
nsString& aResult) const
{ return NS_CONTENT_ATTR_NOT_THERE; }
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom*& aPrefix, nsString& aResult) const
{ return NS_CONTENT_ATTR_NOT_THERE; }
NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify)
{ return NS_OK; }
NS_IMETHOD GetAttributeNameAt(PRInt32 aIndex,
PRInt32& aNameSpaceID,
nsIAtom*& aName,
nsIAtom*& aPrefix) const
{
aName = nsnull;
aPrefix = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHOD GetAttributeCount(PRInt32& aCountResult) const
{
aCountResult = 0;
return NS_OK;
}
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const
{ return mInner.List(out, aIndent); }
NS_IMETHOD DumpContent(FILE* out = stdout, PRInt32 aIndent = 0,PRBool aDumpAll=PR_TRUE) const
{
return mInner.DumpContent(out, aIndent,aDumpAll);
}
NS_IMETHOD BeginConvertToXIF(nsIXIFConverter* aConverter) const
{ return NS_OK; }
NS_IMETHOD ConvertContentToXIF(nsIXIFConverter* aConverter) const
{ return NS_OK; }
NS_IMETHOD FinishConvertToXIF(nsIXIFConverter* aConverter) const
{ return NS_OK; }
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
NS_ENSURE_ARG_POINTER(aEventStatus);
*aEventStatus = nsEventStatus_eIgnore;
return NS_OK;
}
NS_IMETHOD GetContentID(PRUint32* aID) {
*aID = 0;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD SetContentID(PRUint32 aID) {
return NS_ERROR_NOT_IMPLEMENTED;
}
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); }
NS_IMETHOD SetFocus(nsIPresContext* aContext) {
return mInner.SetFocus(aContext);
}
NS_IMETHOD RemoveFocus(nsIPresContext* aContext) {
return mInner.RemoveFocus(aContext);
}
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const {
if (!aResult) {
return NS_ERROR_NULL_POINTER;
}
#ifdef DEBUG
*aResult = sizeof(*this);
#else
*aResult = 0;
#endif
return NS_OK;
}
protected:
nsGenericContainerElement mInner;
void* mScriptObject;
nsIDocument* mOwnerDocument;
};
nsresult
NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
nsIDocument* aOwnerDocument)
{
NS_ENSURE_ARG_POINTER(aInstancePtrResult);
nsCOMPtr<nsINodeInfoManager> nimgr;
nsCOMPtr<nsINodeInfo> nodeInfo;
nsresult rv;
if (aOwnerDocument) {
rv = aOwnerDocument->GetNodeInfoManager(*getter_AddRefs(nimgr));
} else {
rv = nsNodeInfoManager::GetAnonymousManager(*getter_AddRefs(nimgr));
}
NS_ENSURE_SUCCESS(rv, rv);
rv = nimgr->GetNodeInfo(NS_ConvertASCIItoUCS2("#document-fragment"),
nsnull, kNameSpaceID_None,
*getter_AddRefs(nodeInfo));
NS_ENSURE_SUCCESS(rv, rv);
nsDocumentFragment* it = new nsDocumentFragment(aOwnerDocument, nodeInfo);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIDOMDocumentFragmentIID,
(void**) aInstancePtrResult);
}
nsDocumentFragment::nsDocumentFragment(nsIDocument* aOwnerDocument,
nsINodeInfo *aNodeInfo)
{
NS_INIT_REFCNT();
mInner.Init(this, aNodeInfo);
mScriptObject = nsnull;
mOwnerDocument = aOwnerDocument;
NS_IF_ADDREF(mOwnerDocument);
}
nsDocumentFragment::~nsDocumentFragment()
{
NS_IF_RELEASE(mOwnerDocument);
}
NS_IMPL_ADDREF(nsDocumentFragment)
NS_IMPL_RELEASE(nsDocumentFragment)
nsresult
nsDocumentFragment::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (aIID.Equals(kISupportsIID)) {
nsIDOMDocumentFragment* tmp = this;
nsISupports* tmp2 = tmp;
*aInstancePtr = (void*) tmp2;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMDocumentFragmentIID)) {
nsIDOMDocumentFragment* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMNodeIID)) {
nsIDOMDocumentFragment* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
nsIScriptObjectOwner* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIContentIID)) {
nsIContent* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsDocumentFragment::GetNodeName(nsString& aNodeName)
{
aNodeName.AssignWithConversion("#document-fragment");
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::GetNodeValue(nsString& aNodeValue)
{
aNodeValue.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::SetNodeValue(const nsString& aNodeValue)
{
// The node value can't be modified
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_IMETHODIMP
nsDocumentFragment::GetNodeType(PRUint16* aNodeType)
{
*aNodeType = (PRUint16)nsIDOMNode::DOCUMENT_FRAGMENT_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
{
if (nsnull != mOwnerDocument) {
return mOwnerDocument->QueryInterface(kIDOMDocumentIID, (void **)aOwnerDocument);
}
else {
*aOwnerDocument = nsnull;
return NS_OK;
}
}
NS_IMETHODIMP
nsDocumentFragment::GetNamespaceURI(nsString& aNamespaceURI)
{
aNamespaceURI.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::GetPrefix(nsString& aPrefix)
{
aPrefix.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::SetPrefix(const nsString& aPrefix)
{
return NS_ERROR_DOM_NAMESPACE_ERR;
}
NS_IMETHODIMP
nsDocumentFragment::GetLocalName(nsString& aLocalName)
{
return GetNodeName(aLocalName);
}
NS_IMETHODIMP
nsDocumentFragment::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsDocumentFragment* it;
it = new nsDocumentFragment(mOwnerDocument, mInner.mNodeInfo);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
//XXX mInner.CopyInnerTo(this, &it->mInner);
return it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
}
NS_IMETHODIMP
nsDocumentFragment::Normalize()
{
// Nothing to do here yet
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::Supports(const nsString& aFeature, const nsString& aVersion,
PRBool* aReturn)
{
return nsGenericElement::InternalSupports(aFeature, aVersion, aReturn);
}
NS_IMETHODIMP
nsDocumentFragment::GetScriptObject(nsIScriptContext* aContext,
void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = mInner.GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptDocumentFragment(aContext,
(nsISupports*)(nsIDOMDocumentFragment*)this,
mOwnerDocument,
(void**)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
nsDocumentFragment::SetScriptObject(void* aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
#include "nscore.h"
#include "nsCaretProperties.h"
//-----------------------------------------------------------------------------
nsCaretProperties::nsCaretProperties()
: mCaretWidth(eDefaultCaretWidth)
, mBlinkRate(eDefaulBlinkRate)
{
// in your platform-specific class, get data from the OS in your constructor
}
//-----------------------------------------------------------------------------
nsCaretProperties* NewCaretProperties()
{
return new nsCaretProperties();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,652 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsGenericDOMDataNode_h___
#define nsGenericDOMDataNode_h___
#include "nsCOMPtr.h"
#include "nsIDOMCharacterData.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIContent.h"
#include "nsTextFragment.h"
#include "nsVoidArray.h"
#include "nsINameSpaceManager.h"
#include "nsITextContent.h"
#include "nsDOMError.h"
#include "nsIEventListenerManager.h"
extern const nsIID kIDOMCharacterDataIID;
extern const nsIID kIDOMNodeIID;
extern const nsIID kIDOMEventReceiverIID;
extern const nsIID kIDOMEventTargetIID;
extern const nsIID kIScriptObjectOwnerIID;
extern const nsIID kISupportsIID;
extern const nsIID kIContentIID;
class nsIDOMAttr;
class nsIDOMEventListener;
class nsIDOMNodeList;
class nsIFrame;
class nsIStyleContext;
class nsIStyleRule;
class nsISupportsArray;
class nsIDOMText;
class nsINodeInfo;
struct nsGenericDOMDataNode {
nsGenericDOMDataNode();
virtual ~nsGenericDOMDataNode();
// Implementation for nsIDOMNode
nsresult GetNodeValue(nsString& aNodeValue);
nsresult SetNodeValue(nsIContent *aOuterContent,
const nsString& aNodeValue);
nsresult GetParentNode(nsIDOMNode** aParentNode);
nsresult GetAttributes(nsIDOMNamedNodeMap** aAttributes) {
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nsnull;
return NS_OK;
}
nsresult GetPreviousSibling(nsIContent *aOuterContent,
nsIDOMNode** aPreviousSibling);
nsresult GetNextSibling(nsIContent *aOuterContent,
nsIDOMNode** aNextSibling);
nsresult GetChildNodes(nsIDOMNodeList** aChildNodes);
nsresult HasChildNodes(PRBool* aHasChildNodes) {
NS_ENSURE_ARG_POINTER(aHasChildNodes);
*aHasChildNodes = PR_FALSE;
return NS_OK;
}
nsresult GetFirstChild(nsIDOMNode** aFirstChild) {
NS_ENSURE_ARG_POINTER(aFirstChild);
*aFirstChild = nsnull;
return NS_OK;
}
nsresult GetLastChild(nsIDOMNode** aLastChild) {
NS_ENSURE_ARG_POINTER(aLastChild);
*aLastChild = nsnull;
return NS_OK;
}
nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
nsIDOMNode** aReturn) {
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
nsIDOMNode** aReturn) {
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
/*
* Data nodes can't have children, i.e. aOldChild can't be a child of
* this node.
*/
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) {
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
/*
* Data nodes can't have children, i.e. aOldChild can't be a child of
* this node.
*/
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) {
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
nsresult GetOwnerDocument(nsIDOMDocument** aOwnerDocument);
nsresult GetNamespaceURI(nsString& aNamespaceURI);
nsresult GetPrefix(nsString& aPrefix);
nsresult SetPrefix(const nsString& aPrefix);
nsresult Normalize();
nsresult Supports(const nsString& aFeature, const nsString& aVersion,
PRBool* aReturn);
// Implementation for nsIDOMCharacterData
nsresult GetData(nsString& aData);
nsresult SetData(nsIContent *aOuterContent, const nsString& aData);
nsresult GetLength(PRUint32* aLength);
nsresult SubstringData(PRUint32 aOffset, PRUint32 aCount, nsString& aReturn);
nsresult AppendData(nsIContent *aOuterContent, const nsString& aArg);
nsresult InsertData(nsIContent *aOuterContent, PRUint32 aOffset,
const nsString& aArg);
nsresult DeleteData(nsIContent *aOuterContent, PRUint32 aOffset,
PRUint32 aCount);
nsresult ReplaceData(nsIContent *aOuterContent, PRUint32 aOffset,
PRUint32 aCount, const nsString& aArg);
// nsIScriptObjectOwner interface
nsresult GetScriptObject(nsIContent *aOuterContent,
nsIScriptContext* aContext, void** aScriptObject);
nsresult SetScriptObject(void *aScriptObject);
// Implementation for nsIContent
nsresult GetDocument(nsIDocument*& aResult) const;
nsresult SetDocument(nsIDocument* aDocument, PRBool aDeep, PRBool aCompileEventHandlers);
nsresult GetParent(nsIContent*& aResult) const;
nsresult SetParent(nsIContent* aParent);
nsresult IsSynthetic(PRBool& aResult) {
aResult = PR_FALSE;
return NS_OK;
}
nsresult GetNameSpaceID(PRInt32& aID) const {
aID = kNameSpaceID_None;
return NS_OK;
}
nsresult ParseAttributeString(const nsString& aStr,
nsIAtom*& aName,
PRInt32& aNameSpaceID) {
aName = nsnull;
aNameSpaceID = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID,
nsIAtom*& aPrefix) {
aPrefix = nsnull;
return NS_OK;
}
nsresult SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify) {
return NS_OK;
}
nsresult SetAttribute(nsINodeInfo *aNodeInfo, const nsString& aValue,
PRBool aNotify) {
return NS_OK;
}
nsresult UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRBool aNotify) {
return NS_OK;
}
nsresult GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, nsString &aResult) const {
return NS_CONTENT_ATTR_NOT_THERE;
}
nsresult GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, nsIAtom*& aPrefix, nsString &aResult) const {
aPrefix = nsnull;
return NS_CONTENT_ATTR_NOT_THERE;
}
nsresult GetAttributeNameAt(PRInt32 aIndex, PRInt32& aNameSpaceID,
nsIAtom*& aName, nsIAtom*& aPrefix) const {
aNameSpaceID = kNameSpaceID_None;
aName = nsnull;
aPrefix = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult GetAttributeCount(PRInt32& aResult) const {
aResult = 0;
return NS_OK;
}
nsresult List(FILE* out, PRInt32 aIndent) const;
nsresult DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const;
nsresult HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
nsresult RangeAdd(nsIDOMRange& aRange);
nsresult RangeRemove(nsIDOMRange& aRange);
nsresult GetRangeList(nsVoidArray*& aResult) const;
nsresult SetFocus(nsIPresContext *aPresContext);
nsresult RemoveFocus(nsIPresContext *aPresContext);
nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult,
size_t aInstanceSize) const;
// Implementation for nsIContent
nsresult BeginConvertToXIF(nsIXIFConverter * aConverter) const;
nsresult ConvertContentToXIF(const nsIContent *aOuterContent,
nsIXIFConverter * aConverter) const;
nsresult FinishConvertToXIF(nsIXIFConverter * aConverter) const;
nsresult CanContainChildren(PRBool& aResult) const {
aResult = PR_FALSE;
return NS_OK;
}
nsresult ChildCount(PRInt32& aResult) const {
aResult = 0;
return NS_OK;
}
nsresult ChildAt(PRInt32 aIndex, nsIContent*& aResult) const {
aResult = nsnull;
return NS_OK;
}
nsresult IndexOf(nsIContent* aPossibleChild, PRInt32& aResult) const {
aResult = -1;
return NS_OK;
}
nsresult InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
nsresult ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify) {
return NS_OK;
}
nsresult RemoveChildAt(PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
nsresult SplitText(nsIContent *aOuterContent, PRUint32 aOffset,
nsIDOMText** aReturn);
nsresult GetText(const nsTextFragment** aFragmentsResult);
nsresult GetTextLength(PRInt32* aLengthResult);
nsresult CopyText(nsString& aResult);
nsresult SetText(nsIContent *aOuterContent,
const PRUnichar* aBuffer,
PRInt32 aLength,
PRBool aNotify);
nsresult SetText(nsIContent *aOuterContent,
const char* aBuffer,
PRInt32 aLength,
PRBool aNotify);
nsresult IsOnlyWhitespace(PRBool* aResult);
//----------------------------------------
nsresult GetListenerManager(nsIContent* aOuterContent, nsIEventListenerManager** aInstancePtrResult);
void ToCString(nsString& aBuf, PRInt32 aOffset, PRInt32 aLen) const;
nsIDocument* mDocument;
nsIContent* mParent;
void* mScriptObject;
nsIEventListenerManager* mListenerManager;
nsIContent* mCapturer;
nsTextFragment mText;
nsVoidArray *mRangeList;
};
//----------------------------------------------------------------------
/**
* Mostly implement the nsIDOMNode API by forwarding the methods to a
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*
* Note that classes using this macro will need to implement:
* NS_IMETHOD GetNodeType(PRUint16* aNodeType);
* NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
*/
#define NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetNodeName(nsString& aNodeName); \
NS_IMETHOD GetLocalName(nsString& aLocalName) { \
return GetNodeName(aLocalName); \
} \
NS_IMETHOD GetNodeValue(nsString& aNodeValue) { \
return _g.GetNodeValue(aNodeValue); \
} \
NS_IMETHOD SetNodeValue(const nsString& aNodeValue) { \
return _g.SetNodeValue(this, aNodeValue); \
} \
NS_IMETHOD GetNodeType(PRUint16* aNodeType); \
NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) { \
return _g.GetParentNode(aParentNode); \
} \
NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) { \
return _g.GetChildNodes(aChildNodes); \
} \
NS_IMETHOD HasChildNodes(PRBool* aHasChildNodes) { \
return _g.HasChildNodes(aHasChildNodes); \
} \
NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) { \
return _g.GetFirstChild(aFirstChild); \
} \
NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) { \
return _g.GetLastChild(aLastChild); \
} \
NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) { \
return _g.GetPreviousSibling(this, aPreviousSibling); \
} \
NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) { \
return _g.GetNextSibling(this, aNextSibling); \
} \
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) { \
return _g.GetAttributes(aAttributes); \
} \
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, \
nsIDOMNode** aReturn) { \
return _g.InsertBefore(aNewChild, aRefChild, aReturn); \
} \
NS_IMETHOD AppendChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { \
return _g.AppendChild(aOldChild, aReturn); \
} \
NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, \
nsIDOMNode** aReturn) { \
return _g.ReplaceChild(aNewChild, aOldChild, aReturn); \
} \
NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { \
return _g.RemoveChild(aOldChild, aReturn); \
} \
NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) { \
return _g.GetOwnerDocument(aOwnerDocument); \
} \
NS_IMETHOD GetNamespaceURI(nsString& aNamespaceURI) { \
return _g.GetNamespaceURI(aNamespaceURI); \
} \
NS_IMETHOD GetPrefix(nsString& aPrefix) { \
return _g.GetPrefix(aPrefix); \
} \
NS_IMETHOD SetPrefix(const nsString& aPrefix) { \
return _g.SetPrefix(aPrefix); \
} \
NS_IMETHOD Normalize() { \
return NS_OK; \
} \
NS_IMETHOD Supports(const nsString& aFeature, const nsString& aVersion,\
PRBool* aReturn) { \
return _g.Supports(aFeature, aVersion, aReturn); \
} \
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
#define NS_IMPL_IDOMCHARACTERDATA_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetData(nsString& aData) { \
return _g.GetData(aData); \
} \
NS_IMETHOD SetData(const nsString& aData) { \
return _g.SetData(this, aData); \
} \
NS_IMETHOD GetLength(PRUint32* aLength) { \
return _g.GetLength(aLength); \
} \
NS_IMETHOD SubstringData(PRUint32 aStart, PRUint32 aEnd, nsString& aReturn) { \
return _g.SubstringData(aStart, aEnd, aReturn); \
} \
NS_IMETHOD AppendData(const nsString& aData) { \
return _g.AppendData(this, aData); \
} \
NS_IMETHOD InsertData(PRUint32 aOffset, const nsString& aData) { \
return _g.InsertData(this, aOffset, aData); \
} \
NS_IMETHOD DeleteData(PRUint32 aOffset, PRUint32 aCount) { \
return _g.DeleteData(this, aOffset, aCount); \
} \
NS_IMETHOD ReplaceData(PRUint32 aOffset, PRUint32 aCount, \
const nsString& aData) { \
return _g.ReplaceData(this, aOffset, aCount, aData); \
}
/**
* Implement the nsIDOMEventReceiver API by forwarding the methods to a
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*/
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
} \
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent) { \
return _g.HandleEvent(aEvent); \
} \
NS_IMETHOD AddEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aUseCapture) { \
return _g.AddEventListener(aType, aListener, aUseCapture); \
} \
NS_IMETHOD RemoveEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aUseCapture) { \
return _g.RemoveEventListener(aType, aListener, aUseCapture); \
}
/**
* Implement the nsIScriptObjectOwner API by forwarding the methods to a
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*/
#define NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, \
void** aScriptObject) { \
return _g.GetScriptObject(this, aContext, aScriptObject); \
} \
NS_IMETHOD SetScriptObject(void *aScriptObject) { \
return _g.SetScriptObject(aScriptObject); \
}
#define NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetDocument(nsIDocument*& aResult) const { \
return _g.GetDocument(aResult); \
} \
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep, PRBool aCompileEventHandlers) { \
return _g.SetDocument(aDocument, aDeep, aCompileEventHandlers); \
} \
NS_IMETHOD GetParent(nsIContent*& aResult) const { \
return _g.GetParent(aResult); \
} \
NS_IMETHOD SetParent(nsIContent* aParent) { \
return _g.SetParent(aParent); \
} \
NS_IMETHOD CanContainChildren(PRBool& aResult) const { \
return _g.CanContainChildren(aResult); \
} \
NS_IMETHOD ChildCount(PRInt32& aResult) const { \
return _g.ChildCount(aResult); \
} \
NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const { \
return _g.ChildAt(aIndex, aResult); \
} \
NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aResult) const { \
return _g.IndexOf(aPossibleChild, aResult); \
} \
NS_IMETHOD InsertChildAt(nsIContent* aKid, PRInt32 aIndex, \
PRBool aNotify) { \
return _g.InsertChildAt(aKid, aIndex, aNotify); \
} \
NS_IMETHOD ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, \
PRBool aNotify) { \
return _g.ReplaceChildAt(aKid, aIndex, aNotify); \
} \
NS_IMETHOD AppendChildTo(nsIContent* aKid, PRBool aNotify) { \
return _g.AppendChildTo(aKid, aNotify); \
} \
NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) { \
return _g.RemoveChildAt(aIndex, aNotify); \
} \
NS_IMETHOD IsSynthetic(PRBool& aResult) { \
return _g.IsSynthetic(aResult); \
} \
NS_IMETHOD GetNameSpaceID(PRInt32& aID) const { \
return _g.GetNameSpaceID(aID); \
} \
NS_IMETHOD GetTag(nsIAtom*& aResult) const; \
NS_IMETHOD GetNodeInfo(nsINodeInfo*& aResult) const; \
NS_IMETHOD ParseAttributeString(const nsString& aStr, \
nsIAtom*& aName, \
PRInt32& aNameSpaceID) { \
return _g.ParseAttributeString(aStr, aName, aNameSpaceID); \
} \
NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID, \
nsIAtom*& aPrefix) { \
return _g.GetNameSpacePrefixFromId(aNameSpaceID, aPrefix); \
} \
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, \
nsString &aResult) const { \
return _g.GetAttribute(aNameSpaceID, aAttribute, aResult); \
} \
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, \
nsIAtom*& aPrefix, nsString &aResult) const { \
return _g.GetAttribute(aNameSpaceID, aAttribute, aPrefix, aResult); \
} \
NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, \
const nsString& aValue, PRBool aNotify) { \
return _g.SetAttribute(aNameSpaceID, aAttribute, aValue, aNotify); \
} \
NS_IMETHOD SetAttribute(nsINodeInfo* aNodeInfo, \
const nsString& aValue, PRBool aNotify) { \
return _g.SetAttribute(aNodeInfo, aValue, aNotify); \
} \
NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, \
PRBool aNotify) { \
return _g.UnsetAttribute(aNameSpaceID, aAttribute, aNotify); \
} \
NS_IMETHOD GetAttributeNameAt(PRInt32 aIndex, \
PRInt32& aNameSpaceID, \
nsIAtom*& aName, \
nsIAtom*& aPrefix) const { \
return _g.GetAttributeNameAt(aIndex, aNameSpaceID, aName, aPrefix); \
} \
NS_IMETHOD GetAttributeCount(PRInt32& aResult) const { \
return _g.GetAttributeCount(aResult); \
} \
NS_IMETHOD List(FILE* out, PRInt32 aIndent) const; \
NS_IMETHOD DumpContent(FILE* out, \
PRInt32 aIndent, \
PRBool aDumpAll) const; \
NS_IMETHOD BeginConvertToXIF(nsIXIFConverter * aConverter) const { \
return _g.BeginConvertToXIF(aConverter); \
} \
NS_IMETHOD ConvertContentToXIF(nsIXIFConverter * aConverter) const { \
return _g.ConvertContentToXIF(this, aConverter); \
} \
NS_IMETHOD FinishConvertToXIF(nsIXIFConverter * aConverter) const { \
return _g.FinishConvertToXIF(aConverter); \
} \
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext, \
nsEvent* aEvent, \
nsIDOMEvent** aDOMEvent, \
PRUint32 aFlags, \
nsEventStatus* aEventStatus); \
NS_IMETHOD GetContentID(PRUint32* aID); \
NS_IMETHOD SetContentID(PRUint32 aID); \
NS_IMETHOD RangeAdd(nsIDOMRange& aRange){ \
return _g.RangeAdd(aRange); \
} \
NS_IMETHOD RangeRemove(nsIDOMRange& aRange){ \
return _g.RangeRemove(aRange); \
} \
NS_IMETHOD GetRangeList(nsVoidArray*& aResult) const { \
return _g.GetRangeList(aResult); \
} \
NS_IMETHOD SetFocus(nsIPresContext* aPresContext) { \
return _g.SetFocus(aPresContext); \
} \
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext) { \
return _g.RemoveFocus(aPresContext); \
}
/**
* Implement the nsIDOMText API by forwarding the methods to a
* generic character data content object.
*/
#define NS_IMPL_IDOMTEXT_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD SplitText(PRUint32 aOffset, nsIDOMText** aReturn){ \
return _g.SplitText(this, aOffset, aReturn); \
}
/**
* Implement the nsITextContent API by forwarding the methods to a
* generic character data content object.
*/
#define NS_IMPL_ITEXTCONTENT_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetText(const nsTextFragment** aFragmentsResult) { \
return mInner.GetText(aFragmentsResult); \
} \
NS_IMETHOD GetTextLength(PRInt32* aLengthResult) { \
return mInner.GetTextLength(aLengthResult); \
} \
NS_IMETHOD CopyText(nsString& aResult) { \
return mInner.CopyText(aResult); \
} \
NS_IMETHOD SetText(const PRUnichar* aBuffer, \
PRInt32 aLength, \
PRBool aNotify){ \
return mInner.SetText(this, aBuffer, aLength, aNotify); \
} \
NS_IMETHOD SetText(const char* aBuffer, \
PRInt32 aLength, \
PRBool aNotify){ \
return mInner.SetText(this, aBuffer, aLength, aNotify); \
} \
NS_IMETHOD IsOnlyWhitespace(PRBool* aResult){ \
return mInner.IsOnlyWhitespace(aResult); \
} \
NS_IMETHOD CloneContent(PRBool aCloneText, nsITextContent** aClone);
/**
* This macro implements the portion of query interface that is
* generic to all html content objects.
*/
#define NS_IMPL_DOM_DATA_QUERY_INTERFACE(_id, _iptr, _this) \
if (_id.Equals(kISupportsIID)) { \
nsIContent* tmp = _this; \
nsISupports* tmp2 = tmp; \
*_iptr = (void*) tmp2; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMNodeIID)) { \
nsIDOMNode* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMCharacterDataIID)) { \
nsIDOMCharacterData* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMEventReceiverIID)) { \
nsCOMPtr<nsIEventListenerManager> man; \
if (NS_SUCCEEDED(mInner.GetListenerManager(this, getter_AddRefs(man)))){ \
return man->QueryInterface(kIDOMEventReceiverIID, (void**)_iptr); \
} \
return NS_NOINTERFACE; \
} \
if (_id.Equals(kIDOMEventTargetIID)) { \
nsCOMPtr<nsIEventListenerManager> man; \
if (NS_SUCCEEDED(mInner.GetListenerManager(this, getter_AddRefs(man)))){ \
return man->QueryInterface(kIDOMEventTargetIID, (void**)_iptr); \
} \
return NS_NOINTERFACE; \
} \
if (_id.Equals(kIScriptObjectOwnerIID)) { \
nsIScriptObjectOwner* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIContentIID)) { \
nsIContent* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
}
#endif /* nsGenericDOMDataNode_h___ */

View File

@@ -0,0 +1,89 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsGenericDOMNodeList.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsGenericElement.h"
nsGenericDOMNodeList::nsGenericDOMNodeList()
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
}
nsGenericDOMNodeList::~nsGenericDOMNodeList()
{
}
nsresult
nsGenericDOMNodeList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
if (aIID.Equals(kIDOMNodeListIID)) {
*aInstancePtr = (void*)(nsIDOMNodeList*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMNodeList*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsGenericDOMNodeList)
NS_IMPL_RELEASE(nsGenericDOMNodeList)
NS_IMETHODIMP
nsGenericDOMNodeList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = nsGenericElement::GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptNodeList(aContext, (nsISupports *)(nsIDOMNodeList *)this, nsnull, (void**)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
nsGenericDOMNodeList::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}

View File

@@ -0,0 +1,60 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsGenericDOMNodeList_h__
#define nsGenericDOMNodeList_h__
#include "nsISupports.h"
#include "nsIDOMNodeList.h"
#include "nsIScriptObjectOwner.h"
/**
* This is a base class for a generic DOM Node List. The base class
* provides implementations for nsISupports and nsIScriptObjectOwner,
* but it is up to the subclass to implement the core node list
* methods:
* GetLength
* Item
*
*/
class nsGenericDOMNodeList : public nsIDOMNodeList,
public nsIScriptObjectOwner
{
public:
nsGenericDOMNodeList();
virtual ~nsGenericDOMNodeList();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// The following need to be defined in the subclass
// nsIDOMNodeList interface
NS_IMETHOD GetLength(PRUint32* aLength)=0;
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn)=0;
protected:
void* mScriptObject;
};
#endif // nsGenericDOMNodeList_h__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,489 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsINameSpaceManager.h"
#include "nsINameSpace.h"
#include "nsHashtable.h"
#include "nsVoidArray.h"
#include "nsLayoutAtoms.h"
#include "nsString.h"
#include "nsCRT.h"
static NS_DEFINE_IID(kINameSpaceManagerIID, NS_INAMESPACEMANAGER_IID);
static NS_DEFINE_IID(kINameSpaceIID, NS_INAMESPACE_IID);
static const char kXMLNSNameSpaceURI[] = "http://www.w3.org/2000/xmlns";
static const char kXMLNameSpaceURI[] = "http://www.w3.org/XML/1998/namespace";
static const char kHTMLNameSpaceURI[] = "http://www.w3.org/TR/REC-html40"; // XXX?? "urn:w3-org-ns:HTML"??
// XXX To be removed: Bug 7834 ---
static const char kXHTMLNameSpaceURI[] = "http://www.w3.org/1999/xhtml";
static const char kXLinkNameSpaceURI[] = "http://www.w3.org/1999/xlink";
//-----------------------------------------------------------
// Name Space ID table support
static PRInt32 gNameSpaceTableRefs;
static nsHashtable* gURIToIDTable;
static nsVoidArray* gURIArray;
MOZ_DECL_CTOR_COUNTER(NameSpaceURIKey);
class NameSpaceURIKey : public nsHashKey {
public:
NameSpaceURIKey(const nsString* aString)
: mString(aString)
{
MOZ_COUNT_CTOR(NameSpaceURIKey);
}
virtual ~NameSpaceURIKey(void)
{
MOZ_COUNT_DTOR(NameSpaceURIKey);
}
virtual PRUint32 HashValue(void) const
{
#if 1 // case insensitive XXX should this be case sensitive???
PRUint32 hash = 0;
const PRUnichar* string = mString->GetUnicode();
PRUnichar ch;
while ((ch = *string++) != 0) {
// FYI: hash = hash*37 + ch
ch = nsCRT::ToLower(ch);
hash = ((hash << 5) + (hash << 2) + hash) + ch;
}
return hash;
#else
if (nsnull != mString) {
return nsCRT::HashValue(mString->GetUnicode());
}
return 0;
#endif
}
virtual PRBool Equals(const nsHashKey *aKey) const
{
const nsString* other = ((const NameSpaceURIKey*)aKey)->mString;
if (nsnull != mString) {
if (nsnull != other) {
return mString->EqualsIgnoreCase(*other); // XXX case sensitive?
}
return PR_FALSE;
}
return PRBool(nsnull == other);
}
virtual nsHashKey *Clone(void) const
{
return new NameSpaceURIKey(mString);
}
const nsString* mString;
};
static void AddRefTable()
{
if (0 == gNameSpaceTableRefs++) {
NS_ASSERTION(nsnull == gURIToIDTable, "already have URI table");
NS_ASSERTION(nsnull == gURIArray, "already have URI array");
gURIToIDTable = new nsHashtable();
gURIArray = new nsVoidArray();
nsString* xmlns = new nsString( NS_ConvertToString(kXMLNSNameSpaceURI) );
nsString* xml = new nsString( NS_ConvertToString(kXMLNameSpaceURI) );
nsString* xhtml = new nsString( NS_ConvertToString(kXHTMLNameSpaceURI) );
nsString* xlink = new nsString( NS_ConvertToString(kXLinkNameSpaceURI) );
nsString* html = new nsString( NS_ConvertToString(kHTMLNameSpaceURI) );
gURIArray->AppendElement(xmlns); // ordering here needs to match IDs
gURIArray->AppendElement(xml);
gURIArray->AppendElement(xhtml);
gURIArray->AppendElement(xlink);
gURIArray->AppendElement(html);
NameSpaceURIKey xmlnsKey(xmlns);
NameSpaceURIKey xmlKey(xml);
NameSpaceURIKey xhtmlKey(xhtml);
NameSpaceURIKey xlinkKey(xlink);
NameSpaceURIKey htmlKey(html);
gURIToIDTable->Put(&xmlnsKey, (void*)kNameSpaceID_XMLNS);
gURIToIDTable->Put(&xmlKey, (void*)kNameSpaceID_XML);
gURIToIDTable->Put(&xhtmlKey, (void*)kNameSpaceID_HTML);
gURIToIDTable->Put(&xlinkKey, (void*)kNameSpaceID_XLink);
gURIToIDTable->Put(&htmlKey, (void*)kNameSpaceID_HTML);
}
NS_ASSERTION(nsnull != gURIToIDTable, "no URI table");
NS_ASSERTION(nsnull != gURIArray, "no URI array");
}
static void ReleaseTable()
{
if (0 == --gNameSpaceTableRefs) {
delete gURIToIDTable;
PRInt32 index = gURIArray->Count();
while (0 < index--) {
nsString* str = (nsString*)gURIArray->ElementAt(index);
delete str;
}
delete gURIArray;
gURIToIDTable = nsnull;
gURIArray = nsnull;
}
}
static PRInt32 FindNameSpaceID(const nsString& aURI)
{
NS_ASSERTION(nsnull != gURIToIDTable, "no URI table");
NameSpaceURIKey key(&aURI);
void* value = gURIToIDTable->Get(&key);
if (nsnull != value) {
return PRInt32(value);
}
return kNameSpaceID_Unknown;
}
static const nsString* FindNameSpaceURI(PRInt32 aID)
{
NS_ASSERTION(nsnull != gURIArray, "no URI array");
return (const nsString*)gURIArray->ElementAt(aID - 1);
}
//-----------------------------------------------------------
// Name Space
class NameSpaceImpl : public nsINameSpace {
public:
NameSpaceImpl(nsINameSpaceManager* aManager,
NameSpaceImpl* aParent,
nsIAtom* aPrefix,
const nsString& aURI);
NameSpaceImpl(nsINameSpaceManager* aManager,
NameSpaceImpl* aParent,
nsIAtom* aPrefix,
PRInt32 aNameSpaceID);
virtual ~NameSpaceImpl();
NS_DECL_ISUPPORTS
NS_IMETHOD GetNameSpaceManager(nsINameSpaceManager*& aManager) const;
NS_IMETHOD GetNameSpaceID(PRInt32& aID) const;
NS_IMETHOD GetNameSpaceURI(nsString& aURI) const;
NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aPrefix) const;
NS_IMETHOD GetParentNameSpace(nsINameSpace*& aParent) const;
NS_IMETHOD FindNameSpace(nsIAtom* aPrefix, nsINameSpace*& aNameSpace) const;
NS_IMETHOD FindNameSpaceID(nsIAtom* aPrefix, PRInt32& aNameSpaceID) const;
NS_IMETHOD FindNameSpacePrefix(PRInt32 aNameSpaceID, nsIAtom*& aPrefix) const;
NS_IMETHOD CreateChildNameSpace(nsIAtom* aPrefix, const nsString& aURI,
nsINameSpace*& aChildNameSpace);
NS_IMETHOD CreateChildNameSpace(nsIAtom* aPrefix, PRInt32 aNameSpaceID,
nsINameSpace*& aChildNameSpace);
private:
// These are not supported and are not implemented!
NameSpaceImpl(const NameSpaceImpl& aCopy);
NameSpaceImpl& operator=(const NameSpaceImpl& aCopy);
public:
nsINameSpaceManager* mManager;
NameSpaceImpl* mParent;
nsIAtom* mPrefix;
PRInt32 mID;
};
NameSpaceImpl::NameSpaceImpl(nsINameSpaceManager* aManager,
NameSpaceImpl* aParent,
nsIAtom* aPrefix,
const nsString& aURI)
: mManager(aManager),
mParent(aParent),
mPrefix(aPrefix)
{
NS_ASSERTION(nsnull != aManager, "null namespace manager");
NS_INIT_REFCNT();
NS_ADDREF(mManager);
NS_IF_ADDREF(mParent);
NS_IF_ADDREF(mPrefix);
mManager->RegisterNameSpace(aURI, mID);
}
NameSpaceImpl::NameSpaceImpl(nsINameSpaceManager* aManager,
NameSpaceImpl* aParent,
nsIAtom* aPrefix,
PRInt32 aNameSpaceID)
: mManager(aManager),
mParent(aParent),
mPrefix(aPrefix),
mID(aNameSpaceID)
{
NS_ASSERTION(nsnull != aManager, "null namespace manager");
NS_INIT_REFCNT();
NS_ADDREF(mManager);
NS_IF_ADDREF(mParent);
NS_IF_ADDREF(mPrefix);
}
NameSpaceImpl::~NameSpaceImpl()
{
NS_RELEASE(mManager);
NS_IF_RELEASE(mParent);
NS_IF_RELEASE(mPrefix);
}
NS_IMPL_ISUPPORTS(NameSpaceImpl, kINameSpaceIID)
NS_IMETHODIMP
NameSpaceImpl::GetNameSpaceManager(nsINameSpaceManager*& aManager) const
{
NS_ASSERTION(nsnull != aManager, "null namespace manager");
aManager = mManager;
NS_ADDREF(aManager);
return NS_OK;
}
NS_IMETHODIMP
NameSpaceImpl::GetNameSpaceID(PRInt32& aID) const
{
aID = mID;
return NS_OK;
}
NS_IMETHODIMP
NameSpaceImpl::GetNameSpaceURI(nsString& aURI) const
{
NS_ASSERTION(nsnull != mManager, "null namespace manager");
return mManager->GetNameSpaceURI(mID, aURI);
}
NS_IMETHODIMP
NameSpaceImpl::GetNameSpacePrefix(nsIAtom*& aPrefix) const
{
aPrefix = mPrefix;
NS_IF_ADDREF(aPrefix);
return NS_OK;
}
NS_IMETHODIMP
NameSpaceImpl::GetParentNameSpace(nsINameSpace*& aParent) const
{
aParent = mParent;
NS_IF_ADDREF(aParent);
return NS_OK;
}
NS_IMETHODIMP
NameSpaceImpl::FindNameSpace(nsIAtom* aPrefix, nsINameSpace*& aNameSpace) const
{
const NameSpaceImpl* nameSpace = this;
do {
if (aPrefix == nameSpace->mPrefix) {
aNameSpace = (nsINameSpace*)nameSpace;
NS_ADDREF(aNameSpace);
return NS_OK;
}
nameSpace = nameSpace->mParent;
}
while (nsnull != nameSpace);
aNameSpace = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceImpl::FindNameSpaceID(nsIAtom* aPrefix, PRInt32& aNameSpaceID) const
{
const NameSpaceImpl* nameSpace = this;
do {
if (aPrefix == nameSpace->mPrefix) {
aNameSpaceID = nameSpace->mID;
return NS_OK;
}
nameSpace = nameSpace->mParent;
}
while (nsnull != nameSpace);
if (nsnull == aPrefix) {
aNameSpaceID = kNameSpaceID_None;
}
else {
aNameSpaceID = kNameSpaceID_Unknown;
}
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceImpl::FindNameSpacePrefix(PRInt32 aNameSpaceID, nsIAtom*& aPrefix) const
{
const NameSpaceImpl* nameSpace = this;
do {
if (aNameSpaceID == nameSpace->mID) {
aPrefix = nameSpace->mPrefix;
NS_IF_ADDREF(aPrefix);
return NS_OK;
}
nameSpace = nameSpace->mParent;
}
while (nsnull != nameSpace);
aPrefix = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceImpl::CreateChildNameSpace(nsIAtom* aPrefix, const nsString& aURI,
nsINameSpace*& aChildNameSpace)
{
NameSpaceImpl* child = new NameSpaceImpl(mManager, this, aPrefix, aURI);
if (child) {
return child->QueryInterface(kINameSpaceIID, (void**)&aChildNameSpace);
}
aChildNameSpace = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
NameSpaceImpl::CreateChildNameSpace(nsIAtom* aPrefix, PRInt32 aNameSpaceID,
nsINameSpace*& aChildNameSpace)
{
if (FindNameSpaceURI(aNameSpaceID)) {
NameSpaceImpl* child = new NameSpaceImpl(mManager, this, aPrefix, aNameSpaceID);
if (child) {
return child->QueryInterface(kINameSpaceIID, (void**)&aChildNameSpace);
}
aChildNameSpace = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
aChildNameSpace = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
//-----------------------------------------------------------
// Name Space Manager
class NameSpaceManagerImpl : public nsINameSpaceManager {
public:
NameSpaceManagerImpl();
NS_DECL_ISUPPORTS
NS_IMETHOD CreateRootNameSpace(nsINameSpace*& aRootNameSpace);
NS_IMETHOD RegisterNameSpace(const nsString& aURI,
PRInt32& aNameSpaceID);
NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID, nsString& aURI);
NS_IMETHOD GetNameSpaceID(const nsString& aURI, PRInt32& aNameSpaceID);
private:
// These are not supported and are not implemented!
NameSpaceManagerImpl(const NameSpaceManagerImpl& aCopy);
NameSpaceManagerImpl& operator=(const NameSpaceManagerImpl& aCopy);
protected:
virtual ~NameSpaceManagerImpl();
};
NameSpaceManagerImpl::NameSpaceManagerImpl()
{
NS_INIT_REFCNT();
AddRefTable();
}
NameSpaceManagerImpl::~NameSpaceManagerImpl()
{
ReleaseTable();
}
NS_IMPL_ISUPPORTS(NameSpaceManagerImpl, kINameSpaceManagerIID)
NS_IMETHODIMP
NameSpaceManagerImpl::CreateRootNameSpace(nsINameSpace*& aRootNameSpace)
{
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
aRootNameSpace = nsnull;
NameSpaceImpl* xmlns = new NameSpaceImpl(this, nsnull, nsLayoutAtoms::xmlnsNameSpace, kNameSpaceID_XMLNS);
if (nsnull != xmlns) {
NameSpaceImpl* xml = new NameSpaceImpl(this, xmlns, nsLayoutAtoms::xmlNameSpace, kNameSpaceID_XML);
if (nsnull != xml) {
rv = xml->QueryInterface(kINameSpaceIID, (void**)&aRootNameSpace);
}
else {
delete xmlns;
}
}
return rv;
}
NS_IMETHODIMP
NameSpaceManagerImpl::RegisterNameSpace(const nsString& aURI,
PRInt32& aNameSpaceID)
{
PRInt32 id = FindNameSpaceID(aURI);
if (kNameSpaceID_Unknown == id) {
nsString* uri = new nsString(aURI);
gURIArray->AppendElement(uri);
id = gURIArray->Count(); // id is index + 1
NameSpaceURIKey key(uri);
gURIToIDTable->Put(&key, (void*)id);
}
aNameSpaceID = id;
return NS_OK;
}
NS_IMETHODIMP
NameSpaceManagerImpl::GetNameSpaceURI(PRInt32 aNameSpaceID, nsString& aURI)
{
const nsString* result = FindNameSpaceURI(aNameSpaceID);
if (nsnull != result) {
aURI = *result;
return NS_OK;
}
aURI.Truncate();
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceManagerImpl::GetNameSpaceID(const nsString& aURI, PRInt32& aNameSpaceID)
{
aNameSpaceID = FindNameSpaceID(aURI);
return NS_OK;
}
NS_LAYOUT nsresult
NS_NewNameSpaceManager(nsINameSpaceManager** aInstancePtrResult)
{
if (aInstancePtrResult == nsnull) {
return NS_ERROR_NULL_POINTER;
}
NameSpaceManagerImpl *it = new NameSpaceManagerImpl();
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kINameSpaceManagerIID, (void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,400 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsNodeInfo.h"
#include "nsNodeInfoManager.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIAtom.h"
#include "nsINameSpaceManager.h"
#include "nsIServiceManager.h"
#include "nsIPref.h" // Used by the temp pref, should be removed!
static PRBool kStrictDOMLevel2 = PR_FALSE;
nsNodeInfo::nsNodeInfo()
: mInner(), mOwnerManager(nsnull)
{
NS_INIT_REFCNT();
static PRInt32 been_here = 0;
// Temporary hack that tells if some new DOM Level 2 features are on or off
if (!been_here) {
kStrictDOMLevel2 = PR_FALSE; // Default in case of failure
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
if (NS_SUCCEEDED(rv)) {
prefs->GetBoolPref("temp.DOMLevel2update.enabled", &kStrictDOMLevel2);
}
been_here = 1;
}
// End of temp hack.
}
nsNodeInfo::~nsNodeInfo()
{
if (mOwnerManager) {
mOwnerManager->RemoveNodeInfo(this);
NS_RELEASE(mOwnerManager);
}
NS_IF_RELEASE(mInner.mName);
NS_IF_RELEASE(mInner.mPrefix);
}
nsresult
nsNodeInfo::Init(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
nsNodeInfoManager *aOwnerManager)
{
NS_ENSURE_TRUE(!mInner.mName && !mInner.mPrefix && !mOwnerManager,
NS_ERROR_ALREADY_INITIALIZED);
NS_ENSURE_ARG_POINTER(aName);
NS_ENSURE_ARG_POINTER(aOwnerManager);
mInner.mName = aName;
NS_ADDREF(mInner.mName);
mInner.mPrefix = aPrefix;
NS_IF_ADDREF(mInner.mPrefix);
mInner.mNamespaceID = aNamespaceID;
mOwnerManager = aOwnerManager;
NS_ADDREF(mOwnerManager);
return NS_OK;
}
// nsISupports
NS_IMPL_THREADSAFE_ISUPPORTS(nsNodeInfo, NS_GET_IID(nsINodeInfo));
// nsINodeInfo
NS_IMETHODIMP
nsNodeInfo::GetName(nsString& aName)
{
NS_ENSURE_TRUE(mInner.mName, NS_ERROR_NOT_INITIALIZED);
return mInner.mName->ToString(aName);
}
NS_IMETHODIMP
nsNodeInfo::GetNameAtom(nsIAtom*& aAtom)
{
NS_ABORT_IF_FALSE(mInner.mName, "nsNodeInfo not initialized!");
aAtom = mInner.mName;
NS_IF_ADDREF(aAtom);
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetQualifiedName(nsString& aQualifiedName)
{
NS_ENSURE_TRUE(mInner.mName, NS_ERROR_NOT_INITIALIZED);
if (mInner.mPrefix && kStrictDOMLevel2) {
mInner.mPrefix->ToString(aQualifiedName);
aQualifiedName.Append(PRUnichar(':'));
}
const PRUnichar *name;
mInner.mName->GetUnicode(&name);
aQualifiedName.Append(name);
if (kStrictDOMLevel2 && mInner.mPrefix) {
nsCAutoString tmp; tmp.AssignWithConversion(aQualifiedName);
printf ("Possible DOM Error: .name, .nodeName or .tagName requested on a namespace element/attribute with the qulaified name '%s', is this OK?\n", (const char *)tmp);
}
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetLocalName(nsString& aLocalName)
{
NS_ENSURE_TRUE(mInner.mName, NS_ERROR_NOT_INITIALIZED);
#ifdef STRICT_DOM_LEVEL2_LOCALNAME
if (mInner.mNamespaceID > 0) {
return mInner.mName->ToString(aLocalName);
}
aLocalName.Truncate();
return NS_OK;
#else
return mInner.mName->ToString(aLocalName);
#endif
}
NS_IMETHODIMP
nsNodeInfo::GetPrefix(nsString& aPrefix)
{
if (mInner.mPrefix) {
mInner.mPrefix->ToString(aPrefix);
} else {
aPrefix.Truncate();
}
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetPrefixAtom(nsIAtom*& aAtom)
{
aAtom = mInner.mPrefix;
NS_IF_ADDREF(aAtom);
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetNamespaceURI(nsString& aNameSpaceURI)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
nsresult rv = NS_OK;
if (mInner.mNamespaceID > 0) {
nsCOMPtr<nsINameSpaceManager> nsm;
mOwnerManager->GetNamespaceManager(*getter_AddRefs(nsm));
NS_ENSURE_TRUE(nsm, NS_ERROR_NOT_INITIALIZED);
rv = nsm->GetNameSpaceURI(mInner.mNamespaceID, aNameSpaceURI);
} else {
aNameSpaceURI.Truncate();
}
return rv;
}
NS_IMETHODIMP
nsNodeInfo::GetNamespaceID(PRInt32& aResult)
{
aResult = mInner.mNamespaceID;
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetNodeInfoManager(nsINodeInfoManager*& aNodeInfoManager)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
aNodeInfoManager = mOwnerManager;
NS_ADDREF(aNodeInfoManager);
return NS_OK;
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(nsIAtom *aNameAtom)
{
return mInner.mName == aNameAtom;
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(const nsString& aName)
{
if (!mInner.mName) return PR_FALSE;
const PRUnichar *name;
mInner.mName->GetUnicode(&name);
return aName.Equals(name);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom)
{
return (mInner.mName == aNameAtom) && (mInner.mPrefix == aPrefixAtom);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(const nsString& aName, const nsString& aPrefix)
{
if (!mInner.mName) return PR_FALSE;
const PRUnichar *name, *prefix = nsnull;
mInner.mName->GetUnicode(&name);
if (mInner.mPrefix)
mInner.mPrefix->GetUnicode(&prefix);
return aName.Equals(name) && aPrefix.Equals(prefix);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(nsIAtom *aNameAtom, PRInt32 aNamespaceID)
{
return (mInner.mName == aNameAtom) && (mInner.mNamespaceID == aNamespaceID);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(const nsString& aName, PRInt32 aNamespaceID)
{
if (!mInner.mName) return PR_FALSE;
const PRUnichar *name;
mInner.mName->GetUnicode(&name);
return aName.Equals(name) && (mInner.mNamespaceID == aNamespaceID);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom,
PRInt32 aNamespaceID)
{
return (mInner.mName == aNameAtom) &&
(mInner.mPrefix == aPrefixAtom) &&
(mInner.mNamespaceID == aNamespaceID);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(const nsString& aName, const nsString& aPrefix,
PRInt32 aNamespaceID)
{
if (!mInner.mName) return PR_FALSE;
const PRUnichar *name, *prefix = nsnull;
mInner.mName->GetUnicode(&name);
if (mInner.mPrefix)
mInner.mPrefix->GetUnicode(&prefix);
return aName.Equals(name) && aPrefix.Equals(prefix) &&
(mInner.mNamespaceID == aNamespaceID);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::NamespaceEquals(PRInt32 aNamespaceID)
{
return mInner.mNamespaceID == aNamespaceID;
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::NamespaceEquals(const nsString& aNamespaceURI)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
nsCOMPtr<nsINameSpaceManager> nsmgr;
NS_ENSURE_SUCCESS(mOwnerManager->GetNamespaceManager(*getter_AddRefs(nsmgr)),
NS_ERROR_NOT_INITIALIZED);
PRInt32 nsid;
nsmgr->GetNameSpaceID(aNamespaceURI, nsid);
return mInner.mNamespaceID == nsid;
}
NS_IMETHODIMP
nsNodeInfo::NameChanged(nsIAtom *aName, nsINodeInfo*& aResult)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
return mOwnerManager->GetNodeInfo(aName, mInner.mPrefix, mInner.mNamespaceID,
aResult);
}
NS_IMETHODIMP
nsNodeInfo::PrefixChanged(nsIAtom *aPrefix, nsINodeInfo*& aResult)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
return mOwnerManager->GetNodeInfo(mInner.mName, aPrefix, mInner.mNamespaceID,
aResult);
}
PLHashNumber
nsNodeInfoInner::GetHashValue(const void *key)
{
#ifdef NS_DEBUG // Just to shut down a compiler warning
NS_WARN_IF_FALSE(key, "Null key passed to nsNodeInfo::GetHashValue!");
#endif
if (key) {
const nsNodeInfoInner *node = (const nsNodeInfoInner *)key;
// Is this an acceptable has value?
return (((PLHashNumber)node->mName) & 0xffff) >> 8;
}
return 0;
}
PRIntn
nsNodeInfoInner::KeyCompare(const void *key1, const void *key2)
{
#ifdef NS_DEBUG // Just to shut down a compiler warning
NS_WARN_IF_FALSE(key1 && key2, "Null key passed to nsNodeInfo::KeyCompare!");
#endif
if (!key1 || !key2) {
return PR_FALSE;
}
const nsNodeInfoInner *node1 = (const nsNodeInfoInner *)key1;
const nsNodeInfoInner *node2 = (const nsNodeInfoInner *)key2;
if (node1->mName == node2->mName &&
node1->mPrefix == node2->mPrefix &&
node1->mNamespaceID == node2->mNamespaceID) {
return PR_TRUE;
}
return PR_FALSE;
}

View File

@@ -0,0 +1,116 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsNodeInfo_h___
#define nsNodeInfo_h___
#include "nsINodeInfo.h"
#include "nsINameSpaceManager.h"
#include "plhash.h"
/*
* nsNodeInfoInner is used for two things:
*
* 1. as a member in nsNodeInfo for holding the name, prefix and
* namespace ID
* 2. as the hash key in the hash table in nsNodeInfoManager
*
* nsNodeInfoInner does not do any kind of reference counting, that's up
* to the user of this class, since nsNodeInfoInner is a member of
* nsNodeInfo the hash table doesn't need to delete the keys, when the
* value (nsNodeInfo) the key is automatically deleted.
*/
struct nsNodeInfoInner
{
nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
: mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID) {}
nsNodeInfoInner()
: mName(nsnull), mPrefix(nsnull), mNamespaceID(kNameSpaceID_None) {}
static PRIntn PR_CALLBACK KeyCompare(const void *key1, const void *key2);
static PLHashNumber PR_CALLBACK GetHashValue(const void *key);
nsIAtom* mName;
nsIAtom* mPrefix;
PRInt32 mNamespaceID;
};
class nsNodeInfoManager;
class nsNodeInfo : public nsINodeInfo
{
public:
NS_DECL_ISUPPORTS
// nsINodeInfo
NS_IMETHOD GetName(nsString& aName);
NS_IMETHOD GetNameAtom(nsIAtom*& aAtom);
NS_IMETHOD GetQualifiedName(nsString& aQualifiedName);
NS_IMETHOD GetLocalName(nsString& aLocalName);
NS_IMETHOD GetPrefix(nsString& aPrefix);
NS_IMETHOD GetPrefixAtom(nsIAtom*& aAtom);
NS_IMETHOD GetNamespaceURI(nsString& aNameSpaceURI);
NS_IMETHOD GetNamespaceID(PRInt32& aResult);
NS_IMETHOD GetNodeInfoManager(nsINodeInfoManager*& aNodeInfoManager);
NS_IMETHOD_(PRBool) Equals(nsIAtom *aNameAtom);
NS_IMETHOD_(PRBool) Equals(const nsString& aName);
NS_IMETHOD_(PRBool) Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom);
NS_IMETHOD_(PRBool) Equals(const nsString& aName,
const nsString& aPrefix);
NS_IMETHOD_(PRBool) Equals(nsIAtom *aNameAtom, PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) Equals(const nsString& aName, PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom,
PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) Equals(const nsString& aName, const nsString& aPrefix,
PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) NamespaceEquals(PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) NamespaceEquals(const nsString& aNamespaceURI);
NS_IMETHOD NameChanged(nsIAtom *aName, nsINodeInfo*& aResult);
NS_IMETHOD PrefixChanged(nsIAtom *aPrefix, nsINodeInfo*& aResult);
// nsNodeInfo
nsNodeInfo();
virtual ~nsNodeInfo();
/*
* Note! Init() must be called exactly once on every nsNodeInfo before
* the object is used, if Init() returns an error code the nsNodeInfo
* should not be used.
*
* aName and aOwnerManager may not be null.
*/
nsresult Init(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
nsNodeInfoManager *aOwnerManager);
protected:
friend class nsNodeInfoManager; // The NodeInfoManager needs to pass this
// to the hash table.
nsNodeInfoInner mInner;
nsNodeInfoManager* mOwnerManager; // Strong reference!
};
#endif /* nsNodeInfo_h___ */

View File

@@ -0,0 +1,312 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsNodeInfoManager.h"
#include "nsNodeInfo.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIAtom.h"
nsNodeInfoManager* nsNodeInfoManager::gAnonymousNodeInfoManager = nsnull;
PRUint32 nsNodeInfoManager::gNodeManagerCount = 0;
nsresult NS_NewNodeInfoManager(nsINodeInfoManager** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = new nsNodeInfoManager;
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aResult);
return NS_OK;
}
nsNodeInfoManager::nsNodeInfoManager()
: mNameSpaceManager(nsnull)
{
NS_INIT_REFCNT();
if (gNodeManagerCount == 1 && gAnonymousNodeInfoManager) {
/*
* If we get here the global nodeinfo manager was the first one created,
* in that case we're not holding a strong reference to the global nodeinfo
* manager. Now we're creating one more nodeinfo manager so we'll grab
* a strong reference to the global nodeinfo manager so that it's
* lifetime will be longer than the lifetime of the other node managers.
*/
NS_ADDREF(gAnonymousNodeInfoManager);
}
gNodeManagerCount++;
mNodeInfoHash = PL_NewHashTable(32, nsNodeInfoInner::GetHashValue,
nsNodeInfoInner::KeyCompare,
PL_CompareValues, nsnull, nsnull);
#ifdef DEBUG_jst
printf ("Creating NodeInfoManager, gcount = %d\n", gNodeManagerCount);
#endif
}
nsNodeInfoManager::~nsNodeInfoManager()
{
gNodeManagerCount--;
if (gNodeManagerCount == 1 && gAnonymousNodeInfoManager) {
NS_RELEASE(gAnonymousNodeInfoManager);
} else if (!gNodeManagerCount) {
/*
* Here we just make sure that we don't leave a dangling pointer to
* the global nodeinfo manager after it's deleted.
*/
gAnonymousNodeInfoManager = nsnull;
}
if (mNodeInfoHash)
PL_HashTableDestroy(mNodeInfoHash);
#ifdef DEBUG_jst
printf ("Removing NodeInfoManager, gcount = %d\n", gNodeManagerCount);
#endif
}
NS_IMPL_THREADSAFE_ISUPPORTS(nsNodeInfoManager,
NS_GET_IID(nsINodeInfoManager));
// nsINodeInfoManager
NS_IMETHODIMP
nsNodeInfoManager::Init(nsINameSpaceManager *aNameSpaceManager)
{
NS_ENSURE_ARG_POINTER(aNameSpaceManager);
NS_ENSURE_TRUE(mNodeInfoHash, NS_ERROR_OUT_OF_MEMORY);
mNameSpaceManager = aNameSpaceManager;
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG_POINTER(aName);
nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID);
void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey);
if (node) {
aNodeInfo = NS_STATIC_CAST(nsINodeInfo *, node);
NS_ADDREF(aNodeInfo);
return NS_OK;
}
nsNodeInfo *newNodeInfo = new nsNodeInfo();
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(newNodeInfo);
nsresult rv = newNodeInfo->Init(aName, aPrefix, aNamespaceID, this);
NS_ENSURE_SUCCESS(rv, rv);
PLHashEntry *he;
he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
NS_ENSURE_TRUE(he, NS_ERROR_OUT_OF_MEMORY);
aNodeInfo = newNodeInfo;
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(const nsString& aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG(aName.Length());
nsCOMPtr<nsIAtom> name(dont_AddRef(NS_NewAtom(aName)));
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
return GetNodeInfo(name, aPrefix, aNamespaceID, aNodeInfo);
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(const nsString& aName, const nsString& aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG(aName.Length());
nsCOMPtr<nsIAtom> name(dont_AddRef(NS_NewAtom(aName)));
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIAtom> prefix;
if (aPrefix.Length()) {
prefix = dont_AddRef(NS_NewAtom(aPrefix));
NS_ENSURE_TRUE(prefix, NS_ERROR_OUT_OF_MEMORY);
}
return GetNodeInfo(name, prefix, aNamespaceID, aNodeInfo);
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(const nsString& aName, const nsString& aPrefix,
const nsString& aNamespaceURI,
nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG(aName.Length());
nsCOMPtr<nsIAtom> name(dont_AddRef(NS_NewAtom(aName)));
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIAtom> prefix;
if (aPrefix.Length()) {
prefix = dont_AddRef(NS_NewAtom(aPrefix));
NS_ENSURE_TRUE(prefix, NS_ERROR_OUT_OF_MEMORY);
}
PRInt32 nsid = kNameSpaceID_None;
if (aNamespaceURI.Length()) {
if (!mNameSpaceManager) {
return NS_ERROR_NOT_INITIALIZED;
}
nsresult rv = mNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsid);
NS_ENSURE_SUCCESS(rv, rv);
}
return GetNodeInfo(name, prefix, nsid, aNodeInfo);
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(const nsString& aQualifiedName,
const nsString& aNamespaceURI,
nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG(aQualifiedName.Length());
nsAutoString name(aQualifiedName);
nsAutoString prefix;
PRInt32 nsoffset = name.FindChar(':');
if (-1 != nsoffset) {
name.Left(prefix, nsoffset);
name.Cut(0, nsoffset+1);
}
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(name)));
NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIAtom> prefixAtom;
if (prefix.Length()) {
prefixAtom = dont_AddRef(NS_NewAtom(prefix));
NS_ENSURE_TRUE(prefixAtom, NS_ERROR_OUT_OF_MEMORY);
}
PRInt32 nsid = kNameSpaceID_None;
if (aNamespaceURI.Length()) {
NS_ENSURE_TRUE(mNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsresult rv = mNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsid);
NS_ENSURE_SUCCESS(rv, rv);
}
return GetNodeInfo(nameAtom, prefixAtom, nsid, aNodeInfo);
}
NS_IMETHODIMP
nsNodeInfoManager::GetNamespaceManager(nsINameSpaceManager*& aNameSpaceManager)
{
NS_ENSURE_TRUE(mNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
aNameSpaceManager = mNameSpaceManager;
NS_ADDREF(aNameSpaceManager);
return NS_OK;
}
void
nsNodeInfoManager::RemoveNodeInfo(nsNodeInfo *aNodeInfo)
{
NS_WARN_IF_FALSE(aNodeInfo, "Trying to remove null nodeinfo from manager!");
if (aNodeInfo) {
PRBool ret = PL_HashTableRemove(mNodeInfoHash, &aNodeInfo->mInner);
NS_WARN_IF_FALSE(ret, "Can't find nsINodeInfo to remove!!!");
}
}
nsresult
nsNodeInfoManager::GetAnonymousManager(nsINodeInfoManager*& aNodeInfoManager)
{
if (!gAnonymousNodeInfoManager) {
gAnonymousNodeInfoManager = new nsNodeInfoManager;
if (!gAnonymousNodeInfoManager)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(gAnonymousNodeInfoManager);
nsresult rv = NS_NewNameSpaceManager(getter_AddRefs(gAnonymousNodeInfoManager->mNameSpaceManager));
if (NS_FAILED(rv)) {
NS_RELEASE(gAnonymousNodeInfoManager);
return rv;
}
}
aNodeInfoManager = gAnonymousNodeInfoManager;
/*
* If the only nodeinfo manager is the global one we don't hold a ref
* since the global nodeinfo manager should be destroyed when it's released,
* even if it's the last one arround.
*/
if (gNodeManagerCount > 1) {
NS_ADDREF(aNodeInfoManager);
}
return NS_OK;
}

View File

@@ -0,0 +1,83 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsNodeInfoManager_h___
#define nsNodeInfoManager_h___
#include "nsINodeInfo.h"
#include "nsINameSpaceManager.h"
#include "nsCOMPtr.h"
#include "plhash.h"
class nsNodeInfo;
class nsNodeInfoManager : public nsINodeInfoManager
{
public:
NS_DECL_ISUPPORTS
// nsINodeInfoManager
NS_IMETHOD Init(nsINameSpaceManager *aNameSpaceManager);
NS_IMETHOD GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNodeInfo(const nsString& aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNodeInfo(const nsString& aName, const nsString& aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNodeInfo(const nsString& aName, const nsString& aPrefix,
const nsString& aNamespaceURI,
nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNodeInfo(const nsString& aQualifiedName,
const nsString& aNamespaceURI,
nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNamespaceManager(nsINameSpaceManager*& aNameSpaceManager);
// nsNodeInfoManager
nsNodeInfoManager();
virtual ~nsNodeInfoManager();
void RemoveNodeInfo(nsNodeInfo *aNodeInfo);
static nsresult GetAnonymousManager(nsINodeInfoManager*& aNodeInfoManager);
private:
PLHashTable *mNodeInfoHash;
nsCOMPtr<nsINameSpaceManager> mNameSpaceManager;
/*
* gAnonymousNodeInfoManager is a global nodeinfo manager used for nodes
* that are no longer part of a document and for nodes that are created
* where no document is accessible.
*
* gAnonymousNodeInfoManager is allocated when requested for the first time
* and once the last nodeinfo manager (appart from gAnonymousNodeInfoManager)
* is destroyed gAnonymousNodeInfoManager is destroyed. If the global
* nodeinfo manager is the only nodeinfo manager used it can be deleted
* and later reallocated if all users of the nodeinfo manager drops the
* referernces to it.
*/
static nsNodeInfoManager *gAnonymousNodeInfoManager;
static PRUint32 gNodeManagerCount;
};
#endif /* nsNodeInfoManager_h___ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,232 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsRange_h___
#define nsRange_h___
/*
* nsRange.h: interface of the nsRange object.
*/
#include "nsIDOMRange.h"
#include "nsIDOMNSRange.h"
#include "nsCOMPtr.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIScriptObjectOwner.h"
#include "prmon.h"
class nsVoidArray;
class nsRange : public nsIDOMRange,
public nsIDOMNSRange,
public nsIScriptObjectOwner
{
public:
NS_DECL_ISUPPORTS
nsRange();
virtual ~nsRange();
// nsIDOMRange interface
NS_IMETHOD GetIsPositioned(PRBool* aIsPositioned);
NS_IMETHOD GetStartParent(nsIDOMNode** aStartParent);
NS_IMETHOD GetStartOffset(PRInt32* aStartOffset);
NS_IMETHOD GetEndParent(nsIDOMNode** aEndParent);
NS_IMETHOD GetEndOffset(PRInt32* aEndOffset);
NS_IMETHOD GetIsCollapsed(PRBool* aIsCollapsed);
NS_IMETHOD GetCommonParent(nsIDOMNode** aCommonParent);
NS_IMETHOD SetStart(nsIDOMNode* aParent, PRInt32 aOffset);
NS_IMETHOD SetStartBefore(nsIDOMNode* aSibling);
NS_IMETHOD SetStartAfter(nsIDOMNode* aSibling);
NS_IMETHOD SetEnd(nsIDOMNode* aParent, PRInt32 aOffset);
NS_IMETHOD SetEndBefore(nsIDOMNode* aSibling);
NS_IMETHOD SetEndAfter(nsIDOMNode* aSibling);
NS_IMETHOD Collapse(PRBool aToStart);
NS_IMETHOD Unposition();
NS_IMETHOD SelectNode(nsIDOMNode* aN);
NS_IMETHOD SelectNodeContents(nsIDOMNode* aN);
NS_IMETHOD CompareEndPoints(PRUint16 how, nsIDOMRange* srcRange, PRInt32* ret);
NS_IMETHOD DeleteContents();
NS_IMETHOD ExtractContents(nsIDOMDocumentFragment** aReturn);
NS_IMETHOD CloneContents(nsIDOMDocumentFragment** aReturn);
NS_IMETHOD InsertNode(nsIDOMNode* aN);
NS_IMETHOD SurroundContents(nsIDOMNode* aN);
NS_IMETHOD Clone(nsIDOMRange** aReturn);
NS_IMETHOD ToString(nsString& aReturn);
/*BEGIN nsIDOMNSRange interface implementations*/
NS_IMETHOD CreateContextualFragment(const nsString& aFragment,
nsIDOMDocumentFragment** aReturn);
NS_IMETHOD IsValidFragment(const nsString& aFragment, PRBool* aReturn);
NS_IMETHOD IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset,
PRBool* aResult);
NS_IMETHOD ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset,
PRInt16* aResult);
NS_IMETHOD IntersectsNode(nsIDOMNode* aNode, PRBool* aReturn);
NS_IMETHOD CompareNode(nsIDOMNode* aNode, PRInt16* aReturn);
/*END nsIDOMNSRange interface implementations*/
NS_IMETHOD GetHasGeneratedBefore(PRBool *aBool);
NS_IMETHOD GetHasGeneratedAfter(PRBool *aBool);
NS_IMETHOD SetHasGeneratedBefore(PRBool aBool);
NS_IMETHOD SetHasGeneratedAfter(PRBool aBool);
NS_IMETHOD SetBeforeAndAfter(PRBool aBefore, PRBool aAfter);
/*BEGIN nsIScriptObjectOwner interface implementations*/
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
/*END nsIScriptObjectOwner interface implementations*/
// nsRange interface extensions
static NS_METHOD OwnerGone(nsIContent* aParentNode);
static NS_METHOD OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset);
static NS_METHOD OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aRemovedNode);
static NS_METHOD OwnerChildReplaced(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aReplacedNode);
static NS_METHOD TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartOffset, PRInt32 aEndOffset, PRInt32 aReplaceLength);
//private: I wish VC++ would give me a &&*@!#$ break
PRBool mIsPositioned;
PRInt32 mStartOffset;
PRInt32 mEndOffset;
nsCOMPtr<nsIDOMNode> mStartParent;
nsCOMPtr<nsIDOMNode> mEndParent;
static PRMonitor *mMonitor; // monitor to protect the following statics
static nsVoidArray *mStartAncestors; // just keeping these static to avoid reallocing the arrays.
static nsVoidArray *mEndAncestors; // the contents of these arrays are discarded across calls.
static nsVoidArray *mStartAncestorOffsets; // this also makes nsRange objects lighter weight.
static nsVoidArray *mEndAncestorOffsets; //
// no copy's or assigns
nsRange(const nsRange&);
nsRange& operator=(const nsRange&);
// helper routines
static PRBool InSameDoc(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
static PRInt32 IndexOf(nsIDOMNode* aNode);
static PRInt32 FillArrayWithAncestors(nsVoidArray* aArray,nsIDOMNode* aNode);
static nsCOMPtr<nsIDOMNode> CommonParent(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
static nsresult GetDOMNodeFromContent(nsIContent* inContentNode, nsCOMPtr<nsIDOMNode>* outDomNode);
static nsresult GetContentFromDOMNode(nsIDOMNode* inDomNode, nsCOMPtr<nsIContent>* outContentNode);
static nsresult PopRanges(nsIDOMNode* aDestNode, PRInt32 aOffset, nsIContent* aSourceNode);
static nsresult Lock();
static nsresult Unlock();
static nsresult CloneSibsAndParents(nsIDOMNode* parentNode,
PRInt32 nodeOffset,
nsIDOMNode* clonedNode,
nsIDOMNode* commonParent,
nsIDOMDocumentFragment* docfrag,
PRBool leftP);
nsresult DoSetRange(nsIDOMNode* aStartN, PRInt32 aStartOffset,
nsIDOMNode* aEndN, PRInt32 aEndOffset);
PRBool IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOff,
nsIDOMNode* aEndN, PRInt32 aEndOff);
nsresult ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult);
PRInt32 GetAncestorsAndOffsets(nsIDOMNode* aNode, PRInt32 aOffset,
nsVoidArray* aAncestorNodes, nsVoidArray* aAncestorOffsets);
nsresult AddToListOf(nsIDOMNode* aNode);
nsresult RemoveFromListOf(nsIDOMNode* aNode);
nsresult ContentOwnsUs(nsIDOMNode* domNode);
protected:
void* mScriptObject;
PRBool mBeforeGenContent;
PRBool mAfterGenContent;
};
// Make a new nsIDOMRange object
nsresult NS_NewRange(nsIDOMRange** aInstancePtrResult);
/*************************************************************************************
* Utility routine to compare two "points", were a point is a node/offset pair
* Returns -1 if point1 < point2, 1, if point1 > point2,
* 0 if error or if point1 == point2.
************************************************************************************/
PRInt32 ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2);
/*************************************************************************************
* Utility routine to detect if a content node intersects a range
************************************************************************************/
PRBool IsNodeIntersectsRange(nsIContent* aNode, nsIDOMRange* aRange);
/*************************************************************************************
* Utility routine to detect if a content node starts before a range and/or
* ends after a range. If neither it is contained inside the range.
*
* XXX - callers responsibility to ensure node in same doc as range!
*
************************************************************************************/
nsresult CompareNodeToRange(nsIContent* aNode,
nsIDOMRange* aRange,
PRBool *outNodeBefore,
PRBool *outNodeAfter);
/*************************************************************************************
* Utility routine to create a pair of dom points to represent
* the start and end locations of a single node. Return false
* if we dont' succeed.
************************************************************************************/
PRBool GetNodeBracketPoints(nsIContent* aNode,
nsCOMPtr<nsIDOMNode>* outParent,
PRInt32* outStartOffset,
PRInt32* outEndOffset);
#endif /* nsRange_h___ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsTextContentChangeData.h"
// Create a new instance of nsTextContentChangeData with a refcnt of 1
nsresult
NS_NewTextContentChangeData(nsTextContentChangeData** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
nsTextContentChangeData* it = new nsTextContentChangeData();
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(it);
*aResult = it;
return NS_OK;
}
nsTextContentChangeData::nsTextContentChangeData()
: mType(Insert),
mOffset(0),
mLength(0),
mReplaceLength(0)
{
NS_INIT_REFCNT();
}
nsTextContentChangeData::~nsTextContentChangeData()
{
}
NS_IMPL_ISUPPORTS1(nsTextContentChangeData, nsITextContentChangeData);
NS_IMETHODIMP
nsTextContentChangeData::GetChangeType(ChangeType* aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mType;
return NS_OK;
}
NS_IMETHODIMP
nsTextContentChangeData::GetReplaceData(PRInt32* aOffset,
PRInt32* aSourceLength,
PRInt32* aReplaceLength)
{
NS_ENSURE_ARG_POINTER(aOffset);
NS_ENSURE_ARG_POINTER(aSourceLength);
NS_ENSURE_ARG_POINTER(aReplaceLength);
*aOffset = mOffset;
*aSourceLength = mLength;
*aReplaceLength = mReplaceLength;
return NS_OK;
}
NS_IMETHODIMP
nsTextContentChangeData::GetInsertData(PRInt32* aOffset,
PRInt32* aInsertLength)
{
NS_ENSURE_ARG_POINTER(aOffset);
NS_ENSURE_ARG_POINTER(aInsertLength);
*aOffset = mOffset;
*aInsertLength = mLength;
return NS_OK;
}
NS_IMETHODIMP
nsTextContentChangeData::GetAppendData(PRInt32* aOffset,
PRInt32* aAppendLength)
{
NS_ENSURE_ARG_POINTER(aOffset);
NS_ENSURE_ARG_POINTER(aAppendLength);
*aOffset = mOffset;
*aAppendLength = mLength;
return NS_OK;
}

View File

@@ -0,0 +1,72 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsTextContentChangeData_h___
#define nsTextContentChangeData_h___
#include "nsITextContent.h"
class nsTextContentChangeData : public nsITextContentChangeData {
public:
friend nsresult
NS_NewTextContentChangeData(nsTextContentChangeData** aResult);
// nsISupports
NS_DECL_ISUPPORTS
// nsITextContentChangedData
NS_IMETHOD GetChangeType(ChangeType* aResult);
NS_IMETHOD GetReplaceData(PRInt32* aOffset,
PRInt32* aSourceLength,
PRInt32* aReplaceLength);
NS_IMETHOD GetInsertData(PRInt32* aOffset,
PRInt32* aInsertLength);
NS_IMETHOD GetAppendData(PRInt32* aOffset,
PRInt32* aAppendLength);
void SetData(ChangeType aType, PRInt32 aOffset, PRInt32 aLength) {
mType = aType;
mOffset = aOffset;
mLength = aLength;
}
void SetReplaceLength(PRInt32 aReplaceLength) {
mReplaceLength = aReplaceLength;
}
protected:
nsTextContentChangeData();
virtual ~nsTextContentChangeData();
ChangeType mType;
PRInt32 mOffset;
PRInt32 mLength;
PRInt32 mReplaceLength; // only used for replace type
};
// Create a new instance of nsTextContentChangeData with a refcnt of 1
extern nsresult
NS_NewTextContentChangeData(nsTextContentChangeData** aResult);
#endif /* nsTextContentChangeData_h___ */

View File

@@ -0,0 +1,245 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsTextFragment.h"
#include "nsString.h"
#include "nsCRT.h"
nsTextFragment::~nsTextFragment()
{
ReleaseText();
}
void
nsTextFragment::ReleaseText()
{
if (mState.mLength && m1b && mState.mInHeap) {
if (mState.mIs2b) {
delete [] m2b;
}
else {
delete [] m1b;
}
}
m1b = nsnull;
mState.mIs2b = 0;
mState.mInHeap = 0;
mState.mLength = 0;
}
nsTextFragment::nsTextFragment(const nsTextFragment& aOther)
: m1b(nsnull),
mAllBits(0)
{
if (aOther.Is2b()) {
SetTo(aOther.Get2b(), aOther.GetLength());
}
else {
SetTo(aOther.Get1b(), aOther.GetLength());
}
}
nsTextFragment::nsTextFragment(const char* aString)
: m1b(nsnull),
mAllBits(0)
{
SetTo(aString, strlen(aString));
}
nsTextFragment::nsTextFragment(const PRUnichar* aString)
: m1b(nsnull),
mAllBits(0)
{
SetTo(aString, nsCRT::strlen(aString));
}
nsTextFragment::nsTextFragment(const nsString& aString)
: m1b(nsnull),
mAllBits(0)
{
SetTo(aString.GetUnicode(), aString.Length());
}
nsTextFragment&
nsTextFragment::operator=(const nsTextFragment& aOther)
{
if (aOther.Is2b()) {
SetTo(aOther.Get2b(), aOther.GetLength());
}
else {
SetTo(aOther.Get1b(), aOther.GetLength());
}
return *this;
}
nsTextFragment&
nsTextFragment::operator=(const char* aString)
{
SetTo(aString, nsCRT::strlen(aString));
return *this;
}
nsTextFragment&
nsTextFragment::operator=(const PRUnichar* aString)
{
SetTo(aString, nsCRT::strlen(aString));
return *this;
}
nsTextFragment&
nsTextFragment::operator=(const nsString& aString)
{
SetTo(aString.GetUnicode(), aString.Length());
return *this;
}
void
nsTextFragment::SetTo(PRUnichar* aBuffer, PRInt32 aLength, PRBool aRelease)
{
ReleaseText();
m2b = aBuffer;
mState.mIs2b = 1;
mState.mInHeap = aRelease ? 1 : 0;
mState.mLength = aLength;
}
void
nsTextFragment::SetTo(const PRUnichar* aBuffer, PRInt32 aLength)
{
ReleaseText();
if (0 != aLength) {
// See if we need to store the data in ucs2 or not
PRBool need2 = PR_FALSE;
const PRUnichar* ucp = aBuffer;
const PRUnichar* uend = aBuffer + aLength;
while (ucp < uend) {
PRUnichar ch = *ucp++;
if (ch >> 8) {
need2 = PR_TRUE;
break;
}
}
if (need2) {
// Use ucs2 storage because we have to
PRUnichar* nt = new PRUnichar[aLength];
if (nsnull != nt) {
// Copy data
nsCRT::memcpy(nt, aBuffer, sizeof(PRUnichar) * aLength);
// Setup our fields
m2b = nt;
mState.mIs2b = 1;
mState.mInHeap = 1;
mState.mLength = aLength;
}
}
else {
// Use 1 byte storage because we can
unsigned char* nt = new unsigned char[aLength];
if (nsnull != nt) {
// Copy data
unsigned char* cp = nt;
unsigned char* end = nt + aLength;
while (cp < end) {
*cp++ = (unsigned char) *aBuffer++;
}
// Setup our fields
m1b = nt;
mState.mIs2b = 0;
mState.mInHeap = 1;
mState.mLength = aLength;
}
}
}
}
void
nsTextFragment::SetTo(const char* aBuffer, PRInt32 aLength)
{
ReleaseText();
if (0 != aLength) {
unsigned char* nt = new unsigned char[aLength];
if (nsnull != nt) {
nsCRT::memcpy(nt, aBuffer, sizeof(unsigned char) * aLength);
m1b = nt;
mState.mIs2b = 0;
mState.mInHeap = 1;
mState.mLength = aLength;
}
}
}
void
nsTextFragment::AppendTo(nsString& aString) const
{
if (mState.mIs2b) {
aString.Append(m2b, mState.mLength);
}
else {
aString.AppendWithConversion((char*)m1b, mState.mLength);
}
}
void
nsTextFragment::CopyTo(PRUnichar* aDest, PRInt32 aOffset, PRInt32 aCount)
{
if (aOffset < 0) aOffset = 0;
if (aOffset + aCount > GetLength()) {
aCount = mState.mLength - aOffset;
}
if (0 != aCount) {
if (mState.mIs2b) {
nsCRT::memcpy(aDest, m2b + aOffset, sizeof(PRUnichar) * aCount);
}
else {
unsigned char* cp = m1b + aOffset;
unsigned char* end = cp + aCount;
while (cp < end) {
*aDest++ = PRUnichar(*cp++);
}
}
}
}
void
nsTextFragment::CopyTo(char* aDest, PRInt32 aOffset, PRInt32 aCount)
{
if (aOffset < 0) aOffset = 0;
if (aOffset + aCount > GetLength()) {
aCount = mState.mLength - aOffset;
}
if (0 != aCount) {
if (mState.mIs2b) {
PRUnichar* cp = m2b + aOffset;
PRUnichar* end = cp + aCount;
while (cp < end) {
*aDest++ = (unsigned char) (*cp++);
}
}
else {
nsCRT::memcpy(aDest, m1b + aOffset, sizeof(char) * aCount);
}
}
}

View File

@@ -0,0 +1,270 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIDOMText.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIContent.h"
#include "nsITextContent.h"
#include "nsGenericDOMDataNode.h"
#include "nsFrame.h"
#include "nsIDocument.h"
#include "nsCRT.h"
#include "nsLayoutAtoms.h"
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
class nsTextNode : public nsIDOMText,
public nsIScriptObjectOwner,
public nsITextContent
{
public:
nsTextNode();
virtual ~nsTextNode();
// nsISupports
NS_DECL_ISUPPORTS
// nsIDOMNode
NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(mInner)
// nsIDOMCharacterData
NS_IMPL_IDOMCHARACTERDATA_USING_GENERIC_DOM_DATA(mInner)
// nsIDOMText
NS_IMPL_IDOMTEXT_USING_GENERIC_DOM_DATA(mInner)
// nsIScriptObjectOwner
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(mInner)
// nsIContent
NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner)
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const {
return mInner.SizeOf(aSizer, aResult, sizeof(*this));
}
// nsITextContent
NS_IMPL_ITEXTCONTENT_USING_GENERIC_DOM_DATA(mInner)
protected:
nsGenericDOMDataNode mInner;
PRUint32 mContentID;
};
nsresult
NS_NewTextNode(nsIContent** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsTextNode* it;
NS_NEWXPCOM(it, nsTextNode);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIContentIID, (void **) aInstancePtrResult);
}
nsTextNode::nsTextNode()
{
NS_INIT_REFCNT();
mContentID = 0;
}
nsTextNode::~nsTextNode()
{
}
NS_IMPL_ADDREF(nsTextNode)
NS_IMPL_RELEASE(nsTextNode)
NS_IMETHODIMP
nsTextNode::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_DOM_DATA_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMTextIID)) {
nsIDOMText* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kITextContentIID)) {
nsITextContent* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsTextNode::GetTag(nsIAtom*& aResult) const
{
aResult = nsLayoutAtoms::textTagName;
NS_ADDREF(aResult);
return NS_OK;
}
NS_IMETHODIMP
nsTextNode::GetNodeInfo(nsINodeInfo*& aResult) const
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsTextNode::GetNodeName(nsString& aNodeName)
{
aNodeName.AssignWithConversion("#text");
return NS_OK;
}
NS_IMETHODIMP
nsTextNode::GetNodeType(PRUint16* aNodeType)
{
*aNodeType = (PRUint16)nsIDOMNode::TEXT_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsTextNode::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsresult result = NS_OK;
nsTextNode* it;
NS_NEWXPCOM(it, nsTextNode);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
// XXX Increment the ref count before calling any
// methods. If they do a QI and then a Release()
// the instance will be deleted.
result = it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
if (NS_FAILED(result)) {
return result;
}
nsAutoString data;
result = GetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
result = it->SetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
return result;
}
NS_IMETHODIMP
nsTextNode::CloneContent(PRBool aCloneText, nsITextContent** aReturn)
{
nsresult result = NS_OK;
nsTextNode* it;
NS_NEWXPCOM(it, nsTextNode);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
result = it->QueryInterface(kITextContentIID, (void**) aReturn);
if (NS_FAILED(result) || !aCloneText) {
return result;
}
nsAutoString data;
result = GetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
result = it->SetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
return result;
}
NS_IMETHODIMP
nsTextNode::List(FILE* out, PRInt32 aIndent) const
{
NS_PRECONDITION(nsnull != mInner.mDocument, "bad content");
PRInt32 index;
for (index = aIndent; --index >= 0; ) fputs(" ", out);
fprintf(out, "Text@%p refcount=%d<", this, mRefCnt);
nsAutoString tmp;
mInner.ToCString(tmp, 0, mInner.mText.GetLength());
fputs(tmp, out);
fputs(">\n", out);
return NS_OK;
}
NS_IMETHODIMP
nsTextNode::DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const
{
NS_PRECONDITION(nsnull != mInner.mDocument, "bad content");
if(aDumpAll) {
PRInt32 index;
for (index = aIndent; --index >= 0; ) fputs(" ", out);
nsAutoString tmp;
mInner.ToCString(tmp, 0, mInner.mText.GetLength());
if(!tmp.EqualsWithConversion("\\n")) {
fputs(tmp, out);
if(aIndent) fputs("\n", out);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsTextNode::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
NS_IMETHODIMP
nsTextNode::GetContentID(PRUint32* aID)
{
*aID = mContentID;
return NS_OK;
}
NS_IMETHODIMP
nsTextNode::SetContentID(PRUint32 aID)
{
mContentID = aID;
return NS_OK;
}

View File

@@ -0,0 +1,52 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsLayoutAtoms.h"
// define storage for all atoms
#define LAYOUT_ATOM(_name, _value) nsIAtom* nsLayoutAtoms::_name;
#include "nsLayoutAtomList.h"
#undef LAYOUT_ATOM
static nsrefcnt gRefCnt;
void nsLayoutAtoms::AddRefAtoms()
{
if (0 == gRefCnt++) {
// create atoms
#define LAYOUT_ATOM(_name, _value) _name = NS_NewAtom(_value);
#include "nsLayoutAtomList.h"
#undef LAYOUT_ATOM
}
}
void nsLayoutAtoms::ReleaseAtoms()
{
NS_PRECONDITION(gRefCnt != 0, "bad release atoms");
if (--gRefCnt == 0) {
// release atoms
#define LAYOUT_ATOM(_name, _value) NS_RELEASE(_name);
#include "nsLayoutAtomList.h"
#undef LAYOUT_ATOM
}
}

View File

@@ -0,0 +1,245 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsTextFragment.h"
#include "nsString.h"
#include "nsCRT.h"
nsTextFragment::~nsTextFragment()
{
ReleaseText();
}
void
nsTextFragment::ReleaseText()
{
if (mState.mLength && m1b && mState.mInHeap) {
if (mState.mIs2b) {
delete [] m2b;
}
else {
delete [] m1b;
}
}
m1b = nsnull;
mState.mIs2b = 0;
mState.mInHeap = 0;
mState.mLength = 0;
}
nsTextFragment::nsTextFragment(const nsTextFragment& aOther)
: m1b(nsnull),
mAllBits(0)
{
if (aOther.Is2b()) {
SetTo(aOther.Get2b(), aOther.GetLength());
}
else {
SetTo(aOther.Get1b(), aOther.GetLength());
}
}
nsTextFragment::nsTextFragment(const char* aString)
: m1b(nsnull),
mAllBits(0)
{
SetTo(aString, strlen(aString));
}
nsTextFragment::nsTextFragment(const PRUnichar* aString)
: m1b(nsnull),
mAllBits(0)
{
SetTo(aString, nsCRT::strlen(aString));
}
nsTextFragment::nsTextFragment(const nsString& aString)
: m1b(nsnull),
mAllBits(0)
{
SetTo(aString.GetUnicode(), aString.Length());
}
nsTextFragment&
nsTextFragment::operator=(const nsTextFragment& aOther)
{
if (aOther.Is2b()) {
SetTo(aOther.Get2b(), aOther.GetLength());
}
else {
SetTo(aOther.Get1b(), aOther.GetLength());
}
return *this;
}
nsTextFragment&
nsTextFragment::operator=(const char* aString)
{
SetTo(aString, nsCRT::strlen(aString));
return *this;
}
nsTextFragment&
nsTextFragment::operator=(const PRUnichar* aString)
{
SetTo(aString, nsCRT::strlen(aString));
return *this;
}
nsTextFragment&
nsTextFragment::operator=(const nsString& aString)
{
SetTo(aString.GetUnicode(), aString.Length());
return *this;
}
void
nsTextFragment::SetTo(PRUnichar* aBuffer, PRInt32 aLength, PRBool aRelease)
{
ReleaseText();
m2b = aBuffer;
mState.mIs2b = 1;
mState.mInHeap = aRelease ? 1 : 0;
mState.mLength = aLength;
}
void
nsTextFragment::SetTo(const PRUnichar* aBuffer, PRInt32 aLength)
{
ReleaseText();
if (0 != aLength) {
// See if we need to store the data in ucs2 or not
PRBool need2 = PR_FALSE;
const PRUnichar* ucp = aBuffer;
const PRUnichar* uend = aBuffer + aLength;
while (ucp < uend) {
PRUnichar ch = *ucp++;
if (ch >> 8) {
need2 = PR_TRUE;
break;
}
}
if (need2) {
// Use ucs2 storage because we have to
PRUnichar* nt = new PRUnichar[aLength];
if (nsnull != nt) {
// Copy data
nsCRT::memcpy(nt, aBuffer, sizeof(PRUnichar) * aLength);
// Setup our fields
m2b = nt;
mState.mIs2b = 1;
mState.mInHeap = 1;
mState.mLength = aLength;
}
}
else {
// Use 1 byte storage because we can
unsigned char* nt = new unsigned char[aLength];
if (nsnull != nt) {
// Copy data
unsigned char* cp = nt;
unsigned char* end = nt + aLength;
while (cp < end) {
*cp++ = (unsigned char) *aBuffer++;
}
// Setup our fields
m1b = nt;
mState.mIs2b = 0;
mState.mInHeap = 1;
mState.mLength = aLength;
}
}
}
}
void
nsTextFragment::SetTo(const char* aBuffer, PRInt32 aLength)
{
ReleaseText();
if (0 != aLength) {
unsigned char* nt = new unsigned char[aLength];
if (nsnull != nt) {
nsCRT::memcpy(nt, aBuffer, sizeof(unsigned char) * aLength);
m1b = nt;
mState.mIs2b = 0;
mState.mInHeap = 1;
mState.mLength = aLength;
}
}
}
void
nsTextFragment::AppendTo(nsString& aString) const
{
if (mState.mIs2b) {
aString.Append(m2b, mState.mLength);
}
else {
aString.AppendWithConversion((char*)m1b, mState.mLength);
}
}
void
nsTextFragment::CopyTo(PRUnichar* aDest, PRInt32 aOffset, PRInt32 aCount)
{
if (aOffset < 0) aOffset = 0;
if (aOffset + aCount > GetLength()) {
aCount = mState.mLength - aOffset;
}
if (0 != aCount) {
if (mState.mIs2b) {
nsCRT::memcpy(aDest, m2b + aOffset, sizeof(PRUnichar) * aCount);
}
else {
unsigned char* cp = m1b + aOffset;
unsigned char* end = cp + aCount;
while (cp < end) {
*aDest++ = PRUnichar(*cp++);
}
}
}
}
void
nsTextFragment::CopyTo(char* aDest, PRInt32 aOffset, PRInt32 aCount)
{
if (aOffset < 0) aOffset = 0;
if (aOffset + aCount > GetLength()) {
aCount = mState.mLength - aOffset;
}
if (0 != aCount) {
if (mState.mIs2b) {
PRUnichar* cp = m2b + aOffset;
PRUnichar* end = cp + aCount;
while (cp < end) {
*aDest++ = (unsigned char) (*cp++);
}
}
else {
nsCRT::memcpy(aDest, m1b + aOffset, sizeof(char) * aCount);
}
}
}

View File

@@ -0,0 +1,5 @@
#
# This is a list of local files which get copied to the mozilla:dist:layout directory
#
nsContentList.h
nsNodeInfoManager.h

View File

@@ -0,0 +1,96 @@
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = layout
LIBRARY_NAME = gkbase_s
CPPSRCS = \
nsAutoCopy.cpp \
nsCaret.cpp \
nsCommentNode.cpp \
nsContentIterator.cpp \
nsContentList.cpp \
nsContentPolicy.cpp \
nsDocument.cpp \
nsDocumentEncoder.cpp \
nsDocumentFragment.cpp \
nsDocumentViewer.cpp \
nsDOMAttribute.cpp \
nsDOMAttributeMap.cpp \
nsDOMDocumentType.cpp \
nsFrameImageLoader.cpp \
nsFrameList.cpp \
nsFrameTraversal.cpp \
nsFrameUtil.cpp \
nsGalleyContext.cpp \
nsGeneratedIterator.cpp \
nsGenericDOMDataNode.cpp \
nsGenericDOMNodeList.cpp \
nsGenericElement.cpp \
nsLayoutAtoms.cpp \
nsLayoutDebugger.cpp \
nsLayoutUtils.cpp \
nsNameSpaceManager.cpp \
nsNodeInfo.cpp \
nsNodeInfoManager.cpp \
nsPresContext.cpp \
nsPresState.cpp \
nsPrintContext.cpp \
nsPrintPreviewContext.cpp \
nsRange.cpp \
nsSelection.cpp \
nsSpaceManager.cpp \
nsStyleChangeList.cpp \
nsStyleCoord.cpp \
nsStyleContext.cpp \
nsStyleSet.cpp \
nsTextContentChangeData.cpp \
nsTextFragment.cpp \
nsTextNode.cpp \
nsXIFConverter.cpp \
nsLayoutHistoryState.cpp \
$(NULL)
EXPORTS = \
nsDocument.h \
nsNodeInfoManager.h \
nsXIFConverter.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
# we don't want the shared lib, but we want to force the creation of a static lib.
override NO_SHARED_LIB=1
override NO_STATIC_LIB=
include $(topsrcdir)/config/rules.mk
DEFINES += -D_IMPL_NS_LAYOUT
INCLUDES += -I$(srcdir)/../../html/base/src -I$(srcdir)/../../html/style/src -I$(srcdir)/../../xul/base/src

View File

@@ -0,0 +1,145 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
LIBRARY_NAME=raptorlayout_s
DEFINES=-D_IMPL_NS_LAYOUT -DWIN32_LEAN_AND_MEAN
!if defined(XP_NEW_SELECTION)
DEFINES = $(DEFINES) -DXP_NEW_SELECTION
!endif
CPPSRCS = \
nsAutoCopy.cpp \
nsCommentNode.cpp \
nsGenericElement.cpp \
nsGenericDOMDataNode.cpp \
nsGenericDOMNodeList.cpp \
nsContentList.cpp \
nsContentIterator.cpp \
nsContentPolicy.cpp \
nsDocument.cpp \
nsDocumentEncoder.cpp \
nsDocumentFragment.cpp \
nsDocumentViewer.cpp \
nsDOMAttribute.cpp \
nsDOMAttributeMap.cpp \
nsDOMDocumentType.cpp \
nsFrameImageLoader.cpp \
nsFrameList.cpp \
nsFrameTraversal.cpp \
nsFrameUtil.cpp \
nsGalleyContext.cpp \
nsGeneratedIterator.cpp \
nsNameSpaceManager.cpp \
nsNodeInfo.cpp \
nsNodeInfoManager.cpp \
nsPresContext.cpp \
nsPresState.cpp \
nsPrintContext.cpp \
nsPrintPreviewContext.cpp \
nsSpaceManager.cpp \
nsStyleContext.cpp \
nsStyleChangeList.cpp \
nsStyleCoord.cpp \
nsStyleSet.cpp \
nsTextFragment.cpp \
nsXIFConverter.cpp \
nsSelection.cpp \
nsLayoutAtoms.cpp \
nsLayoutDebugger.cpp \
nsLayoutUtils.cpp \
nsCaret.cpp \
nsRange.cpp \
nsTextContentChangeData.cpp \
nsTextNode.cpp \
nsLayoutHistoryState.cpp \
$(NULL)
MODULE=raptor
# EXPORTS=
CPP_OBJS= \
.\$(OBJDIR)\nsAutoCopy.obj \
.\$(OBJDIR)\nsCommentNode.obj \
.\$(OBJDIR)\nsGenericDOMDataNode.obj \
.\$(OBJDIR)\nsGenericDOMNodeList.obj \
.\$(OBJDIR)\nsGenericElement.obj \
.\$(OBJDIR)\nsContentList.obj \
.\$(OBJDIR)\nsContentIterator.obj \
.\$(OBJDIR)\nsContentPolicy.obj \
.\$(OBJDIR)\nsDocument.obj \
.\$(OBJDIR)\nsDocumentEncoder.obj \
.\$(OBJDIR)\nsDocumentFragment.obj \
.\$(OBJDIR)\nsDocumentViewer.obj \
.\$(OBJDIR)\nsDOMAttribute.obj \
.\$(OBJDIR)\nsDOMAttributeMap.obj \
.\$(OBJDIR)\nsDOMDocumentType.obj \
.\$(OBJDIR)\nsFrameImageLoader.obj \
.\$(OBJDIR)\nsFrameList.obj \
.\$(OBJDIR)\nsFrameTraversal.obj \
.\$(OBJDIR)\nsFrameUtil.obj \
.\$(OBJDIR)\nsGalleyContext.obj \
.\$(OBJDIR)\nsGeneratedIterator.obj \
.\$(OBJDIR)\nsNameSpaceManager.obj \
.\$(OBJDIR)\nsNodeInfo.obj \
.\$(OBJDIR)\nsNodeInfoManager.obj \
.\$(OBJDIR)\nsPresContext.obj \
.\$(OBJDIR)\nsPresState.obj \
.\$(OBJDIR)\nsPrintContext.obj \
.\$(OBJDIR)\nsPrintPreviewContext.obj \
.\$(OBJDIR)\nsSpaceManager.obj \
.\$(OBJDIR)\nsStyleContext.obj \
.\$(OBJDIR)\nsStyleChangeList.obj \
.\$(OBJDIR)\nsStyleCoord.obj \
.\$(OBJDIR)\nsStyleSet.obj \
.\$(OBJDIR)\nsTextFragment.obj \
.\$(OBJDIR)\nsXIFConverter.obj \
.\$(OBJDIR)\nsSelection.obj \
.\$(OBJDIR)\nsLayoutAtoms.obj \
.\$(OBJDIR)\nsLayoutDebugger.obj \
.\$(OBJDIR)\nsLayoutUtils.obj \
.\$(OBJDIR)\nsCaret.obj \
.\$(OBJDIR)\nsRange.obj \
.\$(OBJDIR)\nsTextContentChangeData.obj \
.\$(OBJDIR)\nsTextNode.obj \
.\$(OBJDIR)\nsLayoutHistoryState.obj \
$(NULL)
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \
-I$(PUBLIC)\dom -I$(PUBLIC)\js -I$(PUBLIC)\netlib \
-I$(PUBLIC)\pref -I..\..\html\base\src -I..\..\html\style\src \
-I..\..\xul\base\src \
-I$(PUBLIC)\lwbrk -I$(PUBLIC)\plugin
LCFLAGS = \
$(LCFLAGS) \
$(DEFINES) \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
rm -f $(PDBFILE).pdb

View File

@@ -0,0 +1,192 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* shaver@mozilla.org
*/
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsIAutoCopy.h"
#include "nsIDOMSelection.h"
#include "nsIDOMSelectionListener.h"
#include "nsWidgetsCID.h"
#include "nsIClipboard.h"
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsSupportsPrimitives.h"
class nsAutoCopyService : public nsIAutoCopyService , public nsIDOMSelectionListener
{
public:
NS_DECL_ISUPPORTS
nsAutoCopyService();
virtual ~nsAutoCopyService(){}//someday maybe we have it able to shutdown during run
//nsIAutoCopyService interfaces
NS_IMETHOD Listen(nsIDOMSelection *aDomSelection);
//end nsIAutoCopyService
//nsIDOMSelectionListener interfaces
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsIDOMSelection *aSel, short aReason);
//end nsIDOMSelectionListener
protected:
nsCOMPtr<nsIClipboard> mClipboard;
nsCOMPtr<nsIFormatConverter> mXIF;
nsCOMPtr<nsITransferable> mTransferable;
nsCOMPtr<nsIFormatConverter> mConverter;
};
// Implement our nsISupports methods
NS_IMPL_ISUPPORTS2(nsAutoCopyService, nsIAutoCopyService,nsIDOMSelectionListener)
nsresult
NS_NewAutoCopyService(nsIAutoCopyService** aResult)
{
*aResult = new nsAutoCopyService;
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
nsAutoCopyService::nsAutoCopyService()
{
NS_INIT_REFCNT();
}
NS_IMETHODIMP
nsAutoCopyService::Listen(nsIDOMSelection *aDomSelection)
{
return aDomSelection->AddSelectionListener(this);
}
/*
* What we do now:
* On every selection change, we copy to the clipboard anew, creating a
* XIF buffer, a transferable, a XIFFormatConverter, an nsISupportsWString and
* a huge mess every time. This is basically what nsPresShell::DoCopy does
* to move the selection into the clipboard for Edit->Copy.
*
* What we should do, to make our end of the deal faster:
* Create a singleton transferable with our own magic converter. When selection
* changes (use a quick cache to detect ``real'' changes), we put the new
* nsIDOMSelection in the transferable. Our magic converter will take care of
* transferable->XIF->whatever-other-format when the time comes to actually
* hand over the clipboard contents.
*
* Other issues:
* - which X clipboard should we populate?
* - should we use a different one than Edit->Copy, so that inadvertant
* selections (or simple clicks, which currently cause a selection
* notification, regardless of if they're in the document which currently has
* selection!) don't lose the contents of the ``application''? Or should we
* just put some intelligence in the ``is this a real selection?'' code to
* protect our selection against clicks in other documents that don't create
* selections?
* - maybe we should just never clear the X clipboard? That would make this
* problem just go away, which is very tempting.
*/
#define DRAGGING 1
NS_IMETHODIMP
nsAutoCopyService::NotifySelectionChanged(nsIDOMDocument *aDoc, nsIDOMSelection *aSel, short aReason)
{
nsresult rv;
if (!mClipboard) {
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
mClipboard = do_GetService(kCClipboardCID, &rv);
if (NS_FAILED(rv))
return rv;
}
if (!(aReason & nsIDOMSelectionListener::MOUSEUP_REASON))
return NS_OK;//dont care if we are still dragging. or if its not from a mouseup
PRBool collapsed;
if (!aDoc || !aSel || NS_FAILED(aSel->GetIsCollapsed(&collapsed)) || collapsed) {
#ifdef DEBUG_CLIPBOARD
fprintf(stderr, "CLIPBOARD: no selection/collapsed selection\n");
#endif
/* clear X clipboard? */
return NS_OK;
}
nsCOMPtr<nsIDocument> doc;
doc = do_QueryInterface(NS_REINTERPRET_CAST(nsISupports *,aDoc),&rv);
nsAutoString xifBuffer;
/* nsPresShell::DoCopy thinks that this is infalliable -- do you? */
if (NS_FAILED(doc->CreateXIF(xifBuffer, aSel)))
return NS_ERROR_FAILURE;
/* create a transferable */
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
nsCOMPtr<nsITransferable> trans;
rv = nsComponentManager::CreateInstance(kCTransferableCID, nsnull,
NS_GET_IID(nsITransferable),
(void **)getter_AddRefs(trans));
if (NS_FAILED(rv))
return rv;
if (!mXIF) {
static NS_DEFINE_CID(kCXIFConverterCID, NS_XIFFORMATCONVERTER_CID);
rv = nsComponentManager::CreateInstance(kCXIFConverterCID, nsnull,
NS_GET_IID(nsIFormatConverter),
(void **)getter_AddRefs(mXIF));
if (NS_FAILED(rv))
return rv;
}
trans->AddDataFlavor(kXIFMime);
trans->SetConverter(mXIF);
nsCOMPtr<nsISupportsWString> dataWrapper;
rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull,
NS_GET_IID(nsISupportsWString),
getter_AddRefs(dataWrapper));
if (NS_FAILED(rv))
return rv;
dataWrapper->SetData( NS_CONST_CAST(PRUnichar*,xifBuffer.GetUnicode()));
nsCOMPtr<nsISupports> generic(do_QueryInterface(dataWrapper));
/* Length() is in characters, *2 gives bytes. */
trans->SetTransferData(kXIFMime, generic, xifBuffer.Length() * 2);
mClipboard->SetData(trans, nsnull,nsIClipboard::kSelectionClipboard);
#ifdef DEBUG_CLIPBOARD
static char *reasons[] = {
"UNKNOWN", "NEW", "REMOVED", "ALTERED",
"BOGUS4", "BOGUS5", "BOGUS6", "BOGUS7", "BOGUS8"
};
nsAutoString str;
aSel->ToString(str);
char *selStr = str.ToNewCString();
fprintf(stderr, "SELECTION: %s, %p, %p [%s]\n", reasons[reason], doc, aSel,
selStr);
nsMemory::Free(selStr);
#endif
return NS_OK;
}

View File

@@ -0,0 +1,765 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsCOMPtr.h"
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include "nsIComponentManager.h"
#include "nsIFrameSelection.h"
#include "nsIFrame.h"
#include "nsIDOMNode.h"
#include "nsIDOMRange.h"
#include "nsIDOMSelection.h"
#include "nsIDOMCharacterData.h"
#include "nsIContent.h"
#include "nsIPresShell.h"
#include "nsIRenderingContext.h"
#include "nsIDeviceContext.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsIPresContext.h"
#include "nsILookAndFeel.h"
#include "nsWidgetsCID.h" // for NS_LOOKANDFEEL_CID
#include "nsBlockFrame.h"
#include "nsISelectionController.h"
#include "nsCaret.h"
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
//-----------------------------------------------------------------------------
nsCaret::nsCaret()
: mPresShell(nsnull)
, mBlinkRate(500)
, mCaretWidth(20)
, mVisible(PR_FALSE)
, mReadOnly(PR_TRUE)
, mDrawn(PR_FALSE)
, mLastCaretFrame(nsnull)
, mLastContentOffset(0)
{
NS_INIT_REFCNT();
}
//-----------------------------------------------------------------------------
nsCaret::~nsCaret()
{
KillTimer();
}
//-----------------------------------------------------------------------------
NS_IMETHODIMP nsCaret::Init(nsIPresShell *inPresShell)
{
if (!inPresShell)
return NS_ERROR_NULL_POINTER;
mPresShell = getter_AddRefs(NS_GetWeakReference(inPresShell)); // the presshell owns us, so no addref
nsILookAndFeel* touchyFeely;
if (NS_SUCCEEDED(nsComponentManager::CreateInstance(kLookAndFeelCID, nsnull, NS_GET_IID(nsILookAndFeel), (void**)&touchyFeely)))
{
PRInt32 tempInt;
if (NS_SUCCEEDED(touchyFeely->GetMetric(nsILookAndFeel::eMetric_CaretWidthTwips, tempInt)))
mCaretWidth = (nscoord)tempInt;
if (NS_SUCCEEDED(touchyFeely->GetMetric(nsILookAndFeel::eMetric_CaretBlinkTime, tempInt)))
mBlinkRate = (PRUint32)tempInt;
NS_RELEASE(touchyFeely);
}
// get the selection from the pres shell, and set ourselves up as a selection
// listener
nsCOMPtr<nsIDOMSelection> domSelection;
nsCOMPtr<nsISelectionController> selCon = do_QueryReferent(mPresShell);
if (selCon)
{
if (NS_SUCCEEDED(selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSelection))))
{
domSelection->AddSelectionListener(this);
mDomSelectionWeak = getter_AddRefs( NS_GetWeakReference(domSelection) );
}
}
else
return NS_ERROR_FAILURE;
// set up the blink timer
if (mVisible)
{
nsresult err = StartBlinking();
if (NS_FAILED(err))
return err;
}
return NS_OK;
}
//-----------------------------------------------------------------------------
NS_IMPL_ADDREF(nsCaret);
NS_IMPL_RELEASE(nsCaret);
//-----------------------------------------------------------------------------
NS_IMETHODIMP nsCaret::QueryInterface(const nsIID& aIID,
void** aInstancePtrResult)
{
NS_PRECONDITION(aInstancePtrResult, "null pointer");
if (!aInstancePtrResult)
return NS_ERROR_NULL_POINTER;
nsISupports* foundInterface;
if (aIID.Equals(NS_GET_IID(nsISupports)))
foundInterface = (nsISupports*)(nsICaret*)this; // whoo boy
else if (aIID.Equals(NS_GET_IID(nsICaret)))
foundInterface = (nsICaret*)this;
else if (aIID.Equals(NS_GET_IID(nsIDOMSelectionListener)))
foundInterface = (nsIDOMSelectionListener*)this;
else
foundInterface = nsnull;
nsresult status;
if (! foundInterface)
status = NS_NOINTERFACE;
else
{
NS_ADDREF(foundInterface);
status = NS_OK;
}
*aInstancePtrResult = foundInterface;
return status;
}
//-----------------------------------------------------------------------------
NS_IMETHODIMP nsCaret::SetCaretDOMSelection(nsIDOMSelection *aDOMSel)
{
NS_ENSURE_ARG_POINTER(aDOMSel);
mDomSelectionWeak = getter_AddRefs( NS_GetWeakReference(aDOMSel) ); // weak reference to pres shell
return NS_OK;
}
//-----------------------------------------------------------------------------
NS_IMETHODIMP nsCaret::SetCaretVisible(PRBool inMakeVisible)
{
mVisible = inMakeVisible;
nsresult err = NS_OK;
if (mVisible)
err = StartBlinking();
else
err = StopBlinking();
return err;
}
NS_IMETHODIMP nsCaret::GetCaretVisible(PRBool *outMakeVisible)
{
NS_ENSURE_ARG_POINTER(outMakeVisible);
*outMakeVisible = mVisible;
return NS_OK;
}
//-----------------------------------------------------------------------------
NS_IMETHODIMP nsCaret::SetCaretReadOnly(PRBool inMakeReadonly)
{
mReadOnly = inMakeReadonly;
return NS_OK;
}
//-----------------------------------------------------------------------------
NS_IMETHODIMP nsCaret::GetWindowRelativeCoordinates(nsRect& outCoordinates, PRBool& outIsCollapsed, nsIDOMSelection *aDOMSel)
{
if (!mPresShell)
return NS_ERROR_NOT_INITIALIZED;
mDomSelectionWeak = getter_AddRefs( NS_GetWeakReference(aDOMSel) ); // weak reference to pres shell
nsCOMPtr<nsIDOMSelection> domSelection = aDOMSel;
nsresult err;
if (!domSelection)
return NS_ERROR_NOT_INITIALIZED; // no selection
// fill in defaults for failure
outCoordinates.x = -1;
outCoordinates.y = -1;
outCoordinates.width = -1;
outCoordinates.height = -1;
outIsCollapsed = PR_FALSE;
err = domSelection->GetIsCollapsed(&outIsCollapsed);
if (NS_FAILED(err))
return err;
// code in progress
nsCOMPtr<nsIDOMNode> focusNode;
err = domSelection->GetFocusNode(getter_AddRefs(focusNode));
if (NS_FAILED(err))
return err;
if (!focusNode)
return NS_ERROR_FAILURE;
PRInt32 focusOffset;
err = domSelection->GetFocusOffset(&focusOffset);
if (NS_FAILED(err))
return err;
/*
// is this a text node?
nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(focusNode);
// note that we only work with text nodes here, unlike when drawing the caret.
// this is because this routine is intended for IME support, which only cares about text.
if (!nodeAsText)
return NS_ERROR_UNEXPECTED;
*/
nsCOMPtr<nsIContent>contentNode = do_QueryInterface(focusNode);
if (!contentNode)
return NS_ERROR_FAILURE;
//get frame selection and find out what frame to use...
nsCOMPtr<nsIFrameSelection> frameSelection;
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
if (presShell)
err = presShell->GetFrameSelection(getter_AddRefs(frameSelection));
else
return NS_ERROR_FAILURE;
if (NS_FAILED(err) || !frameSelection)
return err?err : NS_ERROR_FAILURE;
// find the frame that contains the content node that has focus
nsIFrame* theFrame = nsnull;
PRInt32 theFrameOffset = 0;
PRBool hintRight;
domSelection->GetHint(&hintRight);//translate hint.
nsIFrameSelection::HINT hint;
if (hintRight)
hint = nsIFrameSelection::HINTRIGHT;
else
hint = nsIFrameSelection::HINTLEFT;
err = frameSelection->GetFrameForNodeOffset(contentNode, focusOffset, hint, &theFrame, &theFrameOffset);
if (NS_FAILED(err) || !theFrame)
return err;
nsPoint viewOffset(0, 0);
nsIView *drawingView; // views are not refcounted
GetViewForRendering(theFrame, eTopLevelWindowCoordinates, viewOffset, drawingView);
if (!drawingView)
return NS_ERROR_UNEXPECTED;
// ramp up to make a rendering context for measuring text.
// First, we get the pres context ...
nsCOMPtr<nsIPresContext> presContext;
err = presShell->GetPresContext(getter_AddRefs(presContext));
if (NS_FAILED(err))
return err;
// ... then get a device context
nsCOMPtr<nsIDeviceContext> dx;
err = presContext->GetDeviceContext(getter_AddRefs(dx));
if (NS_FAILED(err))
return err;
if (!dx)
return NS_ERROR_UNEXPECTED;
// ... then tell it to make a rendering context
nsCOMPtr<nsIRenderingContext> rendContext;
err = dx->CreateRenderingContext(drawingView, *getter_AddRefs(rendContext));
if (NS_FAILED(err))
return err;
if (!rendContext)
return NS_ERROR_UNEXPECTED;
// now we can measure the offset into the frame.
nsPoint framePos(0, 0);
theFrame->GetPointFromOffset(presContext, rendContext, theFrameOffset, &framePos);
nsRect frameRect;
theFrame->GetRect(frameRect);
// now add the frame offset to the view offset, and we're done
viewOffset += framePos;
outCoordinates.x = viewOffset.x;
outCoordinates.y = viewOffset.y;
outCoordinates.height = frameRect.height;
outCoordinates.width = frameRect.width;
return NS_OK;
}
//-----------------------------------------------------------------------------
NS_IMETHODIMP nsCaret::ClearFrameRefs(nsIFrame* aFrame)
{
if (mLastCaretFrame == aFrame)
{
mLastCaretFrame = nsnull; // frames are not refcounted.
mLastContentOffset = 0;
}
mDrawn = PR_FALSE; // assume that the view has been cleared, and ensure
// that we don't try to use the frame.
// should we just call StopBlinking() here?
return NS_OK;
}
NS_IMETHODIMP nsCaret::EraseCaret()
{
if (mDrawn)
DrawCaret();
return NS_OK;
}
#ifdef XP_MAC
#pragma mark -
#endif
//-----------------------------------------------------------------------------
NS_IMETHODIMP nsCaret::NotifySelectionChanged(nsIDOMDocument *, nsIDOMSelection *aDomSel, short aReason)
{
if (aReason & nsIDOMSelectionListener::MOUSEUP_REASON)//this wont do
return NS_OK;
if (mVisible)
StopBlinking();
nsCOMPtr<nsIDOMSelection> domSel(do_QueryReferent(mDomSelectionWeak));
if (domSel.get() != aDomSel)
return NS_OK; //ignore this then.
if (mVisible)
StartBlinking();
return NS_OK;
}
#ifdef XP_MAC
#pragma mark -
#endif
//-----------------------------------------------------------------------------
void nsCaret::KillTimer()
{
if (mBlinkTimer)
{
mBlinkTimer->Cancel();
}
}
//-----------------------------------------------------------------------------
nsresult nsCaret::PrimeTimer()
{
KillTimer();
// set up the blink timer
if (!mReadOnly && mBlinkRate > 0)
{
nsresult err;
mBlinkTimer = do_CreateInstance("component://netscape/timer", &err);
if (NS_FAILED(err))
return err;
mBlinkTimer->Init(CaretBlinkCallback, this, mBlinkRate, NS_PRIORITY_HIGH, NS_TYPE_REPEATING_PRECISE);
}
return NS_OK;
}
//-----------------------------------------------------------------------------
nsresult nsCaret::StartBlinking()
{
PrimeTimer();
//NS_ASSERTION(!mDrawn, "Caret should not be drawn here");
DrawCaret(); // draw it right away
return NS_OK;
}
//-----------------------------------------------------------------------------
nsresult nsCaret::StopBlinking()
{
if (mDrawn) // erase the caret if necessary
DrawCaret();
KillTimer();
return NS_OK;
}
//-----------------------------------------------------------------------------
// Get the nsIFrame and the content offset for the current caret position.
// Returns PR_TRUE if we should go ahead and draw, PR_FALSE otherwise.
//
PRBool nsCaret::SetupDrawingFrameAndOffset()
{
if (!mDomSelectionWeak)
return PR_FALSE;
nsCOMPtr<nsIDOMSelection> domSelection = do_QueryReferent(mDomSelectionWeak);
PRBool isCollapsed;
if (domSelection && NS_SUCCEEDED(domSelection->GetIsCollapsed(&isCollapsed)) && isCollapsed)
{
// start and end parent should be the same since we are collapsed
nsCOMPtr<nsIDOMNode> focusNode;
PRInt32 contentOffset;
if (NS_SUCCEEDED(domSelection->GetFocusNode(getter_AddRefs(focusNode))) && focusNode &&
NS_SUCCEEDED(domSelection->GetFocusOffset(&contentOffset)))
{
nsCOMPtr<nsIContent>contentNode = do_QueryInterface(focusNode);
if (contentNode)
{
// see if we have an offset between child nodes, or an offset into a text
// node.
#if NOT_NEEDED
PRBool canContainChildren;
if (NS_SUCCEEDED(contentNode->CanContainChildren(canContainChildren)) && canContainChildren)
{
// point the caret to the start of the child node
nsCOMPtr<nsIContent> childNode;
contentNode->ChildAt(contentOffset, *getter_AddRefs(childNode));
if (childNode)
{
contentNode = childNode;
contentOffset = 0;
}
}
else
{
// are we in a text node?
//nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(focusNode);
// we can be in a text node, or a BR node here.
}
#endif // NOT_NEEDED
nsIFrame* theFrame = nsnull;
PRInt32 theFrameOffset = 0;
nsresult err;
//get frame selection and find out what frame to use...
nsCOMPtr<nsIFrameSelection> frameSelection;
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
if (presShell)
err = presShell->GetFrameSelection(getter_AddRefs(frameSelection));
else
return NS_ERROR_FAILURE;
if (NS_FAILED(err) || !frameSelection)
return PR_FALSE;
PRBool hintRight;
domSelection->GetHint(&hintRight);//translate hint.
nsIFrameSelection::HINT hint;
if (hintRight)
hint = nsIFrameSelection::HINTRIGHT;
else
hint = nsIFrameSelection::HINTLEFT;
err = frameSelection->GetFrameForNodeOffset(contentNode, contentOffset, hint, &theFrame, &theFrameOffset);
if (NS_FAILED(err))
return PR_FALSE;
else
{
// mark the frame, so we get notified on deletion.
// frames are never unmarked, which means that we'll touch every frame we visit.
// this is not ideal.
nsFrameState state;
theFrame->GetFrameState(&state);
state |= NS_FRAME_EXTERNAL_REFERENCE;
theFrame->SetFrameState(state);
mLastCaretFrame = theFrame;
mLastContentOffset = theFrameOffset;
return PR_TRUE;
}
}
}
}
return PR_FALSE;
}
//-----------------------------------------------------------------------------
void nsCaret::GetViewForRendering(nsIFrame *caretFrame, EViewCoordinates coordType, nsPoint &viewOffset, nsIView* &outView)
{
if (!caretFrame) return;
outView = nsnull;
NS_ASSERTION(caretFrame, "Should have a frame here");
if (!caretFrame)
return;
nsIView* theView = nsnull;
NS_ASSERTION(caretFrame, "Should have frame here");
nsCOMPtr<nsIPresContext> presContext;
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
if (presShell)
presShell->GetPresContext(getter_AddRefs(presContext));
else
return;
caretFrame->GetOffsetFromView(presContext, viewOffset, &theView);
if (theView == nsnull) return;
nsIView* returnView = nsnull;
nscoord x, y;
do {
theView->GetPosition(&x, &y);
if (!returnView)
{
nsCOMPtr<nsIWidget> viewWidget;
theView->GetWidget(*getter_AddRefs(viewWidget));
if (viewWidget)
{
returnView = theView;
if (coordType == eViewCoordinates)
break;
}
viewOffset.x += x;
viewOffset.y += y;
}
theView->GetParent(theView);
} while (theView);
outView = returnView;
}
/*-----------------------------------------------------------------------------
MustDrawCaret
FInd out if we need to do any caret drawing. This returns true if
either a) or b)
a) caret has been drawn, and we need to erase it.
b) caret is not drawn, and selection is collapsed
----------------------------------------------------------------------------- */
PRBool nsCaret::MustDrawCaret()
{
if (mDrawn)
return PR_TRUE;
nsCOMPtr<nsIDOMSelection> domSelection = do_QueryReferent(mDomSelectionWeak);
if (!domSelection)
return PR_FALSE;
PRBool isCollapsed;
if (NS_FAILED(domSelection->GetIsCollapsed(&isCollapsed)))
return PR_FALSE;
return isCollapsed;
}
/*-----------------------------------------------------------------------------
DrawCaretWithContext
By this point, the caret rect should have been set up.
----------------------------------------------------------------------------- */
void nsCaret::DrawCaretWithContext(nsIRenderingContext* inRendContext)
{
NS_ASSERTION(mLastCaretFrame != nsnull, "Should have a frame here");
nsRect frameRect;
mLastCaretFrame->GetRect(frameRect);
frameRect.x = 0; // the origin is accounted for in GetViewForRendering()
frameRect.y = 0;
if (frameRect.height == 0) // we're in a BR frame which has zero height.
{
frameRect.height = 200;
frameRect.y -= 200;
}
nsPoint viewOffset(0, 0);
nsIView *drawingView;
GetViewForRendering(mLastCaretFrame, eViewCoordinates, viewOffset, drawingView);
if (drawingView == nsnull)
return;
frameRect += viewOffset;
nsCOMPtr<nsIPresContext> presContext;
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
if (presShell)
{
if (NS_FAILED(presShell->GetPresContext(getter_AddRefs(presContext))))
return;
}
else
return;
// make a rendering context, if we didn't get passed one
nsCOMPtr<nsIRenderingContext> localRC = do_QueryInterface(inRendContext); // OK if inRendContext is null
if (!localRC)
{
nsCOMPtr<nsIDeviceContext> dx;
if (NS_FAILED(presContext->GetDeviceContext(getter_AddRefs(dx))) || !dx)
return;
if (NS_FAILED(dx->CreateRenderingContext(drawingView, *getter_AddRefs(localRC))) || !localRC)
return;
}
if (!mDrawn)
{
nsPoint framePos(0, 0);
nsRect caretRect = frameRect;
mLastCaretFrame->GetPointFromOffset(presContext, localRC, mLastContentOffset, &framePos);
caretRect += framePos;
//printf("Content offset %ld, frame offset %ld\n", focusOffset, framePos.x);
caretRect.width = mCaretWidth;
// Avoid view redraw problems by making sure the
// caret doesn't hang outside the right edge of
// the frame. This ensures that the caret gets
// erased properly if the frame's right edge gets
// invalidated.
nscoord cX = caretRect.x + caretRect.width;
nscoord fX = frameRect.x + frameRect.width;
if (caretRect.x <= fX && cX > fX)
{
caretRect.x -= cX - fX;
if (caretRect.x < frameRect.x)
caretRect.x = frameRect.x;
}
mCaretRect = caretRect;
}
/*
if (mReadOnly)
inRendContext.SetColor(NS_RGB(85, 85, 85)); // we are drawing it; gray
*/
localRC->SetColor(NS_RGB(255,255,255));
localRC->InvertRect(mCaretRect);
ToggleDrawnStatus();
}
//-----------------------------------------------------------------------------
void nsCaret::DrawCaret()
{
// do we need to draw the caret at all?
if (!MustDrawCaret())
return;
// if we are drawing, not erasing, then set up the frame etc.
if (!mDrawn)
{
if (! SetupDrawingFrameAndOffset())
return;
}
DrawCaretWithContext(nsnull);
}
//-----------------------------------------------------------------------------
void nsCaret::RefreshDrawCaret(nsIView *aView, nsIRenderingContext& inRendContext, const nsRect& aDirtyRect)
{
/*
if (! SetupDrawingFrameAndOffset())
return;
NS_ASSERTION(mLastCaretFrame != nsnull, "Should have a frame here");
nsPoint viewOffset(0, 0);
nsIView *drawingView;
//GetViewForRendering(viewOffset, drawingView);
mLastCaretFrame->GetOffsetFromView(viewOffset, &drawingView);
// are we in the view that is being painted?
if (drawingView == nsnull || drawingView != aView)
return;
mDrawn = PR_FALSE; // we're rendering to a view that is being redrawn
DrawCaretWithContext(inRendContext);
*/
}
#ifdef XP_MAC
#pragma mark -
#endif
//-----------------------------------------------------------------------------
/* static */
void nsCaret::CaretBlinkCallback(nsITimer *aTimer, void *aClosure)
{
nsCaret *theCaret = NS_REINTERPRET_CAST(nsCaret*, aClosure);
if (!theCaret) return;
theCaret->DrawCaret();
#ifndef REPEATING_TIMERS
theCaret->PrimeTimer();
#endif
}
//-----------------------------------------------------------------------------
nsresult NS_NewCaret(nsICaret** aInstancePtrResult)
{
NS_PRECONDITION(aInstancePtrResult, "null ptr");
nsCaret* caret = new nsCaret();
if (nsnull == caret)
return NS_ERROR_OUT_OF_MEMORY;
return caret->QueryInterface(NS_GET_IID(nsICaret), (void**) aInstancePtrResult);
}

View File

@@ -0,0 +1,110 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsCoord.h"
#include "nsIDOMSelectionListener.h"
#include "nsICaret.h"
#include "nsWeakPtr.h"
class nsITimer;
class nsIView;
class nsIRenderingContext;
class nsISelectionController;
// {E14B66F6-BFC5-11d2-B57E-00105AA83B2F}
#define NS_CARET_CID \
{ 0xe14b66f6, 0xbfc5, 0x11d2, { 0xb5, 0x7e, 0x0, 0x10, 0x5a, 0xa8, 0x3b, 0x2f } };
//-----------------------------------------------------------------------------
class nsCaret : public nsICaret,
public nsIDOMSelectionListener
{
public:
nsCaret();
virtual ~nsCaret();
NS_DECL_ISUPPORTS
public:
// nsICaret interface
NS_IMETHOD Init(nsIPresShell *inPresShell);
NS_IMETHOD SetCaretDOMSelection(nsIDOMSelection *inDOMSel);
NS_IMETHOD GetCaretVisible(PRBool *outMakeVisible);
NS_IMETHOD SetCaretVisible(PRBool intMakeVisible);
NS_IMETHOD SetCaretReadOnly(PRBool inMakeReadonly);
NS_IMETHOD GetWindowRelativeCoordinates(nsRect& outCoordinates, PRBool& outIsCollapsed, nsIDOMSelection *inDOMSel);
NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame);
NS_IMETHOD EraseCaret();
//nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsIDOMSelection *aSel, short aReason);
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
protected:
void KillTimer();
nsresult PrimeTimer();
nsresult StartBlinking();
nsresult StopBlinking();
enum EViewCoordinates {
eTopLevelWindowCoordinates,
eViewCoordinates
};
void GetViewForRendering(nsIFrame *caretFrame, EViewCoordinates coordType, nsPoint &viewOffset, nsIView* &outView);
PRBool SetupDrawingFrameAndOffset();
PRBool MustDrawCaret();
void RefreshDrawCaret(nsIView *aView, nsIRenderingContext& inRendContext, const nsRect& aDirtyRect);
void DrawCaretWithContext(nsIRenderingContext* inRendContext);
void DrawCaret();
void ToggleDrawnStatus() { mDrawn = !mDrawn; }
nsCOMPtr<nsIWeakReference> mPresShell;
nsCOMPtr<nsITimer> mBlinkTimer;
PRUint32 mBlinkRate; // time for one cyle (off then on), in milliseconds
nscoord mCaretWidth; // caret width in twips
PRBool mVisible; // is the caret blinking
PRBool mReadOnly; // it the caret in readonly state (draws differently)
private:
PRBool mDrawn; // this should be mutable
nsRect mCaretRect; // the last caret rect
nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.
PRInt32 mLastContentOffset;
nsWeakPtr mDomSelectionWeak;
};

View File

@@ -0,0 +1,549 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIDOMComment.h"
#include "nsGenericDOMDataNode.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIContent.h"
#include "nsFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIDOMSelection.h"
#include "nsIXIFConverter.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);
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
class nsCommentNode : public nsIDOMComment,
public nsIScriptObjectOwner,
public nsITextContent
{
public:
nsCommentNode();
virtual ~nsCommentNode();
// nsISupports
NS_DECL_ISUPPORTS
// nsIDOMNode
NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(mInner)
// nsIDOMCharacterData
NS_IMPL_IDOMCHARACTERDATA_USING_GENERIC_DOM_DATA(mInner)
// nsIDOMComment
// nsIScriptObjectOwner
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(mInner)
// nsIContent
//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, PRBool aCompileEventHandlers) {
return mInner.SetDocument(aDocument, aDeep, aCompileEventHandlers);
}
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 GetNodeInfo(nsINodeInfo*& aResult) const {
aResult = nsnull; return NS_OK;
}
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 GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute,
nsIAtom*& aPrefix, nsString &aResult) const {
return mInner.GetAttribute(aNameSpaceID, aAttribute, aPrefix, aResult);
}
NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
const nsString& aValue, PRBool aNotify) {
return mInner.SetAttribute(aNameSpaceID, aAttribute, aValue, aNotify);
}
NS_IMETHOD SetAttribute(nsINodeInfo* aNodeInfo,
const nsString& aValue, PRBool aNotify) {
return mInner.SetAttribute(aNodeInfo, 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,
nsIAtom*& aPrefix) const {
return mInner.GetAttributeNameAt(aIndex, aNameSpaceID, aName, aPrefix);
}
NS_IMETHOD GetAttributeCount(PRInt32& aResult) const {
return mInner.GetAttributeCount(aResult);
}
NS_IMETHOD List(FILE* out, PRInt32 aIndent) const;
NS_IMETHOD DumpContent(FILE* out = stdout, PRInt32 aIndent = 0,PRBool aDumpAll=PR_TRUE) const {
return NS_OK;
}
NS_IMETHOD BeginConvertToXIF(nsIXIFConverter* aConverter) const {
return mInner.BeginConvertToXIF(aConverter);
}
NS_IMETHOD ConvertContentToXIF(nsIXIFConverter* aConverter) const;
NS_IMETHOD FinishConvertToXIF(nsIXIFConverter* aConverter) const {
return mInner.FinishConvertToXIF(aConverter);
}
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
NS_IMETHOD GetContentID(PRUint32* aID) {
*aID = mContentID;
return NS_OK;
}
NS_IMETHOD SetContentID(PRUint32 aID) {
mContentID = aID;
return NS_OK;
}
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);
}
NS_IMETHOD SetFocus(nsIPresContext* aContext) {
return mInner.SetFocus(aContext);
}
NS_IMETHOD RemoveFocus(nsIPresContext* aContext) {
return mInner.RemoveFocus(aContext);
}
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const {
if (!aResult) {
return NS_ERROR_NULL_POINTER;
}
#ifdef DEBUG
*aResult = sizeof(*this);
#else
*aResult = 0;
#endif
return NS_OK;
}
NS_IMETHOD GetText(const nsTextFragment** aFragmentsResult)
{ return mInner.GetText(aFragmentsResult); }
NS_IMETHOD GetTextLength(PRInt32* aLengthResult) {
return mInner.GetTextLength(aLengthResult);
}
NS_IMETHOD CopyText(nsString& aResult) {
return mInner.CopyText(aResult);
}
NS_IMETHOD SetText(const PRUnichar* aBuffer,
PRInt32 aLength,
PRBool aNotify);
NS_IMETHOD SetText(const char* aBuffer,
PRInt32 aLength,
PRBool aNotify);
NS_IMETHOD IsOnlyWhitespace(PRBool* aResult)
{ return mInner.IsOnlyWhitespace(aResult); }
NS_IMETHOD CloneContent(PRBool aCloneText, nsITextContent** aClone);
protected:
nsGenericDOMDataNode mInner;
PRUint32 mContentID;
};
nsresult
NS_NewCommentNode(nsIContent** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIContent* it = new nsCommentNode();
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIContentIID, (void **) aInstancePtrResult);
}
nsCommentNode::nsCommentNode()
{
NS_INIT_REFCNT();
mContentID = 0;
}
nsCommentNode::~nsCommentNode()
{
}
NS_IMPL_ADDREF(nsCommentNode)
NS_IMPL_RELEASE(nsCommentNode)
NS_IMETHODIMP
nsCommentNode::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_DOM_DATA_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMCommentIID)) {
nsIDOMComment* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kITextContentIID)) {
nsITextContent* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsCommentNode::GetTag(nsIAtom*& aResult) const
{
aResult = nsLayoutAtoms::commentTagName;
NS_ADDREF(aResult);
return NS_OK;
}
NS_IMETHODIMP
nsCommentNode::GetNodeName(nsString& aNodeName)
{
aNodeName.AssignWithConversion("#comment");
return NS_OK;
}
NS_IMETHODIMP
nsCommentNode::GetNodeType(PRUint16* aNodeType)
{
*aNodeType = (PRUint16)nsIDOMNode::COMMENT_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsCommentNode::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsresult result = NS_OK;
nsCommentNode* it = new nsCommentNode();
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
// XXX Increment the ref count before calling any
// methods. If they do a QI and then a Release()
// the instance will be deleted.
result = it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
if (NS_FAILED(result)) {
return result;
}
nsAutoString data;
result = GetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
result = it->SetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
return result;
}
NS_IMETHODIMP
nsCommentNode::CloneContent(PRBool aCloneText, nsITextContent** aReturn)
{
nsresult result = NS_OK;
nsCommentNode* it;
NS_NEWXPCOM(it, nsCommentNode);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
result = it->QueryInterface(kITextContentIID, (void**) aReturn);
if (NS_FAILED(result) || !aCloneText) {
return result;
}
nsAutoString data;
result = GetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
result = it->SetData(data);
if (NS_FAILED(result)) {
NS_RELEASE(*aReturn);
return result;
}
return result;
}
NS_IMETHODIMP
nsCommentNode::List(FILE* out, PRInt32 aIndent) const
{
NS_PRECONDITION(nsnull != mInner.mDocument, "bad content");
PRInt32 indx;
for (indx = aIndent; --indx >= 0; ) fputs(" ", out);
fprintf(out, "Comment@%p refcount=%d<!--", this, mRefCnt);
nsAutoString tmp;
mInner.ToCString(tmp, 0, mInner.mText.GetLength());
fputs(tmp, out);
fputs("-->\n", out);
return NS_OK;
}
NS_IMETHODIMP
nsCommentNode::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
nsresult NS_NewCommentFrame(nsIPresShell* aPresShell, nsIFrame*& aResult);
nsresult
NS_NewCommentFrame(nsIPresShell* aPresShell, nsIFrame*& aResult)
{
nsIFrame* frame;
NS_NewEmptyFrame(aPresShell, &frame);
if (nsnull == frame) {
return NS_ERROR_OUT_OF_MEMORY;
}
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(nsIXIFConverter* aConverter) const
{
const nsIContent* content = this;
nsCOMPtr<nsIDOMSelection> sel;
aConverter->GetSelection(getter_AddRefs(sel));
nsIDocument* document;
nsresult res;
res = GetDocument(document);
if (!NS_SUCCEEDED(res))
return res;
const nsTextFragment* textFrag;
// XXX This method is const, but GetText() isn't,
// XXX so cast away the constness of mInner:
nsGenericDOMDataNode* inner = (nsGenericDOMDataNode*)&mInner;
res = inner->GetText(&textFrag);
if (!NS_SUCCEEDED(res))
return res;
if (sel != nsnull && document->IsInSelection(sel,content))
{
nsIEnumerator *enumerator;
if (NS_SUCCEEDED(sel->GetEnumerator(&enumerator))) {
for (enumerator->First();NS_OK != enumerator->IsDone(); enumerator->Next()) {
nsIDOMRange* range = nsnull;
if (NS_SUCCEEDED(enumerator->CurrentItem((nsISupports**)&range))) {
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode;
PRInt32 startOffset = 0;
PRInt32 endOffset = 0;
range->GetStartParent(getter_AddRefs(startNode));
range->GetEndParent(getter_AddRefs(endNode));
range->GetStartOffset(&startOffset);
range->GetEndOffset(&endOffset);
nsCOMPtr<nsIContent> startContent;
nsCOMPtr<nsIContent> 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->AddContentComment(buffer);
}
}
}
}
else
{
nsString buffer;
textFrag->AppendTo(buffer);
aConverter->AddContentComment(buffer);
}
NS_IF_RELEASE(document);
// XXX Possible mem leak: Do we need to delete textFrag?
return NS_OK;
}
#if 0
nsresult
nsCommentNode::BeginConvertToXIF(nsIXIFConverter* aConverter) const
{
return NS_OK;
}
nsresult
nsCommentNode::FinishConvertToXIF(nsIXIFConverter* aConverter) const
{
return NS_OK;
}
#endif
// This would ideally be done by the parser, but for the sake
// of "genericity" it's being done in the comment content code
static void
StripCommentDelimiters(nsString& aCommentString)
{
PRInt32 offset;
static char* kCommentStart = "<!";
static char* kCommentEnd = "->";
static char* kCommentAlternateEnd = "--!>";
static char kMinus = '-';
offset = aCommentString.Find(kCommentStart);
if (-1 != offset) {
// Take up to 2 '-' characters
offset += strlen(kCommentStart);
if (kMinus == aCommentString.CharAt(offset)) {
offset++;
if (kMinus == aCommentString.CharAt(offset)) {
offset++;
}
}
aCommentString.Cut(0, offset);
}
offset = aCommentString.RFind(kCommentEnd);
if (-1 != offset) {
// Take up to 1 more '-'
if (kMinus == aCommentString.CharAt(offset-1)) {
offset--;
}
aCommentString.Cut(offset, aCommentString.Length()-offset);
}
else {
offset = aCommentString.RFind(kCommentAlternateEnd);
if (-1 != offset) {
aCommentString.Cut(offset, aCommentString.Length()-offset);
}
}
}
NS_IMETHODIMP
nsCommentNode::SetText(const PRUnichar* aBuffer,
PRInt32 aLength,
PRBool aNotify)
{
nsAutoString str(aBuffer);
StripCommentDelimiters(str);
return mInner.SetText(this, str.GetUnicode(), str.Length(), aNotify);
}
NS_IMETHODIMP
nsCommentNode::SetText(const char* aBuffer,
PRInt32 aLength,
PRBool aNotify)
{
nsAutoString str; str.AssignWithConversion(aBuffer);
StripCommentDelimiters(str);
return mInner.SetText(this, str.GetUnicode(), str.Length(), aNotify);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,566 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsContentList.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDocument.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsGenericElement.h"
#include "nsLayoutAtoms.h"
#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms
nsContentList::nsContentList(nsIDocument *aDocument)
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
mFunc = nsnull;
mMatchAtom = nsnull;
mDocument = aDocument;
mData = nsnull;
mMatchAll = PR_FALSE;
mRootContent = nsnull;
}
nsContentList::nsContentList(nsIDocument *aDocument,
nsIAtom* aMatchAtom,
PRInt32 aMatchNameSpaceId,
nsIContent* aRootContent)
{
mMatchAtom = aMatchAtom;
NS_IF_ADDREF(mMatchAtom);
if (nsLayoutAtoms::wildcard == mMatchAtom) {
mMatchAll = PR_TRUE;
}
else {
mMatchAll = PR_FALSE;
}
mMatchNameSpaceId = aMatchNameSpaceId;
mFunc = nsnull;
mData = nsnull;
mRootContent = aRootContent;
Init(aDocument);
}
nsContentList::nsContentList(nsIDocument *aDocument,
nsContentListMatchFunc aFunc,
const nsString* aData,
nsIContent* aRootContent)
{
mFunc = aFunc;
if (nsnull != aData) {
mData = new nsString(*aData);
// If this fails, fail silently
}
else {
mData = nsnull;
}
mMatchAtom = nsnull;
mRootContent = aRootContent;
mMatchAll = PR_FALSE;
Init(aDocument);
}
void nsContentList::Init(nsIDocument *aDocument)
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
// We don't reference count the reference to the document
// If the document goes away first, we'll be informed and we
// can drop our reference.
// If we go away first, we'll get rid of ourselves from the
// document's observer list.
mDocument = aDocument;
if (nsnull != mDocument) {
mDocument->AddObserver(this);
}
PopulateSelf();
}
nsContentList::~nsContentList()
{
if (nsnull != mDocument) {
mDocument->RemoveObserver(this);
}
NS_IF_RELEASE(mMatchAtom);
if (nsnull != mData) {
delete mData;
}
}
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
nsresult nsContentList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (nsnull == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIDOMNodeListIID)) {
*aInstancePtr = (void*)(nsIDOMNodeList*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMHTMLCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLCollection*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMNodeList*)this;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsContentList)
NS_IMPL_RELEASE(nsContentList)
NS_IMETHODIMP
nsContentList::GetLength(PRUint32* aLength)
{
nsresult result = CheckDocumentExistence();
if (NS_OK == result) {
*aLength = mContent.Count();
}
return result;
}
NS_IMETHODIMP
nsContentList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
nsresult result = CheckDocumentExistence();
if (NS_OK == result) {
if (nsnull != mDocument) {
mDocument->FlushPendingNotifications(); // Flush pending content changes Bug 4891
}
nsISupports *element = (nsISupports *)mContent.ElementAt(aIndex);
if (nsnull != element) {
result = element->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
else {
*aReturn = nsnull;
}
}
return result;
}
NS_IMETHODIMP
nsContentList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
nsresult result = CheckDocumentExistence();
if (NS_OK == result) {
if (nsnull != mDocument) {
mDocument->FlushPendingNotifications(); // Flush pending content changes Bug 4891
}
PRInt32 i, count = mContent.Count();
for (i = 0; i < count; i++) {
nsIContent *content = (nsIContent *)mContent.ElementAt(i);
if (nsnull != content) {
nsAutoString name;
// XXX Should it be an EqualsIgnoreCase?
if (((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::name, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name))) ||
((content->GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::id, name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name)))) {
return content->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
}
}
}
*aReturn = nsnull;
return result;
}
NS_IMETHODIMP
nsContentList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = nsGenericElement::GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptHTMLCollection(aContext,
(nsISupports*)(nsIDOMHTMLCollection*)this,
global,
(void**)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
NS_RELEASE(global);
return res;
}
NS_IMETHODIMP
nsContentList::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
NS_IMETHODIMP
nsContentList::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
PRInt32 i, count;
aContainer->ChildCount(count);
if ((count > 0) && IsDescendantOfRoot(aContainer)) {
PRBool repopulate = PR_FALSE;
for (i = aNewIndexInContainer; i <= count-1; i++) {
nsIContent *content;
aContainer->ChildAt(i, content);
if (mMatchAll || MatchSelf(content)) {
repopulate = PR_TRUE;
}
NS_RELEASE(content);
}
if (repopulate) {
PopulateSelf();
}
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
if (IsDescendantOfRoot(aContainer)) {
if (mMatchAll || MatchSelf(aChild)) {
PopulateSelf();
}
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
if (IsDescendantOfRoot(aContainer)) {
if (mMatchAll || MatchSelf(aOldChild) || MatchSelf(aNewChild)) {
PopulateSelf();
}
}
else if (ContainsRoot(aOldChild)) {
DisconnectFromDocument();
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
if (IsDescendantOfRoot(aContainer) && MatchSelf(aChild)) {
PopulateSelf();
}
else if (ContainsRoot(aChild)) {
DisconnectFromDocument();
}
return NS_OK;
}
NS_IMETHODIMP
nsContentList::DocumentWillBeDestroyed(nsIDocument *aDocument)
{
if (nsnull != mDocument) {
aDocument->RemoveObserver(this);
mDocument = nsnull;
}
Reset();
return NS_OK;
}
// Returns whether the content element matches the
// criterion
nsresult
nsContentList::Match(nsIContent *aContent, PRBool *aMatch)
{
*aMatch = PR_FALSE;
if (!aContent) {
return NS_OK;
}
if (mMatchAtom) {
nsCOMPtr<nsINodeInfo> ni;
aContent->GetNodeInfo(*getter_AddRefs(ni));
if (!ni)
return NS_OK;
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aContent));
if (!node)
return NS_OK;
PRUint16 type;
node->GetNodeType(&type);
if (type != nsIDOMNode::ELEMENT_NODE)
return NS_OK;
if (mMatchNameSpaceId == kNameSpaceID_Unknown) {
if (mMatchAll || ni->Equals(mMatchAtom)) {
*aMatch = PR_TRUE;
}
} else if ((mMatchAll && ni->NamespaceEquals(mMatchNameSpaceId)) ||
ni->Equals(mMatchAtom, mMatchNameSpaceId)) {
*aMatch = PR_TRUE;
}
}
else if (nsnull != mFunc) {
*aMatch = (*mFunc)(aContent, mData);
}
return NS_OK;
}
nsresult
nsContentList::Add(nsIContent *aContent)
{
// Shouldn't hold a reference since we'll be
// told when the content leaves the document or
// the document will be destroyed.
mContent.AppendElement(aContent);
return NS_OK;
}
nsresult
nsContentList::Remove(nsIContent *aContent)
{
mContent.RemoveElement(aContent);
return NS_OK;
}
nsresult
nsContentList::IndexOf(nsIContent *aContent, PRInt32& aIndex)
{
aIndex = mContent.IndexOf(aContent);
return NS_OK;
}
nsresult
nsContentList::Reset()
{
mContent.Clear();
return NS_OK;
}
// If we were created outside the context of a document and we
// have root content, then check if our content has been added
// to a document yet. If so, we'll become an observer of the document.
nsresult
nsContentList::CheckDocumentExistence()
{
nsresult result = NS_OK;
if ((nsnull == mDocument) && (nsnull != mRootContent)) {
result = mRootContent->GetDocument(mDocument);
if (nsnull != mDocument) {
mDocument->AddObserver(this);
PopulateSelf();
}
}
return result;
}
// Match recursively. See if anything in the subtree
// matches the criterion.
PRBool
nsContentList::MatchSelf(nsIContent *aContent)
{
PRBool match;
PRInt32 i, count;
Match(aContent, &match);
if (match) {
return PR_TRUE;
}
aContent->ChildCount(count);
for (i = 0; i < count; i++) {
nsIContent *child;
aContent->ChildAt(i, child);
if (MatchSelf(child)) {
NS_RELEASE(child);
return PR_TRUE;
}
NS_RELEASE(child);
}
return PR_FALSE;
}
// Add all elements in this subtree that match to
// our list.
void
nsContentList::PopulateWith(nsIContent *aContent, PRBool aIncludeRoot)
{
PRBool match;
PRInt32 i, count;
if (aIncludeRoot) {
Match(aContent, &match);
if (match) {
Add(aContent);
}
}
aContent->ChildCount(count);
for (i = 0; i < count; i++) {
nsIContent *child;
aContent->ChildAt(i, child);
PopulateWith(child, PR_TRUE);
NS_RELEASE(child);
}
}
// Clear out our old list and build up a new one
void
nsContentList::PopulateSelf()
{
Reset();
if (nsnull != mRootContent) {
PopulateWith(mRootContent, PR_FALSE);
}
else if (nsnull != mDocument) {
nsIContent *root;
root = mDocument->GetRootContent();
PopulateWith(root, PR_TRUE);
NS_RELEASE(root);
}
}
// Is the specified element a descendant of the root? If there
// is no root, then yes. Otherwise keep tracing up the tree from
// the element till we find our root, or until we reach the
// document root.
PRBool
nsContentList::IsDescendantOfRoot(nsIContent* aContainer)
{
if (nsnull == mRootContent) {
return PR_TRUE;
}
else if (mRootContent == aContainer) {
return PR_TRUE;
}
else if (nsnull == aContainer) {
return PR_FALSE;
}
else {
nsIContent* parent;
PRBool ret;
aContainer->GetParent(parent);
ret = IsDescendantOfRoot(parent);
NS_IF_RELEASE(parent);
return ret;
}
}
// Does this subtree contain the root?
PRBool
nsContentList::ContainsRoot(nsIContent* aContent)
{
if (nsnull == mRootContent) {
return PR_FALSE;
}
else if (mRootContent == aContent) {
return PR_TRUE;
}
else {
PRInt32 i, count;
aContent->ChildCount(count);
for (i = 0; i < count; i++) {
nsIContent *child;
aContent->ChildAt(i, child);
if (ContainsRoot(child)) {
NS_RELEASE(child);
return PR_TRUE;
}
NS_RELEASE(child);
}
return PR_FALSE;
}
}
// Our root content has been disconnected from the
// document, so stop observing. The list then becomes
// a snapshot rather than a dynamic list.
void
nsContentList::DisconnectFromDocument()
{
if (nsnull != mDocument) {
mDocument->RemoveObserver(this);
mDocument = nsnull;
}
}

View File

@@ -0,0 +1,148 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsContentList_h___
#define nsContentList_h___
#include "nsISupports.h"
#include "nsVoidArray.h"
#include "nsString.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMNodeList.h"
#include "nsIDocumentObserver.h"
#include "nsIScriptObjectOwner.h"
typedef PRBool (*nsContentListMatchFunc)(nsIContent* aContent, nsString* aData);
class nsIDocument;
class nsContentList : public nsIDOMNodeList,
public nsIDOMHTMLCollection,
public nsIScriptObjectOwner,
public nsIDocumentObserver {
public:
nsContentList(nsIDocument *aDocument);
nsContentList(nsIDocument *aDocument,
nsIAtom* aMatchAtom,
PRInt32 aMatchNameSpaceId,
nsIContent* aRootContent=nsnull);
nsContentList(nsIDocument *aDocument,
nsContentListMatchFunc aFunc,
const nsString* aData,
nsIContent* aRootContent=nsnull);
virtual ~nsContentList();
NS_DECL_ISUPPORTS
// nsIDOMHTMLCollection
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
NS_IMETHOD NamedItem(const nsString& aName, nsIDOMNode** aReturn);
// nsIScriptObjectOwner
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIDocumentObserver
NS_IMETHOD BeginUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndUpdate(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD EndLoad(nsIDocument *aDocument) { return NS_OK; }
NS_IMETHOD BeginReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD EndReflow(nsIDocument *aDocument,
nsIPresShell* aShell) { return NS_OK; }
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent) { return NS_OK; }
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent1,
nsIContent* aContent2) { return NS_OK; }
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint) { return NS_OK; }
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet) { return NS_OK; }
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
PRBool aDisabled) { return NS_OK; }
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint) { return NS_OK; }
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule) { return NS_OK; }
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
nsresult Add(nsIContent *aContent);
nsresult Remove(nsIContent *aContent);
nsresult IndexOf(nsIContent *aContent, PRInt32& aIndex);
protected:
nsresult Match(nsIContent *aContent, PRBool *aMatch);
nsresult Reset();
void Init(nsIDocument *aDocument);
void PopulateWith(nsIContent *aContent, PRBool aIncludeRoot);
PRBool MatchSelf(nsIContent *aContent);
void PopulateSelf();
void DisconnectFromDocument();
PRBool IsDescendantOfRoot(nsIContent* aContainer);
PRBool ContainsRoot(nsIContent* aContent);
nsresult CheckDocumentExistence();
nsIAtom* mMatchAtom;
PRInt32 mMatchNameSpaceId;
nsContentListMatchFunc mFunc;
nsString* mData;
nsVoidArray mContent;
void *mScriptObject;
nsIDocument* mDocument;
nsIContent* mRootContent;
PRBool mMatchAll;
};
#endif // nsContentList_h___

View File

@@ -0,0 +1,176 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla code.
*
* The Initial Developer of the Original Code is Zero-Knowledge Systems,
* Inc. Portions created by Zero-Knowledge are Copyright (C) 2000
* Zero-Knowledge Systems, Inc. All Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.h"
#include "nsISupportsPrimitives.h"
#include "nsXPIDLString.h"
#include "nsContentPolicyUtils.h"
#include "nsContentPolicy.h"
#include "nsICategoryManager.h"
NS_IMPL_ISUPPORTS1(nsContentPolicy, nsIContentPolicy)
nsresult
NS_NewContentPolicy(nsIContentPolicy **aResult)
{
*aResult = new nsContentPolicy;
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
/*
* This constructor does far too much. I wish there was a way to get
* an Init method called by the service manager after the factory
* returned the new object, so that errors could be propagated back to
* the caller correctly.
*/
nsContentPolicy::nsContentPolicy()
{
NS_INIT_REFCNT();
nsresult rv;
NS_WITH_SERVICE(nsICategoryManager, catman, NS_CATEGORYMANAGER_PROGID, &rv);
if (NS_FAILED(rv))
/* log an error? */
return;
/*
* I'd like to use GetCategoryContents, so that I can size the array
* correctly on the first go and avoid the enumerator overhead, but it's
* not yet implemented (see nsCategoryManager.cpp). No biggie, I guess.
*/
nsCOMPtr<nsISimpleEnumerator> catEnum;
if (NS_FAILED(catman->EnumerateCategory(NS_CONTENTPOLICY_CATEGORY,
getter_AddRefs(catEnum)))) {
/* no category, no problem */
return;
}
PRBool hasMore;
if (NS_FAILED(catEnum->HasMoreElements(&hasMore)) || !hasMore ||
NS_FAILED(NS_NewISupportsArray(getter_AddRefs(mPolicies)))) {
return;
}
/*
* Populate mPolicies with policy services named by progids in the
* "content-policy" category.
*/
nsCOMPtr<nsISupports> item;
while (NS_SUCCEEDED(catEnum->GetNext(getter_AddRefs(item)))) {
nsCOMPtr<nsISupportsString> string = do_QueryInterface(item, &rv);
if (NS_FAILED(rv))
continue;
nsXPIDLCString progid;
if (NS_FAILED(string->GetData(getter_Copies(progid))))
continue;
#ifdef DEBUG_shaver
fprintf(stderr, "POLICY: loading %s\n", (const char *)progid);
#endif
/*
* Create this policy service and add to mPolicies.
*
* Should we try to parse as a CID, in case the component prefers to be
* registered that way?
*/
nsCOMPtr<nsISupports> policy = do_GetService(progid, &rv);
if (NS_SUCCEEDED(rv))
mPolicies->AppendElement(policy);
}
}
nsContentPolicy::~nsContentPolicy()
{
}
#define POLICY_LOAD 0
#define POLICY_PROCESS 1
NS_IMETHODIMP
nsContentPolicy::CheckPolicy(PRInt32 policyType, PRInt32 contentType,
nsIDOMElement *element,
const PRUnichar *contentLocation,
PRBool *shouldProceed)
{
*shouldProceed = PR_TRUE;
if (!mPolicies)
return NS_OK;
/*
* Enumerate mPolicies and ask each of them, taking the logical AND of
* their permissions.
*/
nsresult rv;
nsCOMPtr<nsIContentPolicy> policy;
PRUint32 count;
if (NS_FAILED(rv = mPolicies->Count(&count)))
return NS_OK;
for (PRUint32 i = 0; i < count; i++) {
rv = mPolicies->QueryElementAt(i, NS_GET_IID(nsIContentPolicy),
getter_AddRefs(policy));
if (NS_FAILED(rv))
continue;
/* check the appropriate policy */
if (policyType == POLICY_LOAD)
rv = policy->ShouldLoad(contentType, element, contentLocation,
shouldProceed);
else
rv = policy->ShouldProcess(contentType, element, contentLocation,
shouldProceed);
if (NS_SUCCEEDED(rv) && !*shouldProceed)
/* policy says no, no point continuing to check */
return NS_OK;
}
/*
* One of the policy objects might be misbehaving and setting shouldProceed
* to PR_FALSE before returning an error, so force it back to PR_TRUE
* here.
*/
*shouldProceed = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsContentPolicy::ShouldLoad(PRInt32 contentType, nsIDOMElement *element,
const PRUnichar *contentLocation,
PRBool *shouldLoad)
{
return CheckPolicy(POLICY_LOAD, contentType, element, contentLocation,
shouldLoad);
}
NS_IMETHODIMP
nsContentPolicy::ShouldProcess(PRInt32 contentType, nsIDOMElement *element,
const PRUnichar *contentLocation,
PRBool *shouldProcess)
{
return CheckPolicy(POLICY_PROCESS, contentType, element, contentLocation,
shouldProcess);
}

View File

@@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla code.
*
* The Initial Developer of the Original Code is Zero-Knowledge Systems,
* Inc. Portions created by Zero-Knowledge are Copyright (C) 2000
* Zero-Knowledge Systems, Inc. All Rights Reserved.
*
* Contributor(s):
*/
#include "nsIContentPolicy.h"
#include "nsISupportsArray.h"
#ifndef __nsContentPolicy_h__
#define __nsContentPolicy_h__
class nsContentPolicy : public nsIContentPolicy
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICONTENTPOLICY
nsContentPolicy();
virtual ~nsContentPolicy();
private:
nsCOMPtr<nsISupportsArray> mPolicies;
NS_IMETHOD CheckPolicy(PRInt32 policyType, PRInt32 contentType,
nsIDOMElement *element,
const PRUnichar *contentLocation,
PRBool *shouldProceed);
};
nsresult
NS_NewContentPolicy(nsIContentPolicy **aResult);
#endif /* __nsContentPolicy_h__ */

View File

@@ -0,0 +1,568 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsDOMAttribute.h"
#include "nsGenericElement.h"
#include "nsIContent.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsITextContent.h"
#include "nsINameSpaceManager.h"
static NS_DEFINE_IID(kIDOMAttrIID, NS_IDOMATTR_IID);
static NS_DEFINE_IID(kIDOMAttributePrivateIID, NS_IDOMATTRIBUTEPRIVATE_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
//----------------------------------------------------------------------
nsDOMAttribute::nsDOMAttribute(nsIContent* aContent,
nsINodeInfo *aNodeInfo,
const nsString& aValue)
: mNodeInfo(aNodeInfo), mValue(aValue)
{
NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!");
NS_INIT_REFCNT();
// We don't add a reference to our content. It will tell us
// to drop our reference when it goes away.
mContent = aContent;
mScriptObject = nsnull;
mChild = nsnull;
mChildList = nsnull;
}
nsDOMAttribute::~nsDOMAttribute()
{
NS_IF_RELEASE(mChild);
NS_IF_RELEASE(mChildList);
}
nsresult
nsDOMAttribute::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIDOMAttrIID)) {
nsIDOMAttr* tmp = this;
*aInstancePtr = (void*)tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
nsIScriptObjectOwner* tmp = this;
*aInstancePtr = (void*)tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMAttributePrivateIID)) {
nsIDOMAttributePrivate* tmp = this;
*aInstancePtr = (void*)tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMNodeIID)) {
nsIDOMNode* tmp = this;
*aInstancePtr = (void*)tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
nsIDOMAttr* tmp1 = this;
nsISupports* tmp2 = tmp1;
*aInstancePtr = (void*)tmp2;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsDOMAttribute)
NS_IMPL_RELEASE(nsDOMAttribute)
NS_IMETHODIMP
nsDOMAttribute::DropReference()
{
mContent = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::SetContent(nsIContent* aContent)
{
mContent = aContent;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetContent(nsIContent** aContent)
{
*aContent = mContent;
NS_IF_ADDREF(*aContent);
return NS_OK;
}
nsresult
nsDOMAttribute::GetScriptObject(nsIScriptContext *aContext,
void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = nsGenericElement::GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptAttr(aContext,
(nsISupports *)(nsIDOMAttr *)this,
(nsISupports *)mContent,
(void **)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
return res;
}
nsresult
nsDOMAttribute::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
nsresult
nsDOMAttribute::GetName(nsString& aName)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
return mNodeInfo->GetQualifiedName(aName);
}
nsresult
nsDOMAttribute::GetValue(nsString& aValue)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
nsresult result = NS_OK;
if (nsnull != mContent) {
nsresult attrResult;
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> name;
mNodeInfo->GetNameAtom(*getter_AddRefs(name));
mNodeInfo->GetNamespaceID(nameSpaceID);
nsAutoString tmpValue;
attrResult = mContent->GetAttribute(nameSpaceID, name, tmpValue);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult) {
mValue = tmpValue;
}
}
aValue=mValue;
return result;
}
nsresult
nsDOMAttribute::SetValue(const nsString& aValue)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
nsresult result = NS_OK;
if (nsnull != mContent) {
result = mContent->SetAttribute(mNodeInfo, aValue, PR_TRUE);
}
mValue=aValue;
return result;
}
nsresult
nsDOMAttribute::GetSpecified(PRBool* aSpecified)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
NS_ENSURE_ARG_POINTER(aSpecified);
nsresult result = NS_OK;
if (nsnull == mContent) {
*aSpecified = PR_FALSE;
} else {
nsAutoString value;
nsresult attrResult;
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> name;
mNodeInfo->GetNameAtom(*getter_AddRefs(name));
mNodeInfo->GetNamespaceID(nameSpaceID);
attrResult = mContent->GetAttribute(nameSpaceID, name, value);
if (NS_CONTENT_ATTR_HAS_VALUE == attrResult) {
*aSpecified = PR_TRUE;
}
else {
*aSpecified = PR_FALSE;
}
}
return result;
}
NS_IMETHODIMP
nsDOMAttribute::GetOwnerElement(nsIDOMElement** aOwnerElement)
{
NS_ENSURE_ARG_POINTER(aOwnerElement);
if (mContent) {
return mContent->QueryInterface(NS_GET_IID(nsIDOMElement),
(void **)aOwnerElement);
}
*aOwnerElement = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetNodeName(nsString& aNodeName)
{
return GetName(aNodeName);
}
NS_IMETHODIMP
nsDOMAttribute::GetNodeValue(nsString& aNodeValue)
{
return GetValue(aNodeValue);
}
NS_IMETHODIMP
nsDOMAttribute::SetNodeValue(const nsString& aNodeValue)
{
return SetValue(aNodeValue);
}
NS_IMETHODIMP
nsDOMAttribute::GetNodeType(PRUint16* aNodeType)
{
NS_ENSURE_ARG_POINTER(aNodeType);
*aNodeType = (PRUint16)nsIDOMNode::ATTRIBUTE_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetParentNode(nsIDOMNode** aParentNode)
{
NS_ENSURE_ARG_POINTER(aParentNode);
*aParentNode = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetChildNodes(nsIDOMNodeList** aChildNodes)
{
if (nsnull == mChildList) {
mChildList = new nsAttributeChildList(this);
if (nsnull == mChildList) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mChildList);
}
return mChildList->QueryInterface(kIDOMNodeListIID, (void**)aChildNodes);
}
NS_IMETHODIMP
nsDOMAttribute::HasChildNodes(PRBool* aHasChildNodes)
{
*aHasChildNodes = PR_FALSE;
if (nsnull != mChild) {
*aHasChildNodes = PR_TRUE;
}
else if (nsnull != mContent) {
nsAutoString value;
GetValue(value);
if (0 < value.Length()) {
*aHasChildNodes = PR_TRUE;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetFirstChild(nsIDOMNode** aFirstChild)
{
nsAutoString value;
nsresult result;
result = GetValue(value);
if (NS_OK != result) {
return result;
}
if (0 < value.Length()) {
if (nsnull == mChild) {
nsIContent* content;
result = NS_NewTextNode(&content);
if (NS_OK != result) {
return result;
}
result = content->QueryInterface(kIDOMTextIID, (void**)&mChild);
NS_RELEASE(content);
}
mChild->SetData(value);
result = mChild->QueryInterface(kIDOMNodeIID, (void**)aFirstChild);
}
else {
*aFirstChild = nsnull;
}
return result;
}
NS_IMETHODIMP
nsDOMAttribute::GetLastChild(nsIDOMNode** aLastChild)
{
return GetFirstChild(aLastChild);
}
NS_IMETHODIMP
nsDOMAttribute::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
{
NS_ENSURE_ARG_POINTER(aPreviousSibling);
*aPreviousSibling = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetNextSibling(nsIDOMNode** aNextSibling)
{
NS_ENSURE_ARG_POINTER(aNextSibling);
*aNextSibling = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetAttributes(nsIDOMNamedNodeMap** aAttributes)
{
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMAttribute::ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMAttribute::RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMAttribute::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsDOMAttribute::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsDOMAttribute* newAttr;
if (nsnull != mContent) {
nsAutoString value;
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> name;
mNodeInfo->GetNameAtom(*getter_AddRefs(name));
mNodeInfo->GetNamespaceID(nameSpaceID);
mContent->GetAttribute(nameSpaceID, name, value);
newAttr = new nsDOMAttribute(nsnull, mNodeInfo, value);
}
else {
newAttr = new nsDOMAttribute(nsnull, mNodeInfo, mValue);
}
if (nsnull == newAttr) {
return NS_ERROR_OUT_OF_MEMORY;
}
return newAttr->QueryInterface(kIDOMNodeIID, (void**)aReturn);
}
NS_IMETHODIMP
nsDOMAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
{
nsresult result = NS_OK;
if (nsnull != mContent) {
nsIDOMNode* node;
result = mContent->QueryInterface(kIDOMNodeIID, (void**)&node);
if (NS_SUCCEEDED(result)) {
result = node->GetOwnerDocument(aOwnerDocument);
NS_RELEASE(node);
}
}
else {
*aOwnerDocument = nsnull;
}
return result;
}
NS_IMETHODIMP
nsDOMAttribute::GetNamespaceURI(nsString& aNamespaceURI)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
return mNodeInfo->GetNamespaceURI(aNamespaceURI);
}
NS_IMETHODIMP
nsDOMAttribute::GetPrefix(nsString& aPrefix)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
return mNodeInfo->GetPrefix(aPrefix);
}
NS_IMETHODIMP
nsDOMAttribute::SetPrefix(const nsString& aPrefix)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfo> newNodeInfo;
nsCOMPtr<nsIAtom> prefix;
nsresult rv = NS_OK;
if (aPrefix.Length())
prefix = dont_AddRef(NS_NewAtom(aPrefix));
rv = mNodeInfo->PrefixChanged(prefix, *getter_AddRefs(newNodeInfo));
NS_ENSURE_SUCCESS(rv, rv);
if (mContent) {
nsCOMPtr<nsIAtom> name;
PRInt32 nameSpaceID;
nsAutoString tmpValue;
mNodeInfo->GetNameAtom(*getter_AddRefs(name));
mNodeInfo->GetNamespaceID(nameSpaceID);
rv = mContent->GetAttribute(nameSpaceID, name, tmpValue);
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
mContent->UnsetAttribute(nameSpaceID, name, PR_TRUE);
mContent->SetAttribute(newNodeInfo, tmpValue, PR_TRUE);
}
}
mNodeInfo = newNodeInfo;
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::GetLocalName(nsString& aLocalName)
{
NS_ENSURE_TRUE(mNodeInfo, NS_ERROR_FAILURE);
return mNodeInfo->GetLocalName(aLocalName);
}
NS_IMETHODIMP
nsDOMAttribute::Normalize()
{
// Nothing to do here
return NS_OK;
}
NS_IMETHODIMP
nsDOMAttribute::Supports(const nsString& aFeature, const nsString& aVersion,
PRBool* aReturn)
{
return nsGenericElement::InternalSupports(aFeature, aVersion, aReturn);
}
//----------------------------------------------------------------------
nsAttributeChildList::nsAttributeChildList(nsDOMAttribute* aAttribute)
{
// Don't increment the reference count. The attribute will tell
// us when it's going away
mAttribute = aAttribute;
}
nsAttributeChildList::~nsAttributeChildList()
{
}
NS_IMETHODIMP
nsAttributeChildList::GetLength(PRUint32* aLength)
{
nsAutoString value;
*aLength = 0;
if (nsnull != mAttribute) {
mAttribute->GetValue(value);
if (0 < value.Length()) {
*aLength = 1;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsAttributeChildList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
*aReturn = nsnull;
if ((nsnull != mAttribute) && (0 == aIndex)) {
mAttribute->GetFirstChild(aReturn);
}
return NS_OK;
}
void
nsAttributeChildList::DropReference()
{
mAttribute = nsnull;
}

View File

@@ -0,0 +1,105 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDOMAttribute_h___
#define nsDOMAttribute_h___
#include "nsIDOMAttr.h"
#include "nsIDOMText.h"
#include "nsIDOMNodeList.h"
#include "nsIScriptObjectOwner.h"
#include "nsGenericDOMNodeList.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsINodeInfo.h"
class nsIContent;
class nsDOMAttribute;
#define NS_IDOMATTRIBUTEPRIVATE_IID \
{0xa6cf90dd, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
class nsIDOMAttributePrivate : public nsISupports {
public:
NS_IMETHOD DropReference() = 0;
NS_IMETHOD SetContent(nsIContent* aContent) = 0;
NS_IMETHOD GetContent(nsIContent** aContent) = 0;
};
// bogus child list for an attribute
class nsAttributeChildList : public nsGenericDOMNodeList
{
public:
nsAttributeChildList(nsDOMAttribute* aAttribute);
virtual ~nsAttributeChildList();
// interface nsIDOMNodeList
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
void DropReference();
protected:
nsDOMAttribute* mAttribute;
};
// Attribute helper class used to wrap up an attribute with a dom
// object that implements nsIDOMAttr and nsIDOMNode and
// nsIScriptObjectOwner
class nsDOMAttribute : public nsIDOMAttr,
public nsIScriptObjectOwner,
public nsIDOMAttributePrivate
{
public:
nsDOMAttribute(nsIContent* aContent, nsINodeInfo *aNodeInfo,
const nsString& aValue);
virtual ~nsDOMAttribute();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIDOMAttr interface
NS_DECL_IDOMATTR
// nsIDOMNode interface
NS_DECL_IDOMNODE
// nsIDOMAttributePrivate interface
NS_IMETHOD DropReference();
NS_IMETHOD SetContent(nsIContent* aContent);
NS_IMETHOD GetContent(nsIContent** aContent);
private:
nsIContent* mContent;
nsCOMPtr<nsINodeInfo> mNodeInfo;
nsString mValue;
// XXX For now, there's only a single child - a text
// element representing the value
nsIDOMText* mChild;
nsAttributeChildList* mChildList;
void* mScriptObject;
};
#endif /* nsDOMAttribute_h___ */

View File

@@ -0,0 +1,531 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsDOMAttributeMap.h"
#include "nsDOMAttribute.h"
#include "nsGenericElement.h"
#include "nsIContent.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsINameSpaceManager.h"
#include "nsDOMError.h"
//----------------------------------------------------------------------
nsDOMAttributeMap::nsDOMAttributeMap(nsIContent* aContent)
: mContent(aContent)
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
// We don't add a reference to our content. If it goes away,
// we'll be told to drop our reference
}
nsDOMAttributeMap::~nsDOMAttributeMap()
{
}
void
nsDOMAttributeMap::DropReference()
{
mContent = nsnull;
}
NS_INTERFACE_MAP_BEGIN(nsDOMAttributeMap)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNamedNodeMap)
NS_INTERFACE_MAP_ENTRY(nsIDOMNamedNodeMap)
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectOwner)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsDOMAttributeMap)
NS_IMPL_RELEASE(nsDOMAttributeMap)
nsresult
nsDOMAttributeMap::GetScriptObject(nsIScriptContext *aContext,
void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = nsGenericElement::GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptNamedNodeMap(aContext,
(nsISupports *)(nsIDOMNamedNodeMap *)this,
(nsISupports *)mContent,
(void**)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
return res;
}
nsresult
nsDOMAttributeMap::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
nsresult
nsDOMAttributeMap::GetNamedItem(const nsString &aAttrName,
nsIDOMNode** aAttribute)
{
NS_ENSURE_ARG_POINTER(aAttribute);
*aAttribute = nsnull;
nsresult rv = NS_OK;
if (mContent) {
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aAttrName)));
nsCOMPtr<nsIAtom> prefix;
nsresult attrResult;
nsAutoString value;
attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom,
*getter_AddRefs(prefix), value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
PRInt32 nameSpaceID = kNameSpaceID_None;
if (prefix) {
nsCOMPtr<nsIAtom> tmpName, tmpPrefix;
PRInt32 tmpNameSpaceID, attrCount;
mContent->GetAttributeCount(attrCount);
while (attrCount--) {
mContent->GetAttributeNameAt(attrCount, tmpNameSpaceID,
*getter_AddRefs(tmpName),
*getter_AddRefs(tmpPrefix));
if (tmpName == nameAtom && tmpPrefix == prefix) {
nameSpaceID = tmpNameSpaceID;
break;
}
}
}
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID,
*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute;
domAttribute = new nsDOMAttribute(mContent, ni, value);
NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY);
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aAttribute);
}
}
return rv;
}
nsresult
nsDOMAttributeMap::SetNamedItem(nsIDOMNode *aNode, nsIDOMNode **aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
if (!aNode) {
return NS_ERROR_NULL_POINTER;
}
nsresult rv = NS_OK;
*aReturn = nsnull;
if (mContent) {
nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aNode));
if (!attribute) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
nsAutoString name, value;
nsCOMPtr<nsIAtom> nameAtom;
attribute->GetName(name);
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(name, nsnull, kNameSpaceID_None, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
ni->GetNameAtom(*getter_AddRefs(nameAtom));
nsresult attrResult = mContent->GetAttribute(kNameSpaceID_Unknown,
nameAtom, value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
nsDOMAttribute* domAttribute;
// We pass a null content here since the attr node we return isn't
// tied to this content anymore.
domAttribute = new nsDOMAttribute(nsnull, ni, value);
if (!domAttribute) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
}
attribute->GetValue(value);
rv = mContent->SetAttribute(kNameSpaceID_None, nameAtom, value, PR_TRUE);
}
return rv;
}
NS_IMETHODIMP
nsDOMAttributeMap::RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
nsresult rv = NS_OK;
if (mContent) {
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aName)));
PRInt32 nameSpaceID = kNameSpaceID_None;
nsCOMPtr<nsIDOMNode> attribute;
nsCOMPtr<nsIAtom> prefix;
nsresult attrResult;
nsAutoString value;
attrResult = mContent->GetAttribute(kNameSpaceID_Unknown, nameAtom,
*getter_AddRefs(prefix), value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
if (prefix) {
nsCOMPtr<nsIAtom> tmpName, tmpPrefix;
PRInt32 tmpNameSpaceID, attrCount;
mContent->GetAttributeCount(attrCount);
while (attrCount--) {
mContent->GetAttributeNameAt(attrCount, tmpNameSpaceID,
*getter_AddRefs(tmpName),
*getter_AddRefs(tmpPrefix));
if (tmpName == nameAtom && tmpPrefix == prefix) {
nameSpaceID = tmpNameSpaceID;
break;
}
}
}
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute;
domAttribute = new nsDOMAttribute(nsnull, ni, value);
if (!domAttribute) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
} else {
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
rv = mContent->UnsetAttribute(nameSpaceID, nameAtom, PR_TRUE);
}
return rv;
}
nsresult
nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
PRInt32 nameSpaceID;
nsCOMPtr<nsIAtom> nameAtom, prefix;
nsresult rv = NS_OK;
if (mContent &&
NS_SUCCEEDED(mContent->GetAttributeNameAt(aIndex,
nameSpaceID,
*getter_AddRefs(nameAtom),
*getter_AddRefs(prefix)))) {
nsAutoString value, name;
mContent->GetAttribute(nameSpaceID, nameAtom, value);
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute = new nsDOMAttribute(mContent, ni, value);
NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY);
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
}
else {
*aReturn = nsnull;
rv = NS_ERROR_DOM_INDEX_SIZE_ERR;
}
return rv;
}
nsresult
nsDOMAttributeMap::GetLength(PRUint32 *aLength)
{
NS_ENSURE_ARG_POINTER(aLength);
PRInt32 n;
nsresult rv = NS_OK;
if (nsnull != mContent) {
rv = mContent->GetAttributeCount(n);
*aLength = PRUint32(n);
} else {
*aLength = 0;
}
return rv;
}
nsresult
nsDOMAttributeMap::GetNamedItemNS(const nsString& aNamespaceURI,
const nsString& aLocalName,
nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
nsresult rv = NS_OK;
if (mContent) {
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aLocalName)));
PRInt32 nameSpaceID = kNameSpaceID_None;
nsCOMPtr<nsIAtom> prefix;
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
if (aNamespaceURI.Length()) {
nsCOMPtr<nsINameSpaceManager> nsmgr;
nimgr->GetNamespaceManager(*getter_AddRefs(nsmgr));
NS_ENSURE_TRUE(nsmgr, NS_ERROR_FAILURE);
nsmgr->GetNameSpaceID(aNamespaceURI, nameSpaceID);
if (nameSpaceID == kNameSpaceID_Unknown)
return NS_OK;
}
nsresult attrResult;
nsAutoString value;
attrResult = mContent->GetAttribute(nameSpaceID, nameAtom,
*getter_AddRefs(prefix), value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute;
domAttribute = new nsDOMAttribute(mContent, ni, value);
NS_ENSURE_TRUE(domAttribute, NS_ERROR_OUT_OF_MEMORY);
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
}
}
return rv;
}
nsresult
nsDOMAttributeMap::SetNamedItemNS(nsIDOMNode* aArg, nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
nsresult rv = NS_OK;
*aReturn = nsnull;
if (mContent) {
nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aArg));
if (!attribute) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
nsAutoString name, nsURI, value;
nsCOMPtr<nsIAtom> nameAtom;
PRInt32 nameSpaceID;
attribute->GetName(name);
attribute->GetNamespaceURI(nsURI);
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
nimgr->GetNodeInfo(name, nsURI, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
ni->GetNameAtom(*getter_AddRefs(nameAtom));
ni->GetNamespaceID(nameSpaceID);
nsresult attrResult = mContent->GetAttribute(nameSpaceID, nameAtom, value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
nsDOMAttribute* domAttribute;
// We pass a null content here since the attr node we return isn't
// tied to this content anymore.
domAttribute = new nsDOMAttribute(nsnull, ni, value);
if (!domAttribute) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
}
attribute->GetValue(value);
rv = mContent->SetAttribute(ni, value, PR_TRUE);
}
return rv;
}
nsresult
nsDOMAttributeMap::RemoveNamedItemNS(const nsString& aNamespaceURI,
const nsString& aLocalName,
nsIDOMNode** aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
nsresult rv = NS_OK;
if (mContent) {
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(aLocalName)));
PRInt32 nameSpaceID = kNameSpaceID_None;
nsCOMPtr<nsIDOMNode> attribute;
nsCOMPtr<nsIAtom> prefix;
nsCOMPtr<nsINodeInfo> ni;
mContent->GetNodeInfo(*getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsCOMPtr<nsINodeInfoManager> nimgr;
ni->GetNodeInfoManager(*getter_AddRefs(nimgr));
NS_ENSURE_TRUE(nimgr, NS_ERROR_FAILURE);
if (aNamespaceURI.Length()) {
nsCOMPtr<nsINameSpaceManager> nsmgr;
nimgr->GetNamespaceManager(*getter_AddRefs(nsmgr));
NS_ENSURE_TRUE(nsmgr, NS_ERROR_FAILURE);
nsmgr->GetNameSpaceID(aNamespaceURI, nameSpaceID);
if (nameSpaceID == kNameSpaceID_Unknown)
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
nsresult attrResult;
nsAutoString value;
attrResult = mContent->GetAttribute(nameSpaceID, nameAtom,
*getter_AddRefs(prefix), value);
if (NS_CONTENT_ATTR_NOT_THERE != attrResult && NS_SUCCEEDED(attrResult)) {
nimgr->GetNodeInfo(nameAtom, prefix, nameSpaceID, *getter_AddRefs(ni));
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
nsDOMAttribute* domAttribute;
domAttribute = new nsDOMAttribute(nsnull, ni, value);
if (!domAttribute) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = domAttribute->QueryInterface(NS_GET_IID(nsIDOMAttr),
(void **)aReturn);
} else {
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
rv = mContent->UnsetAttribute(nameSpaceID, nameAtom, PR_TRUE);
}
return rv;
}
#ifdef DEBUG
nsresult
nsDOMAttributeMap::SizeOfNamedNodeMap(nsIDOMNamedNodeMap* aMap,
nsISizeOfHandler* aSizer,
PRUint32* aResult)
{
if (!aResult) return NS_ERROR_NULL_POINTER;
nsDOMAttributeMap* map = (nsDOMAttributeMap*) aMap;
PRUint32 sum = sizeof(nsDOMAttributeMap);
*aResult = sum;
return NS_OK;
}
#endif

View File

@@ -0,0 +1,72 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDOMAttributeMap_h___
#define nsDOMAttributeMap_h___
#include "nsIDOMNamedNodeMap.h"
#include "nsIScriptObjectOwner.h"
#include "nsVoidArray.h"
#include "nsString.h"
#include "plhash.h"
class nsIContent;
// Helper class that implements the nsIDOMNamedNodeMap interface.
class nsDOMAttributeMap : public nsIDOMNamedNodeMap,
public nsIScriptObjectOwner
{
public:
nsDOMAttributeMap(nsIContent* aContent);
virtual ~nsDOMAttributeMap();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIDOMNamedNodeMap interface
NS_IMETHOD GetLength(PRUint32* aSize);
NS_IMETHOD GetNamedItem(const nsString& aName, nsIDOMNode** aReturn);
NS_IMETHOD SetNamedItem(nsIDOMNode* aNode, nsIDOMNode** aReturn);
NS_IMETHOD RemoveNamedItem(const nsString& aName, nsIDOMNode** aReturn);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
NS_IMETHOD GetNamedItemNS(const nsString& aNamespaceURI,
const nsString& aLocalName, nsIDOMNode** aReturn);
NS_IMETHOD SetNamedItemNS(nsIDOMNode* aArg, nsIDOMNode** aReturn);
NS_IMETHOD RemoveNamedItemNS(const nsString& aNamespaceURI,
const nsString&aLocalName, nsIDOMNode** aReturn);
void DropReference();
#ifdef DEBUG
static nsresult SizeOfNamedNodeMap(nsIDOMNamedNodeMap* aMap,
nsISizeOfHandler* aSizer,
PRUint32* aResult);
#endif
private:
nsIContent* mContent;
void* mScriptObject;
};
#endif /* nsDOMAttributeMap_h___ */

View File

@@ -0,0 +1,268 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsDOMDocumentType.h"
#include "nsDOMAttributeMap.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsLayoutAtoms.h"
#include "nsCOMPtr.h"
nsresult
NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
const nsString& aName,
nsIDOMNamedNodeMap *aEntities,
nsIDOMNamedNodeMap *aNotations,
const nsString& aPublicId,
const nsString& aSystemId,
const nsString& aInternalSubset)
{
NS_ENSURE_ARG_POINTER(aDocType);
*aDocType = new nsDOMDocumentType(aName, aEntities, aNotations,
aPublicId, aSystemId, aInternalSubset);
if (!*aDocType) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(*aDocType);
return NS_OK;
}
nsDOMDocumentType::nsDOMDocumentType(const nsString& aName,
nsIDOMNamedNodeMap *aEntities,
nsIDOMNamedNodeMap *aNotations,
const nsString& aPublicId,
const nsString& aSystemId,
const nsString& aInternalSubset) :
mName(aName),
mPublicId(aPublicId),
mSystemId(aSystemId),
mInternalSubset(aInternalSubset)
{
NS_INIT_REFCNT();
mEntities = aEntities;
mNotations = aNotations;
NS_IF_ADDREF(mEntities);
NS_IF_ADDREF(mNotations);
}
nsDOMDocumentType::~nsDOMDocumentType()
{
NS_IF_RELEASE(mEntities);
NS_IF_RELEASE(mNotations);
}
NS_IMPL_ADDREF(nsDOMDocumentType)
NS_IMPL_RELEASE(nsDOMDocumentType)
NS_INTERFACE_MAP_BEGIN(nsDOMDocumentType)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDocumentType)
NS_INTERFACE_MAP_ENTRY(nsIDOMDocumentType)
NS_INTERFACE_MAP_ENTRY(nsIDOMNode)
NS_INTERFACE_MAP_ENTRY(nsIContent)
NS_INTERFACE_MAP_ENTRY(nsIScriptObjectOwner)
NS_INTERFACE_MAP_END_THREADSAFE
NS_IMETHODIMP
nsDOMDocumentType::GetName(nsString& aName)
{
aName=mName;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetEntities(nsIDOMNamedNodeMap** aEntities)
{
NS_ENSURE_ARG_POINTER(aEntities);
*aEntities = mEntities;
NS_IF_ADDREF(*aEntities);
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetNotations(nsIDOMNamedNodeMap** aNotations)
{
NS_ENSURE_ARG_POINTER(aNotations);
*aNotations = mNotations;
NS_IF_ADDREF(*aNotations);
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetPublicId(nsString& aPublicId)
{
aPublicId = mPublicId;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetSystemId(nsString& aSystemId)
{
aSystemId = mSystemId;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetInternalSubset(nsString& aInternalSubset)
{
aInternalSubset = mInternalSubset;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetTag(nsIAtom*& aResult) const
{
aResult = NS_NewAtom(mName.GetUnicode());
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetNodeInfo(nsINodeInfo*& aResult) const
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetNodeName(nsString& aNodeName)
{
aNodeName=mName;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::GetNodeType(PRUint16* aNodeType)
{
*aNodeType = nsIDOMNode::DOCUMENT_TYPE_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsDOMDocumentType* it = new nsDOMDocumentType(mName,
mEntities,
mNotations,
mPublicId,
mSystemId,
mInternalSubset);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
}
NS_IMETHODIMP
nsDOMDocumentType::List(FILE* out, PRInt32 aIndent) const
{
NS_PRECONDITION(nsnull != mInner.mDocument, "bad content");
PRInt32 index;
for (index = aIndent; --index >= 0; ) fputs(" ", out);
fprintf(out, "Document type refcount: %d\n", mRefCnt);
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::DumpContent(FILE* out = stdout, PRInt32 aIndent = 0,PRBool aDumpAll=PR_TRUE) const {
return NS_OK;
}
NS_IMETHODIMP
nsDOMDocumentType::HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
// We should never be getting events
NS_ASSERTION(0, "event handler called for document type");
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
NS_IMETHODIMP
nsDOMDocumentType::GetContentID(PRUint32* aID)
{
NS_ENSURE_ARG_POINTER(aID);
*aID = 0;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDOMDocumentType::SetContentID(PRUint32 aID)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsDOMDocumentType::SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const
{
NS_ENSURE_ARG_POINTER(aResult);
#ifdef DEBUG
PRUint32 sum;
mInner.SizeOf(aSizer, &sum, sizeof(*this));
PRUint32 ssize;
mName.SizeOf(aSizer, &ssize);
sum = sum - sizeof(mName) + ssize;
if (mEntities) {
PRBool recorded;
aSizer->RecordObject((void*) mEntities, &recorded);
if (!recorded) {
PRUint32 size;
nsDOMAttributeMap::SizeOfNamedNodeMap(mEntities, aSizer, &size);
aSizer->AddSize(nsLayoutAtoms::xml_document_entities, size);
}
}
if (mNotations) {
PRBool recorded;
aSizer->RecordObject((void*) mNotations, &recorded);
if (!recorded) {
PRUint32 size;
nsDOMAttributeMap::SizeOfNamedNodeMap(mNotations, aSizer, &size);
aSizer->AddSize(nsLayoutAtoms::xml_document_notations, size);
}
}
#endif
return NS_OK;
}

View File

@@ -0,0 +1,88 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDOMDocumentType_h___
#define nsDOMDocumentType_h___
#include "nsIDOMDocumentType.h"
#include "nsIScriptObjectOwner.h"
#include "nsIContent.h"
#include "nsGenericDOMDataNode.h"
#include "nsString.h"
#include "nsISizeOfHandler.h"
class nsIDOMNamedNodeMap;
class nsDOMDocumentType : public nsIDOMDocumentType,
public nsIScriptObjectOwner,
public nsIContent
{
public:
nsDOMDocumentType(const nsString& aName,
nsIDOMNamedNodeMap *aEntities,
nsIDOMNamedNodeMap *aNotations,
const nsString& aPublicId,
const nsString& aSystemId,
const nsString& aInternalSubset);
virtual ~nsDOMDocumentType();
// nsISupports
NS_DECL_ISUPPORTS
// nsIDOMNode
NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(mInner)
// nsIDOMDocumentType
NS_DECL_IDOMDOCUMENTTYPE
// nsIScriptObjectOwner interface
NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(mInner);
// nsIContent
NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(mInner)
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
protected:
// XXX DocumentType is currently implemented by using the generic
// CharacterData inner object, even though DocumentType is not
// character data. This is done simply for convenience and should
// be changed if this restricts what should be done for character data.
nsGenericDOMDataNode mInner;
nsString mName;
nsIDOMNamedNodeMap* mEntities;
nsIDOMNamedNodeMap* mNotations;
nsString mPublicId;
nsString mSystemId;
nsString mInternalSubset;
};
extern nsresult NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
const nsString& aName,
nsIDOMNamedNodeMap *aEntities,
nsIDOMNamedNodeMap *aNotations,
const nsString& aPublicId,
const nsString& aSystemId,
const nsString& aInternalSubset);
#endif // nsDOMDocument_h___

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,530 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsDocument_h___
#define nsDocument_h___
#include "nsIDocument.h"
#include "nsWeakReference.h"
#include "nsWeakPtr.h"
#include "nsVoidArray.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentView.h"
#include "nsIDOMDocumentXBL.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMDocumentStyle.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDiskDocument.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMEventTarget.h"
#include "nsIXIFConverter.h"
#include "nsIJSScriptObject.h"
#include "nsIContent.h"
#include "nsGenericDOMNodeList.h"
#include "nsIPrincipal.h"
#include "nsIBindingManager.h"
#include "nsINodeInfo.h"
#include "nsIDOMDocumentEvent.h"
#include "nsISupportsArray.h"
class nsIEventListenerManager;
class nsDOMStyleSheetList;
class nsIOutputStream;
class nsDocument;
#if 0
class nsPostData : public nsIPostData {
public:
nsPostData(PRBool aIsFile, char* aData);
NS_DECL_ISUPPORTS
virtual PRBool IsFile();
virtual const char* GetData();
virtual PRInt32 GetDataLength();
protected:
virtual ~nsPostData();
PRBool mIsFile;
char* mData;
PRInt32 mDataLen;
};
#endif
class nsDocHeaderData
{
public:
nsDocHeaderData(nsIAtom* aField, const nsString& aData)
{
mField = aField;
NS_IF_ADDREF(mField);
mData.Assign(aData);
mNext = nsnull;
}
~nsDocHeaderData(void)
{
NS_IF_RELEASE(mField);
if (nsnull != mNext) {
delete mNext;
mNext = nsnull;
}
}
nsIAtom* mField;
nsAutoString mData;
nsDocHeaderData* mNext;
};
// Represents the children of a document (prolog, epilog and
// document element)
class nsDocumentChildNodes : public nsGenericDOMNodeList
{
public:
nsDocumentChildNodes(nsIDocument* aDocument);
~nsDocumentChildNodes();
NS_IMETHOD GetLength(PRUint32* aLength);
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn);
void DropReference();
protected:
nsIDocument* mDocument;
};
class nsAnonymousContentList : public nsGenericDOMNodeList
{
public:
nsAnonymousContentList(nsISupportsArray* aElements);
virtual ~nsAnonymousContentList();
// nsIDOMNodeList interface
NS_DECL_IDOMNODELIST
private:
nsISupportsArray* mElements;
};
// Base class for our document implementations
class nsDocument : public nsIDocument,
public nsIDOMDocument,
public nsIDOMNSDocument,
public nsIDOMDocumentEvent,
public nsIDOMDocumentStyle,
public nsIDOMDocumentView,
public nsIDOMDocumentXBL,
public nsIDiskDocument,
public nsIJSScriptObject,
public nsSupportsWeakReference,
public nsIDOMEventReceiver,
public nsIScriptObjectPrincipal
{
public:
NS_DECL_ISUPPORTS
virtual nsIArena* GetArena();
NS_IMETHOD StartDocumentLoad(const char* aCommand,
nsIChannel* aChannel,
nsILoadGroup* aLoadGroup,
nsISupports* aContainer,
nsIStreamListener **aDocListener,
PRBool aReset = PR_TRUE);
NS_IMETHOD StopDocumentLoad();
/**
* Return the title of the document. May return null.
*/
virtual const nsString* GetDocumentTitle() const;
/**
* Return the URL for the document. May return null.
*/
virtual nsIURI* GetDocumentURL() const;
/**
* Return the principal responsible for this document.
*/
NS_IMETHOD GetPrincipal(nsIPrincipal **aPrincipal);
/**
* Update principal responsible for this document to the intersection
* of its previous value and aPrincipal, and return its new value.
*/
NS_IMETHOD AddPrincipal(nsIPrincipal *aPrincipal);
/**
* Return the content (mime) type of this document.
*/
NS_IMETHOD GetContentType(nsString& aContentType) const;
/**
* Return the LoadGroup for the document. May return null.
*/
NS_IMETHOD GetDocumentLoadGroup(nsILoadGroup **aGroup) const;
/**
* Return the base URL for realtive URLs in the document. May return null (or the document URL).
*/
NS_IMETHOD GetBaseURL(nsIURI*& aURL) const;
/**
* Return a standard name for the document's character set. This will
* trigger a startDocumentLoad if necessary to answer the question.
*/
NS_IMETHOD GetDocumentCharacterSet(nsString& oCharsetID);
NS_IMETHOD SetDocumentCharacterSet(const nsString& aCharSetID);
/**
* Add an observer that gets notified whenever the charset changes.
*/
NS_IMETHOD AddCharSetObserver(nsIObserver* aObserver);
/**
* Remove a charset observer.
*/
NS_IMETHOD RemoveCharSetObserver(nsIObserver* aObserver);
/**
* Return the Line Breaker for the document
*/
NS_IMETHOD GetLineBreaker(nsILineBreaker** aResult) ;
NS_IMETHOD SetLineBreaker(nsILineBreaker* aLineBreaker) ;
NS_IMETHOD GetWordBreaker(nsIWordBreaker** aResult) ;
NS_IMETHOD SetWordBreaker(nsIWordBreaker* aWordBreaker) ;
/**
* Access HTTP header data (this may also get set from other sources, like
* HTML META tags).
*/
NS_IMETHOD GetHeaderData(nsIAtom* aHeaderField, nsString& aData) const;
NS_IMETHOD SetHeaderData(nsIAtom* aheaderField, const nsString& aData);
/**
* Create a new presentation shell that will use aContext for
* it's presentation context (presentation context's <b>must not</b> be
* shared among multiple presentation shell's).
*/
#if 0
// XXX Temp hack: moved to nsMarkupDocument
NS_IMETHOD CreateShell(nsIPresContext* aContext,
nsIViewManager* aViewManager,
nsIStyleSet* aStyleSet,
nsIPresShell** aInstancePtrResult);
#endif
virtual PRBool DeleteShell(nsIPresShell* aShell);
virtual PRInt32 GetNumberOfShells();
virtual nsIPresShell* GetShellAt(PRInt32 aIndex);
/**
* Return the parent document of this document. Will return null
* unless this document is within a compound document and has a parent.
*/
virtual nsIDocument* GetParentDocument();
virtual void SetParentDocument(nsIDocument* aParent);
virtual void AddSubDocument(nsIDocument* aSubDoc);
virtual PRInt32 GetNumberOfSubDocuments();
virtual nsIDocument* GetSubDocumentAt(PRInt32 aIndex);
/**
* Return the root content object for this document.
*/
virtual nsIContent* GetRootContent();
virtual void SetRootContent(nsIContent* aRoot);
/**
* Methods to append to the prolog and epilog of
* a document. The prolog is the content before the document
* element, the epilog after.
*/
NS_IMETHOD AppendToProlog(nsIContent* aContent);
NS_IMETHOD AppendToEpilog(nsIContent* aContent);
/**
* Get the direct children of the document - content in
* the prolog, the root content and content in the epilog.
*/
NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const;
NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aIndex) const;
NS_IMETHOD GetChildCount(PRInt32& aCount);
/**
* Get the style sheets owned by this document.
* These are ordered, highest priority last
*/
virtual PRInt32 GetNumberOfStyleSheets();
virtual nsIStyleSheet* GetStyleSheetAt(PRInt32 aIndex);
virtual PRInt32 GetIndexOfStyleSheet(nsIStyleSheet* aSheet);
virtual void AddStyleSheet(nsIStyleSheet* aSheet);
virtual void RemoveStyleSheet(nsIStyleSheet* aSheet);
NS_IMETHOD UpdateStyleSheets(nsISupportsArray* aOldSheets, nsISupportsArray* aNewSheets);
virtual void AddStyleSheetToStyleSets(nsIStyleSheet* aSheet);
virtual void RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet);
NS_IMETHOD InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool aNotify);
virtual void SetStyleSheetDisabledState(nsIStyleSheet* aSheet,
PRBool mDisabled);
/**
* Set the object from which a document can get a script context.
* This is the context within which all scripts (during document
* creation and during event handling) will run.
*/
NS_IMETHOD GetScriptGlobalObject(nsIScriptGlobalObject** aGlobalObject);
NS_IMETHOD SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject);
/**
* Get the name space manager for this document
*/
NS_IMETHOD GetNameSpaceManager(nsINameSpaceManager*& aManager);
/**
* Add a new observer of document change notifications. Whenever
* content is changed, appended, inserted or removed the observers are
* informed.
*/
virtual void AddObserver(nsIDocumentObserver* aObserver);
/**
* Remove an observer of document change notifications. This will
* return false if the observer cannot be found.
*/
virtual PRBool RemoveObserver(nsIDocumentObserver* aObserver);
// Observation hooks used by content nodes to propagate
// notifications to document observers.
NS_IMETHOD BeginUpdate();
NS_IMETHOD EndUpdate();
NS_IMETHOD BeginLoad();
NS_IMETHOD EndLoad();
NS_IMETHOD ContentChanged(nsIContent* aContent,
nsISupports* aSubContent);
NS_IMETHOD ContentStatesChanged(nsIContent* aContent1, nsIContent* aContent2);
NS_IMETHOD AttributeChanged(nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD ContentAppended(nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD StyleRuleChanged(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint); // See nsStyleConsts fot hint values
NS_IMETHOD StyleRuleAdded(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule);
NS_IMETHOD StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule);
/**
* Finds text in content
*/
NS_IMETHOD FindNext(const nsString &aSearchStr, PRBool aMatchCase, PRBool aSearchDown, PRBool &aIsFound);
/**
* Converts the document or a selection of the
* document to XIF (XML Interchange Format)
* and places the result in aBuffer.
*/
NS_IMETHOD CreateXIF(nsString & aBuffer, nsIDOMSelection* aSelection);
NS_IMETHOD ToXIF(nsIXIFConverter * aConverter, nsIDOMNode* aNode);
virtual void BeginConvertToXIF(nsIXIFConverter * aConverter, nsIDOMNode* aNode);
virtual void ConvertChildrenToXIF(nsIXIFConverter * aConverter, nsIDOMNode* aNode);
virtual void FinishConvertToXIF(nsIXIFConverter * aConverter, nsIDOMNode* aNode);
NS_IMETHOD FlushPendingNotifications();
NS_IMETHOD GetAndIncrementContentID(PRInt32* aID);
NS_IMETHOD GetBindingManager(nsIBindingManager** aResult);
NS_IMETHOD GetNodeInfoManager(nsINodeInfoManager*& aNodeInfoManager);
public:
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// nsIDOMDocument interface
NS_IMETHOD GetDoctype(nsIDOMDocumentType** aDoctype);
NS_IMETHOD GetImplementation(nsIDOMDOMImplementation** aImplementation);
NS_IMETHOD GetDocumentElement(nsIDOMElement** aDocumentElement);
NS_IMETHOD CreateElement(const nsString& aTagName, nsIDOMElement** aReturn);
NS_IMETHOD CreateDocumentFragment(nsIDOMDocumentFragment** aReturn);
NS_IMETHOD CreateTextNode(const nsString& aData, nsIDOMText** aReturn);
NS_IMETHOD CreateComment(const nsString& aData, nsIDOMComment** aReturn);
NS_IMETHOD CreateCDATASection(const nsString& aData, nsIDOMCDATASection** aReturn);
NS_IMETHOD CreateProcessingInstruction(const nsString& aTarget, const nsString& aData, nsIDOMProcessingInstruction** aReturn);
NS_IMETHOD CreateAttribute(const nsString& aName, nsIDOMAttr** aReturn);
NS_IMETHOD CreateEntityReference(const nsString& aName, nsIDOMEntityReference** aReturn);
NS_IMETHOD GetElementsByTagName(const nsString& aTagname, nsIDOMNodeList** aReturn);
NS_IMETHOD GetElementsByTagNameNS(const nsString& aNamespaceURI, const nsString& aLocalName, nsIDOMNodeList** aReturn);
NS_IMETHOD GetStyleSheets(nsIDOMStyleSheetList** aStyleSheets);
NS_IMETHOD GetCharacterSet(nsString& aCharacterSet);
NS_IMETHOD ImportNode(nsIDOMNode* aImportedNode,
PRBool aDeep,
nsIDOMNode** aReturn);
NS_IMETHOD CreateElementWithNameSpace(const nsString& aTagName,
const nsString& aNameSpace,
nsIDOMElement** aReturn);
NS_IMETHOD CreateRange(nsIDOMRange** aReturn);
NS_IMETHOD GetWidth(PRInt32* aWidth);
NS_IMETHOD GetHeight(PRInt32* aHeight);
NS_IMETHOD Load (const nsString& aUrl);
NS_IMETHOD GetPlugins(nsIDOMPluginArray** aPlugins);
// nsIDOMNode interface
NS_DECL_IDOMNODE
// nsIDOMDocumentView
NS_DECL_IDOMDOCUMENTVIEW
// nsIDOMDocumentXBL
NS_DECL_IDOMDOCUMENTXBL
// nsIDOMDocumentEvent
NS_DECL_IDOMDOCUMENTEVENT
// nsIDOMEventReceiver interface
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager **aInstancePtrResult);
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
// nsIDiskDocument inteface
NS_IMETHOD InitDiskDocument(nsFileSpec *aFileSpec);
NS_IMETHOD SaveFile(nsFileSpec* aFileSpec,
PRBool aReplaceExisting,
PRBool aSaveCopy,
const nsString& aSaveFileType,
const nsString& aSaveCharset,
PRUint32 aFlags);
NS_IMETHOD GetFileSpec(nsFileSpec& aFileSpec);
NS_IMETHOD GetModCount(PRInt32 *outModCount);
NS_IMETHOD ResetModCount();
NS_IMETHOD IncrementModCount(PRInt32 aNumMods);
// nsIDOMEventTarget interface
NS_IMETHOD AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aUseCapture);
NS_IMETHOD RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aUseCapture);
NS_IMETHOD DispatchEvent(nsIDOMEvent* aEvent);
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
virtual PRBool IsInSelection(nsIDOMSelection* aSelection, const nsIContent *aContent) const;
virtual nsIContent* GetPrevContent(const nsIContent *aContent) const;
virtual nsIContent* GetNextContent(const nsIContent *aContent) const;
// nsIJSScriptObject interface
virtual PRBool AddProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool DeleteProperty(JSContext *aContext,
JSObject *aObj, jsval aID, jsval *aVp);
virtual PRBool GetProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool SetProperty(JSContext *aContext, JSObject *aObj,
jsval aID, jsval *aVp);
virtual PRBool EnumerateProperty(JSContext *aContext, JSObject *aObj);
virtual PRBool Resolve(JSContext *aContext, JSObject *aObj, jsval aID);
virtual PRBool Convert(JSContext *aContext, JSObject *aObj, jsval aID);
virtual void Finalize(JSContext *aContext, JSObject *aObj);
virtual nsresult Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup);
virtual nsresult SetDocumentURL(nsIURI* aURI);
protected:
nsIContent* FindContent(const nsIContent* aStartNode,
const nsIContent* aTest1,
const nsIContent* aTest2) const;
nsresult GetPixelDimensions(nsIPresShell* aShell,
PRInt32* aWidth,
PRInt32* aHeight);
protected:
virtual void InternalAddStyleSheet(nsIStyleSheet* aSheet); // subclass hooks for sheet ordering
virtual void InternalInsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex);
nsDocument();
virtual ~nsDocument();
nsresult Init();
nsIArena* mArena;
nsString* mDocumentTitle;
nsIURI* mDocumentURL;
nsIPrincipal* mPrincipal;
nsWeakPtr mDocumentLoadGroup;
nsString mCharacterSet;
nsVoidArray mCharSetObservers;
nsIDocument* mParentDocument;
nsVoidArray mSubDocuments;
nsVoidArray mPresShells;
nsIContent* mRootContent;
nsVoidArray mStyleSheets;
nsVoidArray mObservers;
void* mScriptObject;
nsCOMPtr<nsIScriptGlobalObject> mScriptGlobalObject;
nsIEventListenerManager* mListenerManager;
PRInt8 mDisplaySelection;
PRBool mInDestructor;
nsDOMStyleSheetList *mDOMStyleSheets;
nsINameSpaceManager* mNameSpaceManager;
nsDocHeaderData* mHeaderData;
nsILineBreaker* mLineBreaker;
nsVoidArray *mProlog;
nsVoidArray *mEpilog;
nsDocumentChildNodes* mChildNodes;
nsIWordBreaker* mWordBreaker;
// A content ID counter used to give a monotonically increasing ID to the content
// objects in the document's content model
PRInt32 mNextContentID;
// disk file members
nsFileSpec* mFileSpec;
PRInt32 mModCount;
nsCOMPtr<nsIBindingManager> mBindingManager;
nsCOMPtr<nsINodeInfoManager> mNodeInfoManager; // OWNER
};
#endif /* nsDocument_h___ */

View File

@@ -0,0 +1,365 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsIDocumentEncoder.h"
#include "nscore.h"
#include "nsIFactory.h"
#include "nsISupports.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIDocument.h"
#include "nsIDOMSelection.h"
#include "nsIPresShell.h"
#include "nsXIFDTD.h"
#include "nsParserCIID.h"
#include "nsIParser.h"
#include "nsHTMLContentSinkStream.h"
#include "nsHTMLToTXTSinkStream.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kCTextEncoderCID, NS_TEXT_ENCODER_CID);
static NS_DEFINE_IID(kCParserIID, NS_IPARSER_IID);
static NS_DEFINE_IID(kCParserCID, NS_PARSER_IID);
class nsTextEncoder : public nsIDocumentEncoder
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IDOCUMENT_ENCODER_IID; return iid; }
nsTextEncoder();
virtual ~nsTextEncoder();
NS_IMETHOD Init(nsIDocument* aDocument, const nsString& aMimeType, PRUint32 aFlags);
/* Interfaces for addref and release and queryinterface */
NS_DECL_ISUPPORTS
// Inherited methods from nsIDocumentEncoder
NS_IMETHOD SetSelection(nsIDOMSelection* aSelection);
NS_IMETHOD SetWrapColumn(PRUint32 aWC);
NS_IMETHOD SetCharset(const nsString& aCharset);
NS_IMETHOD EncodeToStream(nsIOutputStream* aStream);
NS_IMETHOD EncodeToString(nsString& aOutputString);
protected:
// Local methods to the text encoder -- used to be in nsITextEncoder,
// but that interface is obsolete now.
//NS_IMETHOD PrettyPrint(PRBool aYes);
//NS_IMETHOD AddHeader(PRBool aYes);
nsIDocument* mDocument;
nsIDOMSelection* mSelection;
nsString mMimeType;
nsString mCharset;
PRUint32 mFlags;
PRUint32 mWrapColumn;
};
NS_IMPL_ADDREF(nsTextEncoder)
NS_IMPL_RELEASE(nsTextEncoder)
nsTextEncoder::nsTextEncoder()
{
NS_INIT_REFCNT();
mMimeType.AssignWithConversion("text/plain");
mDocument = 0;
mSelection = 0;
mFlags = 0;
mWrapColumn = 72;
}
nsTextEncoder::~nsTextEncoder()
{
NS_IF_RELEASE(mDocument);
//NS_IF_RELEASE(mSelection); // no. we never addref'd it.
}
NS_IMETHODIMP
nsTextEncoder::Init(nsIDocument* aDocument, const nsString& aMimeType, PRUint32 aFlags)
{
if (!aDocument)
return NS_ERROR_INVALID_ARG;
mDocument = aDocument;
NS_ADDREF(mDocument);
mMimeType = aMimeType;
mFlags = aFlags;
return NS_OK;
}
nsresult nsTextEncoder::QueryInterface(REFNSIID aIID,
void **aInstancePtr)
{
if (nsnull == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = 0;
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void *)(nsISupports*)this;
} else if (aIID.Equals(NS_GET_IID(nsIDocumentEncoder))) {
*aInstancePtr = (void *)(nsIDocumentEncoder*)this;
}
if (nsnull == *aInstancePtr)
return NS_NOINTERFACE;
NS_ADDREF_THIS();
return NS_OK;
}
NS_IMETHODIMP
nsTextEncoder::SetWrapColumn(PRUint32 aWC)
{
mWrapColumn = aWC;
return NS_OK;
}
NS_IMETHODIMP
nsTextEncoder::SetSelection(nsIDOMSelection* aSelection)
{
mSelection = aSelection;
return NS_OK;
}
NS_IMETHODIMP
nsTextEncoder::SetCharset(const nsString& aCharset)
{
mCharset = aCharset;
return NS_OK;
}
NS_IMETHODIMP
nsTextEncoder::EncodeToString(nsString& aOutputString)
{
nsresult rv;
if (!mDocument)
return NS_ERROR_NOT_INITIALIZED;
// xxx Also make sure mString is a mime type "text/html" or "text/plain"
if (mDocument)
{
nsString buffer;
if (mMimeType.EqualsWithConversion("text/xif"))
{
mDocument->CreateXIF(aOutputString, mSelection);
return NS_OK;
}
mDocument->CreateXIF(buffer, mSelection);
nsIParser* parser;
rv = nsComponentManager::CreateInstance(kCParserCID,
nsnull,
kCParserIID,
(void **)&parser);
if (NS_SUCCEEDED(rv))
{
nsIHTMLContentSink* sink = nsnull;
if (mMimeType.EqualsWithConversion("text/html"))
rv = NS_New_HTML_ContentSinkStream(&sink, &aOutputString, mFlags);
else // default to text/plain
rv = NS_New_HTMLToTXT_SinkStream(&sink, &aOutputString,
mWrapColumn, mFlags);
if (sink && NS_SUCCEEDED(rv))
{
parser->SetContentSink(sink);
nsIDTD* dtd = nsnull;
rv = NS_NewXIFDTD(&dtd);
if (NS_SUCCEEDED(rv))
{
parser->RegisterDTD(dtd);
parser->Parse(buffer, 0, NS_ConvertToString("text/xif"), PR_FALSE, PR_TRUE);
}
NS_IF_RELEASE(dtd);
NS_IF_RELEASE(sink);
}
NS_RELEASE(parser);
}
}
return rv;
}
NS_IMETHODIMP
nsTextEncoder::EncodeToStream(nsIOutputStream* aStream)
{
nsresult rv;
if (!mDocument)
return NS_ERROR_NOT_INITIALIZED;
// xxx Also make sure mString is a mime type "text/html" or "text/plain"
if (mDocument)
{
nsString buffer;
mDocument->CreateXIF(buffer,mSelection);
nsString* charset = nsnull;
nsAutoString defaultCharset; defaultCharset.AssignWithConversion("ISO-8859-1");
if (!mCharset.EqualsWithConversion("null") && !mCharset.IsEmpty())
charset = &mCharset;
nsIParser* parser;
rv = nsComponentManager::CreateInstance(kCParserCID,
nsnull,
kCParserIID,
(void **)&parser);
if (NS_SUCCEEDED(rv)) {
nsIHTMLContentSink* sink = nsnull;
if (mMimeType.EqualsWithConversion("text/html"))
rv = NS_New_HTML_ContentSinkStream(&sink, aStream, charset, mFlags);
else
rv = NS_New_HTMLToTXT_SinkStream(&sink, aStream, charset,
mWrapColumn, mFlags);
if (NS_SUCCEEDED(rv))
{
parser->SetContentSink(sink);
nsIDTD* dtd = nsnull;
rv = NS_NewXIFDTD(&dtd);
if (NS_SUCCEEDED(rv))
{
parser->RegisterDTD(dtd);
parser->Parse(buffer, 0, NS_ConvertToString("text/xif"), PR_FALSE, PR_TRUE);
}
NS_IF_RELEASE(dtd);
NS_IF_RELEASE(sink);
}
NS_RELEASE(parser);
}
}
return rv;
}
nsresult
NS_NewTextEncoder(nsIDocumentEncoder** aResult)
{
*aResult = new nsTextEncoder;
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}
class nsDocumentEncoderFactory : public nsIFactory
{
public:
nsDocumentEncoderFactory();
virtual ~nsDocumentEncoderFactory();
// nsISupports methods
NS_DECL_ISUPPORTS
NS_IMETHOD CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult);
};
MOZ_DECL_CTOR_COUNTER(nsDocumentEncoderFactory);
nsDocumentEncoderFactory::nsDocumentEncoderFactory()
{
MOZ_COUNT_CTOR(nsDocumentEncoderFactory);
mRefCnt = 0;
}
nsDocumentEncoderFactory::~nsDocumentEncoderFactory()
{
MOZ_COUNT_DTOR(nsDocumentEncoderFactory);
}
NS_IMPL_ADDREF(nsDocumentEncoderFactory)
NS_IMPL_RELEASE(nsDocumentEncoderFactory)
nsresult nsDocumentEncoderFactory::QueryInterface(REFNSIID aIID,
void **aInstancePtr)
{
if (nsnull == aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = 0;
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void *)(nsISupports*)this;
} else if (aIID.Equals(kIFactoryIID)) {
*aInstancePtr = (void *)(nsIFactory*)this;
}
if (nsnull == *aInstancePtr)
return NS_NOINTERFACE;
NS_ADDREF_THIS();
return NS_OK;
}
nsresult
nsDocumentEncoderFactory::CreateInstance(nsISupports *aOuter,
REFNSIID aIID,
void **aResult)
{
if (!aResult)
return NS_ERROR_NULL_POINTER;
*aResult = 0;
if (aIID.Equals(kCTextEncoderCID))
*aResult = new nsTextEncoder;
else
return NS_NOINTERFACE;
if (*aResult == NULL)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}

View File

@@ -0,0 +1,471 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.h"
#include "nsIContent.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIScriptObjectOwner.h"
#include "nsGenericElement.h"
#include "nsINameSpaceManager.h"
#include "nsINodeInfo.h"
#include "nsNodeInfoManager.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsDOMError.h"
static NS_DEFINE_IID(kIDOMDocumentFragmentIID, NS_IDOMDOCUMENTFRAGMENT_IID);
static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID);
class nsDocumentFragment : public nsIContent,
public nsIDOMDocumentFragment,
public nsIScriptObjectOwner
{
public:
nsDocumentFragment(nsIDocument* aOwnerDocument, nsINodeInfo *aNodeInfo);
virtual ~nsDocumentFragment();
// nsISupports
NS_DECL_ISUPPORTS
// interface nsIDOMDocumentFragment
NS_IMETHOD GetNodeName(nsString& aNodeName);
NS_IMETHOD GetNodeValue(nsString& aNodeValue);
NS_IMETHOD SetNodeValue(const nsString& aNodeValue);
NS_IMETHOD GetNodeType(PRUint16* aNodeType);
NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode)
{
*aParentNode = nsnull;
return NS_OK;
}
NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes)
{ return mInner.GetChildNodes(aChildNodes); }
NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild)
{ return mInner.GetFirstChild(aFirstChild); }
NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild)
{ return mInner.GetLastChild(aLastChild); }
NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling)
{
*aPreviousSibling = nsnull;
return NS_OK;
}
NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling)
{
*aNextSibling = nsnull;
return NS_OK;
}
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes)
{
*aAttributes = nsnull;
return NS_OK;
}
NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument);
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
nsIDOMNode** aReturn)
{ return mInner.InsertBefore(aNewChild, aRefChild, aReturn); }
NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
nsIDOMNode** aReturn)
{ return mInner.ReplaceChild(aNewChild, aOldChild, aReturn); }
NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{ return mInner.RemoveChild(aOldChild, aReturn); }
NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
{ return mInner.AppendChild(aNewChild, aReturn); }
NS_IMETHOD HasChildNodes(PRBool* aReturn)
{ return mInner.HasChildNodes(aReturn); }
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
NS_IMETHOD GetPrefix(nsString& aPrefix);
NS_IMETHOD SetPrefix(const nsString& aPrefix);
NS_IMETHOD GetNamespaceURI(nsString& aNamespaceURI);
NS_IMETHOD GetLocalName(nsString& aLocalName);
NS_IMETHOD Normalize();
NS_IMETHOD Supports(const nsString& aFeature, const nsString& aVersion,
PRBool* aReturn);
// interface nsIScriptObjectOwner
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void* aScriptObject);
// interface nsIContent
NS_IMETHOD ParseAttributeString(const nsString& aStr,
nsIAtom*& aName,
PRInt32& aNameSpaceID)
{ aName = nsnull;
aNameSpaceID = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID,
nsIAtom*& aPrefix)
{
aPrefix = nsnull;
return NS_OK;
}
NS_IMETHOD GetDocument(nsIDocument*& aResult) const
{ return mInner.GetDocument(aResult); }
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep, PRBool aCompileEventHandlers)
{ return mInner.SetDocument(aDocument, aDeep, aCompileEventHandlers); }
NS_IMETHOD GetParent(nsIContent*& aResult) const
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD SetParent(nsIContent* aParent)
{ return NS_OK; }
NS_IMETHOD GetNameSpaceID(PRInt32& aResult) const
{
aResult = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD GetTag(nsIAtom*& aResult) const
{
aResult = nsnull;
return NS_OK;
}
NS_IMETHOD GetNodeInfo(nsINodeInfo*& aResult) const
{
aResult = nsnull;
return NS_OK;
}
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& aIndex) const
{ return mInner.IndexOf(aPossibleChild, aIndex); }
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 SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsString& aValue,
PRBool aNotify)
{ return NS_OK; }
NS_IMETHOD SetAttribute(nsINodeInfo* aNodeInfo,
const nsString& aValue,
PRBool aNotify)
{ return NS_OK; }
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
nsString& aResult) const
{ return NS_CONTENT_ATTR_NOT_THERE; }
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom*& aPrefix, nsString& aResult) const
{ return NS_CONTENT_ATTR_NOT_THERE; }
NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify)
{ return NS_OK; }
NS_IMETHOD GetAttributeNameAt(PRInt32 aIndex,
PRInt32& aNameSpaceID,
nsIAtom*& aName,
nsIAtom*& aPrefix) const
{
aName = nsnull;
aPrefix = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHOD GetAttributeCount(PRInt32& aCountResult) const
{
aCountResult = 0;
return NS_OK;
}
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0) const
{ return mInner.List(out, aIndent); }
NS_IMETHOD DumpContent(FILE* out = stdout, PRInt32 aIndent = 0,PRBool aDumpAll=PR_TRUE) const
{
return mInner.DumpContent(out, aIndent,aDumpAll);
}
NS_IMETHOD BeginConvertToXIF(nsIXIFConverter* aConverter) const
{ return NS_OK; }
NS_IMETHOD ConvertContentToXIF(nsIXIFConverter* aConverter) const
{ return NS_OK; }
NS_IMETHOD FinishConvertToXIF(nsIXIFConverter* aConverter) const
{ return NS_OK; }
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus)
{
NS_ENSURE_ARG_POINTER(aEventStatus);
*aEventStatus = nsEventStatus_eIgnore;
return NS_OK;
}
NS_IMETHOD GetContentID(PRUint32* aID) {
*aID = 0;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHOD SetContentID(PRUint32 aID) {
return NS_ERROR_NOT_IMPLEMENTED;
}
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); }
NS_IMETHOD SetFocus(nsIPresContext* aContext) {
return mInner.SetFocus(aContext);
}
NS_IMETHOD RemoveFocus(nsIPresContext* aContext) {
return mInner.RemoveFocus(aContext);
}
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const {
if (!aResult) {
return NS_ERROR_NULL_POINTER;
}
#ifdef DEBUG
*aResult = sizeof(*this);
#else
*aResult = 0;
#endif
return NS_OK;
}
protected:
nsGenericContainerElement mInner;
void* mScriptObject;
nsIDocument* mOwnerDocument;
};
nsresult
NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
nsIDocument* aOwnerDocument)
{
NS_ENSURE_ARG_POINTER(aInstancePtrResult);
nsCOMPtr<nsINodeInfoManager> nimgr;
nsCOMPtr<nsINodeInfo> nodeInfo;
nsresult rv;
if (aOwnerDocument) {
rv = aOwnerDocument->GetNodeInfoManager(*getter_AddRefs(nimgr));
} else {
rv = nsNodeInfoManager::GetAnonymousManager(*getter_AddRefs(nimgr));
}
NS_ENSURE_SUCCESS(rv, rv);
rv = nimgr->GetNodeInfo(NS_ConvertASCIItoUCS2("#document-fragment"),
nsnull, kNameSpaceID_None,
*getter_AddRefs(nodeInfo));
NS_ENSURE_SUCCESS(rv, rv);
nsDocumentFragment* it = new nsDocumentFragment(aOwnerDocument, nodeInfo);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIDOMDocumentFragmentIID,
(void**) aInstancePtrResult);
}
nsDocumentFragment::nsDocumentFragment(nsIDocument* aOwnerDocument,
nsINodeInfo *aNodeInfo)
{
NS_INIT_REFCNT();
mInner.Init(this, aNodeInfo);
mScriptObject = nsnull;
mOwnerDocument = aOwnerDocument;
NS_IF_ADDREF(mOwnerDocument);
}
nsDocumentFragment::~nsDocumentFragment()
{
NS_IF_RELEASE(mOwnerDocument);
}
NS_IMPL_ADDREF(nsDocumentFragment)
NS_IMPL_RELEASE(nsDocumentFragment)
nsresult
nsDocumentFragment::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (aIID.Equals(kISupportsIID)) {
nsIDOMDocumentFragment* tmp = this;
nsISupports* tmp2 = tmp;
*aInstancePtr = (void*) tmp2;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMDocumentFragmentIID)) {
nsIDOMDocumentFragment* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMNodeIID)) {
nsIDOMDocumentFragment* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
nsIScriptObjectOwner* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIContentIID)) {
nsIContent* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsDocumentFragment::GetNodeName(nsString& aNodeName)
{
aNodeName.AssignWithConversion("#document-fragment");
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::GetNodeValue(nsString& aNodeValue)
{
aNodeValue.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::SetNodeValue(const nsString& aNodeValue)
{
// The node value can't be modified
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
}
NS_IMETHODIMP
nsDocumentFragment::GetNodeType(PRUint16* aNodeType)
{
*aNodeType = (PRUint16)nsIDOMNode::DOCUMENT_FRAGMENT_NODE;
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
{
if (nsnull != mOwnerDocument) {
return mOwnerDocument->QueryInterface(kIDOMDocumentIID, (void **)aOwnerDocument);
}
else {
*aOwnerDocument = nsnull;
return NS_OK;
}
}
NS_IMETHODIMP
nsDocumentFragment::GetNamespaceURI(nsString& aNamespaceURI)
{
aNamespaceURI.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::GetPrefix(nsString& aPrefix)
{
aPrefix.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::SetPrefix(const nsString& aPrefix)
{
return NS_ERROR_DOM_NAMESPACE_ERR;
}
NS_IMETHODIMP
nsDocumentFragment::GetLocalName(nsString& aLocalName)
{
return GetNodeName(aLocalName);
}
NS_IMETHODIMP
nsDocumentFragment::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
{
nsDocumentFragment* it;
it = new nsDocumentFragment(mOwnerDocument, mInner.mNodeInfo);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
//XXX mInner.CopyInnerTo(this, &it->mInner);
return it->QueryInterface(kIDOMNodeIID, (void**) aReturn);
}
NS_IMETHODIMP
nsDocumentFragment::Normalize()
{
// Nothing to do here yet
return NS_OK;
}
NS_IMETHODIMP
nsDocumentFragment::Supports(const nsString& aFeature, const nsString& aVersion,
PRBool* aReturn)
{
return nsGenericElement::InternalSupports(aFeature, aVersion, aReturn);
}
NS_IMETHODIMP
nsDocumentFragment::GetScriptObject(nsIScriptContext* aContext,
void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = mInner.GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptDocumentFragment(aContext,
(nsISupports*)(nsIDOMDocumentFragment*)this,
mOwnerDocument,
(void**)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
nsDocumentFragment::SetScriptObject(void* aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,615 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsFrameImageLoader.h"
#include "nsIPresShell.h"
#include "nsIViewManager.h"
#include "nsIView.h"
#include "nsIFrame.h"
#include "nsIURL.h"
#include "nsIImageGroup.h"
#include "nsIImageRequest.h"
#include "nsIStyleContext.h"
#include "nsCOMPtr.h"
#include "nsIDeviceContext.h"
#ifdef DEBUG
#undef NOISY_IMAGE_LOADING
#else
#undef NOISY_IMAGE_LOADING
#endif
static NS_DEFINE_IID(kIFrameImageLoaderIID, NS_IFRAME_IMAGE_LOADER_IID);
static NS_DEFINE_IID(kIImageRequestObserverIID, NS_IIMAGEREQUESTOBSERVER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
NS_LAYOUT nsresult
NS_NewFrameImageLoader(nsIFrameImageLoader** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
nsFrameImageLoader* it = new nsFrameImageLoader();
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIFrameImageLoaderIID, (void**) aResult);
}
nsFrameImageLoader::nsFrameImageLoader()
: mPresContext(nsnull),
mImageRequest(nsnull),
mImage(nsnull),
mHaveBackgroundColor(PR_FALSE),
mHaveDesiredSize(PR_FALSE),
mBackgroundColor(0),
mDesiredSize(0, 0),
mImageLoadStatus(NS_IMAGE_LOAD_STATUS_NONE),
mImageLoadError( nsImageError(-1) ),
mNotifyLockCount(0),
mFrames(nsnull)
{
NS_INIT_REFCNT();
}
nsFrameImageLoader::~nsFrameImageLoader()
{
PerFrameData* pfd = mFrames;
while (nsnull != pfd) {
PerFrameData* next = pfd->mNext;
delete pfd;
pfd = next;
}
NS_IF_RELEASE(mImageRequest);
NS_IF_RELEASE(mPresContext);
NS_IF_RELEASE(mImage);
}
NS_IMPL_ADDREF(nsFrameImageLoader)
NS_IMPL_RELEASE(nsFrameImageLoader)
NS_IMETHODIMP
nsFrameImageLoader::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIFrameImageLoaderIID)) {
nsIFrameImageLoader* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIImageRequestObserverIID)) {
nsIImageRequestObserver* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
nsIFrameImageLoader* tmp1 = this;
nsISupports* tmp2 = tmp1;
*aInstancePtr = (void*) tmp2;
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsFrameImageLoader::Init(nsIPresContext* aPresContext,
nsIImageGroup* aGroup,
const nsString& aURL,
const nscolor* aBackgroundColor,
const nsSize* aDesiredSize,
nsIFrame* aTargetFrame,
nsImageAnimation aAnimationMode,
nsIFrameImageLoaderCB aCallBack,
void* aClosure)
{
NS_PRECONDITION(nsnull != aPresContext, "null ptr");
if (nsnull == aPresContext) {
return NS_ERROR_NULL_POINTER;
}
NS_PRECONDITION(nsnull == mPresContext, "double init");
if (nsnull != mPresContext) {
return NS_ERROR_ALREADY_INITIALIZED;
}
mPresContext = aPresContext;
NS_IF_ADDREF(aPresContext);
mURL = aURL;
if (aBackgroundColor) {
mHaveBackgroundColor = PR_TRUE;
mBackgroundColor = *aBackgroundColor;
}
// Computed desired size, in pixels
nscoord desiredWidth = 0;
nscoord desiredHeight = 0;
if (aDesiredSize) {
mHaveDesiredSize = PR_TRUE;
mDesiredSize = *aDesiredSize;
float t2p,devScale;
nsIDeviceContext *theDC;
aPresContext->GetTwipsToPixels(&t2p);
aPresContext->GetDeviceContext(&theDC);
theDC->GetCanonicalPixelScale(devScale);
NS_RELEASE(theDC);
desiredWidth = NSToCoordRound((mDesiredSize.width * t2p)/devScale);
desiredHeight = NSToCoordRound((mDesiredSize.height * t2p)/devScale);
}
if (nsnull != aTargetFrame) {
PerFrameData* pfd = new PerFrameData;
if (nsnull == pfd) {
return NS_ERROR_OUT_OF_MEMORY;
}
pfd->mFrame = aTargetFrame;
pfd->mCallBack = aCallBack;
pfd->mClosure = aClosure;
pfd->mNext = mFrames;
pfd->mNeedSizeUpdate = PR_TRUE;
mFrames = pfd;
}
// Start image load request
char* cp = aURL.ToNewCString();
mImageRequest = aGroup->GetImage(cp, this, aBackgroundColor,
desiredWidth, desiredHeight, 0);
nsCRT::free(cp);
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::AddFrame(nsIFrame* aFrame,
nsIFrameImageLoaderCB aCallBack,
void* aClosure)
{
PerFrameData* pfd = mFrames;
while (pfd) {
if (pfd->mFrame == aFrame) {
pfd->mCallBack = aCallBack;
pfd->mClosure = aClosure;
return NS_OK;
}
pfd = pfd->mNext;
}
if (nsnull != aFrame) {
pfd = new PerFrameData;
if (nsnull == pfd) {
return NS_ERROR_OUT_OF_MEMORY;
}
pfd->mFrame = aFrame;
pfd->mCallBack = aCallBack;
pfd->mClosure = aClosure;
pfd->mNext = mFrames;
pfd->mNeedSizeUpdate = PR_TRUE;
mFrames = pfd;
if (aCallBack && mPresContext &&
((NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE |
NS_IMAGE_LOAD_STATUS_ERROR) & mImageLoadStatus)) {
// Fire notification callback right away so that caller doesn't
// miss it...
#ifdef NOISY_IMAGE_LOADING
printf("%p: AddFrame: notify frame=%p status=%x\n",
this, pfd->mFrame, mImageLoadStatus);
#endif
(*aCallBack)(mPresContext, this, pfd->mFrame, pfd->mClosure,
mImageLoadStatus);
pfd->mNeedSizeUpdate = PR_FALSE;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::RemoveFrame(nsIFrame* aFrame)
{
PerFrameData** pfdp = &mFrames;
PerFrameData* pfd;
while (nsnull != (pfd = *pfdp)) {
if (pfd->mFrame == aFrame) {
*pfdp = pfd->mNext;
delete pfd;
return NS_OK;
}
pfdp = &pfd->mNext;
}
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::StopImageLoad()
{
#ifdef NOISY_IMAGE_LOADING
printf(" %p: stopping ", this);
fputs(mURL, stdout);
printf("\n");
#endif
if (nsnull != mImageRequest) {
mImageRequest->RemoveObserver(this);
NS_RELEASE(mImageRequest);
}
NS_IF_RELEASE(mPresContext);
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::AbortImageLoad()
{
if (nsnull != mImageRequest) {
mImageRequest->Interrupt();
}
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::IsSameImageRequest(const nsString& aURL,
const nscolor* aBackgroundColor,
const nsSize* aDesiredSize,
PRBool* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
// URL's must match (XXX: not quite right; need real comparison here...)
if (!aURL.Equals(mURL)) {
*aResult = PR_FALSE;
return NS_OK;
}
// XXX Temporary fix to deal with the case of animated
// images that are preloaded. If we've completed the image
// and there aren't any frames associated with it, then we
// interrupted the load of the image. The good things is that
// the image is still in the image cache. The bad thing is that
// we don't share the image loader.
if ((nsnull == mFrames) && (mImageLoadStatus & NS_IMAGE_LOAD_STATUS_IMAGE_READY)) {
*aResult = PR_FALSE;
return NS_OK;
}
// Background colors must match
if (aBackgroundColor) {
if (!mHaveBackgroundColor) {
*aResult = PR_FALSE;
return NS_OK;
}
if (mBackgroundColor != *aBackgroundColor) {
*aResult = PR_FALSE;
return NS_OK;
}
}
else if (mHaveBackgroundColor) {
*aResult = PR_FALSE;
return NS_OK;
}
// Desired sizes must match
if (aDesiredSize) {
if (!mHaveDesiredSize) {
*aResult = PR_FALSE;
return NS_OK;
}
if ((mDesiredSize.width != aDesiredSize->width) ||
(mDesiredSize.height != aDesiredSize->height)) {
*aResult = PR_FALSE;
return NS_OK;
}
}
else if (mHaveDesiredSize) {
*aResult = PR_FALSE;
return NS_OK;
}
*aResult = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::SafeToDestroy(PRBool* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = PR_FALSE;
if ((nsnull == mFrames) && (0 == mNotifyLockCount)) {
*aResult = PR_TRUE;
}
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::GetURL(nsString& aResult)
{
aResult = mURL;
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::GetPresContext(nsIPresContext** aPresContext)
{
NS_IF_ADDREF(*aPresContext = mPresContext);
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::GetImage(nsIImage** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = mImage;
NS_IF_ADDREF(mImage);
return NS_OK;
}
// Return the size of the image, in twips
NS_IMETHODIMP
nsFrameImageLoader::GetSize(nsSize& aResult)
{
aResult = mDesiredSize;
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::GetImageLoadStatus(PRUint32* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = mImageLoadStatus;
return NS_OK;
}
NS_IMETHODIMP
nsFrameImageLoader::GetIntrinsicSize(nsSize& aResult)
{
if (mImageRequest) {
PRUint32 width, height;
float p2t;
mImageRequest->GetNaturalDimensions(&width, &height);
mPresContext->GetScaledPixelsToTwips(&p2t);
aResult.width = NSIntPixelsToTwips(width, p2t);
aResult.height = NSIntPixelsToTwips(height, p2t);
} else {
aResult.SizeTo(0, 0);
}
return NS_OK;
}
void
nsFrameImageLoader::Notify(nsIImageRequest *aImageRequest,
nsIImage *aImage,
nsImageNotification aNotificationType,
PRInt32 aParam1, PRInt32 aParam2,
void *aParam3)
{
nsIView* view;
nsRect damageRect;
float p2t;
const nsRect* changeRect;
PerFrameData* pfd;
if (!mPresContext) {
return;
}
mNotifyLockCount++;
#ifdef NOISY_IMAGE_LOADING
printf("%p: loading ", this);
fputs(mURL, stdout);
printf(" notification=%d params=%d,%d,%p\n", aNotificationType,
aParam1, aParam2, aParam3);
#endif
switch (aNotificationType) {
case nsImageNotification_kDimensions:
mPresContext->GetScaledPixelsToTwips(&p2t);
mDesiredSize.width = NSIntPixelsToTwips(aParam1, p2t);
mDesiredSize.height = NSIntPixelsToTwips(aParam2, p2t);
mImageLoadStatus |= NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE;
NotifyFrames(PR_TRUE);
break;
case nsImageNotification_kPixmapUpdate:
if ((nsnull == mImage) && (nsnull != aImage)) {
mImage = aImage;
NS_ADDREF(aImage);
}
mImageLoadStatus |= NS_IMAGE_LOAD_STATUS_IMAGE_READY;
// Convert the rect from pixels to twips
mPresContext->GetScaledPixelsToTwips(&p2t);
changeRect = (const nsRect*) aParam3;
damageRect.x = NSIntPixelsToTwips(changeRect->x, p2t);
damageRect.y = NSIntPixelsToTwips(changeRect->y, p2t);
damageRect.width = NSIntPixelsToTwips(changeRect->width, p2t);
damageRect.height = NSIntPixelsToTwips(changeRect->height, p2t);
DamageRepairFrames(&damageRect);
break;
case nsImageNotification_kImageComplete:
// XXX Temporary fix to deal with the case of animated
// images that are preloaded. If there are no frames
// registered, then stop loading this image.
if (nsnull == mFrames) {
AbortImageLoad();
}
if ((nsnull == mImage) && (nsnull != aImage)) {
mImage = aImage;
NS_ADDREF(aImage);
mImageLoadStatus |= NS_IMAGE_LOAD_STATUS_IMAGE_READY;
DamageRepairFrames(nsnull);
}
NotifyFrames(PR_FALSE);
break;
case nsImageNotification_kFrameComplete:
// New frame of a GIF animation
// XXX Image library sends this for all images, and not just for animated
// images. You bastards. It's a waste to re-draw the image if it's not an
// animated image, but unfortunately we don't currently have a way to tell
// whether the image is animated
if (mImage) {
DamageRepairFrames(nsnull);
}
break;
case nsImageNotification_kIsTransparent:
// Mark the frame's view as having transparent areas
// XXX this is pretty vile; change this so that we set another frame status bit and then pass on a notification *or* lets just start passing on the notifications directly to the frames and eliminate all of this code.
pfd = mFrames;
while (pfd) {
pfd->mFrame->GetView(mPresContext, &view);
if (view) {
view->SetContentTransparency(PR_TRUE);
}
pfd = pfd->mNext;
}
break;
case nsImageNotification_kAborted:
// Treat this like an error
mImageLoadError = nsImageError_kNoData;
mImageLoadStatus |= NS_IMAGE_LOAD_STATUS_ERROR;
NotifyFrames(PR_FALSE);
break;
default:
break;
}
mNotifyLockCount--;
}
void
nsFrameImageLoader::NotifyError(nsIImageRequest *aImageRequest,
nsImageError aErrorType)
{
mNotifyLockCount++;
mImageLoadError = aErrorType;
mImageLoadStatus |= NS_IMAGE_LOAD_STATUS_ERROR;
NotifyFrames(PR_FALSE);
mNotifyLockCount--;
}
void
nsFrameImageLoader::NotifyFrames(PRBool aIsSizeUpdate)
{
PerFrameData* pfd = mFrames;
while (nsnull != pfd) {
if ((aIsSizeUpdate && pfd->mNeedSizeUpdate) || !aIsSizeUpdate) {
if (pfd->mCallBack) {
#ifdef NOISY_IMAGE_LOADING
printf(" notify frame=%p status=%x\n", pfd->mFrame, mImageLoadStatus);
#endif
(*pfd->mCallBack)(mPresContext, this, pfd->mFrame, pfd->mClosure,
mImageLoadStatus);
}
if (aIsSizeUpdate) {
pfd->mNeedSizeUpdate = PR_FALSE;
}
}
pfd = pfd->mNext;
}
}
void
nsFrameImageLoader::DamageRepairFrames(const nsRect* aDamageRect)
{
// Determine damaged area and tell view manager to redraw it
nsPoint offset;
nsRect bounds;
nsIView* view;
PerFrameData* pfd = mFrames;
while (nsnull != pfd) {
nsIFrame* frame = pfd->mFrame;
// NOTE: It is not sufficient to invalidate only the size of the image:
// the image may be tiled!
// The best option is to call into the frame, however lacking this
// we have to at least invalidate the frame's bounds, hence
// as long as we have a frame we'll use its size.
//
// XXX - Add a NotifyImageLoaded to nsIFrame and call that, passing the
// damage rect (image size)
NS_ASSERTION(frame, "Frame should not be null and be remembered");
if (frame) {
// Invalidate the entire frame
// XXX We really only need to invalidate the client area of the frame...
frame->GetRect(bounds);
bounds.x = bounds.y = 0;
}
else {
// aDamageRect represents the part of the content area that
// needs updating.
bounds = *aDamageRect;
// Offset damage origin by border/padding
// XXX This is pretty sleazy. See the XXX remark below...
const nsStyleSpacing* space;
nsMargin borderPadding;
frame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)space);
space->CalcBorderPaddingFor(frame, borderPadding);
bounds.MoveBy(borderPadding.left, borderPadding.top);
}
// XXX We should tell the frame the damage area and let it invalidate
// itself. Add some API calls to nsIFrame to allow a caller to invalidate
// parts of the frame...
frame->GetView(mPresContext, &view);
if (nsnull == view) {
frame->GetOffsetFromView(mPresContext, offset, &view);
bounds.x += offset.x;
bounds.y += offset.y;
}
nsCOMPtr<nsIViewManager> vm = nsnull;
nsresult rv = NS_OK;
rv = view->GetViewManager(*getter_AddRefs(vm));
if (NS_SUCCEEDED(rv) && nsnull != vm) {
vm->UpdateView(view, bounds, NS_VMREFRESH_NO_SYNC);
}
pfd = pfd->mNext;
}
}

View File

@@ -0,0 +1,135 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsFrameImageLoader_h___
#define nsFrameImageLoader_h___
#include "nsSize.h"
#include "nsString.h"
#include "nsVoidArray.h"
#include "nsIFrameImageLoader.h"
#include "nsIPresContext.h"
#include "nsIImageObserver.h"
struct nsRect;
/**
* An image loader for frame's.
*/
class nsFrameImageLoader : public nsIFrameImageLoader,
public nsIImageRequestObserver
{
public:
// nsISupports
NS_DECL_ISUPPORTS
// nsIImageRequestObserver
virtual void Notify(nsIImageRequest *aImageRequest,
nsIImage *aImage,
nsImageNotification aNotificationType,
PRInt32 aParam1, PRInt32 aParam2,
void *aParam3);
virtual void NotifyError(nsIImageRequest *aImageRequest,
nsImageError aErrorType);
// nsFrameImageLoader API
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIImageGroup* aGroup,
const nsString& aURL,
const nscolor* aBackgroundColor,
const nsSize* aDesiredSize,
nsIFrame* aTargetFrame,
nsImageAnimation aAnimationMode,
nsIFrameImageLoaderCB aCallBack,
void* aClosure);
NS_IMETHOD StopImageLoad();
NS_IMETHOD AbortImageLoad();
NS_IMETHOD IsSameImageRequest(const nsString& aURL,
const nscolor* aBackgroundColor,
const nsSize* aDesiredSize,
PRBool* aResult);
NS_IMETHOD AddFrame(nsIFrame* aFrame, nsIFrameImageLoaderCB aCallBack,
void* aClosure);
NS_IMETHOD RemoveFrame(nsIFrame* aFrame);
// See if its safe to destroy this image loader. Its safe if there
// are no more frames using the loader and we aren't in the middle
// of processing a callback.
NS_IMETHOD SafeToDestroy(PRBool* aResult);
NS_IMETHOD GetURL(nsString& aResult);
NS_IMETHOD GetPresContext(nsIPresContext** aPresContext);
NS_IMETHOD GetImage(nsIImage** aResult);
// Return the size of the image, in twips
NS_IMETHOD GetSize(nsSize& aResult);
NS_IMETHOD GetImageLoadStatus(PRUint32* aLoadStatus);
NS_IMETHOD GetIntrinsicSize(nsSize& aResult);
protected:
nsFrameImageLoader();
virtual ~nsFrameImageLoader();
void DamageRepairFrames(const nsRect* aDamageRect);
void NotifyFrames(PRBool aIsSizeUpdate);
nsIPresContext* mPresContext;
nsIImageRequest* mImageRequest;
nsIImage* mImage;
PRPackedBool mHaveBackgroundColor;
PRPackedBool mHaveDesiredSize;
nsString mURL;
nscolor mBackgroundColor;
nsSize mDesiredSize;
nsSize mImageSize;
PRUint32 mImageLoadStatus;
nsImageError mImageLoadError;
PRInt32 mNotifyLockCount;
struct PerFrameData {
PerFrameData* mNext;
nsIFrame* mFrame;
nsIFrameImageLoaderCB mCallBack;
void* mClosure;
PRBool mNeedSizeUpdate;
};
PerFrameData* mFrames;
friend NS_LAYOUT nsresult NS_NewFrameImageLoader(nsIFrameImageLoader**);
};
extern NS_LAYOUT nsresult
NS_NewFrameImageLoader(nsIFrameImageLoader** aInstancePtrResult);
#endif /* nsFrameImageLoader_h___ */

View File

@@ -0,0 +1,378 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsFrameList.h"
#ifdef NS_DEBUG
#include "nsIFrameDebug.h"
#endif
void
nsFrameList::DestroyFrames(nsIPresContext* aPresContext)
{
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* next;
frame->GetNextSibling(&next);
frame->Destroy(aPresContext);
mFirstChild = frame = next;
}
}
void
nsFrameList::AppendFrames(nsIFrame* aParent, nsIFrame* aFrameList)
{
NS_PRECONDITION(nsnull != aFrameList, "null ptr");
if (nsnull != aFrameList) {
nsIFrame* lastChild = LastChild();
if (nsnull == lastChild) {
mFirstChild = aFrameList;
}
else {
lastChild->SetNextSibling(aFrameList);
}
if (nsnull != aParent) {
nsIFrame* frame = aFrameList;
while (nsnull != frame) {
frame->SetParent(aParent);
frame->GetNextSibling(&frame);
}
}
}
}
void
nsFrameList::AppendFrame(nsIFrame* aParent, nsIFrame* aFrame)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (nsnull != aFrame) {
nsIFrame* lastChild = LastChild();
if (nsnull == lastChild) {
mFirstChild = aFrame;
}
else {
lastChild->SetNextSibling(aFrame);
}
if (nsnull != aParent) {
aFrame->SetParent(aParent);
}
}
}
PRBool
nsFrameList::RemoveFrame(nsIFrame* aFrame)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (nsnull != aFrame) {
nsIFrame* nextFrame;
aFrame->GetNextSibling(&nextFrame);
aFrame->SetNextSibling(nsnull);
if (aFrame == mFirstChild) {
mFirstChild = nextFrame;
return PR_TRUE;
}
else {
nsIFrame* prevSibling = GetPrevSiblingFor(aFrame);
if (nsnull != prevSibling) {
prevSibling->SetNextSibling(nextFrame);
return PR_TRUE;
}
}
}
return PR_FALSE;
}
PRBool
nsFrameList::RemoveFirstChild()
{
if (nsnull != mFirstChild) {
nsIFrame* nextFrame;
mFirstChild->GetNextSibling(&nextFrame);
mFirstChild->SetNextSibling(nsnull);
mFirstChild = nextFrame;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsFrameList::DestroyFrame(nsIPresContext* aPresContext, nsIFrame* aFrame)
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (RemoveFrame(aFrame)) {
aFrame->Destroy(aPresContext);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsFrameList::InsertFrame(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aNewFrame)
{
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if (nsnull != aNewFrame) {
if (nsnull == aPrevSibling) {
aNewFrame->SetNextSibling(mFirstChild);
mFirstChild = aNewFrame;
}
else {
nsIFrame* nextFrame;
aPrevSibling->GetNextSibling(&nextFrame);
aPrevSibling->SetNextSibling(aNewFrame);
aNewFrame->SetNextSibling(nextFrame);
}
if (nsnull != aParent) {
aNewFrame->SetParent(aParent);
}
}
}
void
nsFrameList::InsertFrames(nsIFrame* aParent,
nsIFrame* aPrevSibling,
nsIFrame* aFrameList)
{
NS_PRECONDITION(nsnull != aFrameList, "null ptr");
if (nsnull != aFrameList) {
nsIFrame* lastNewFrame = nsnull;
if (nsnull != aParent) {
nsIFrame* frame = aFrameList;
while (nsnull != frame) {
frame->SetParent(aParent);
lastNewFrame = frame;
frame->GetNextSibling(&frame);
}
}
// Get the last new frame if necessary
if (!lastNewFrame) {
nsFrameList tmp(aFrameList);
lastNewFrame = tmp.LastChild();
}
// Link the new frames into the child list
if (nsnull == aPrevSibling) {
lastNewFrame->SetNextSibling(mFirstChild);
mFirstChild = aFrameList;
}
else {
nsIFrame* nextFrame;
aPrevSibling->GetNextSibling(&nextFrame);
aPrevSibling->SetNextSibling(aFrameList);
lastNewFrame->SetNextSibling(nextFrame);
}
}
}
PRBool
nsFrameList::ReplaceFrame(nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame)
{
NS_PRECONDITION(nsnull != aOldFrame, "null ptr");
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if ((nsnull != aOldFrame) && (nsnull != aNewFrame)) {
nsIFrame* nextFrame;
aOldFrame->GetNextSibling(&nextFrame);
if (aOldFrame == mFirstChild) {
mFirstChild = aNewFrame;
aNewFrame->SetNextSibling(nextFrame);
}
else {
nsIFrame* prevSibling = GetPrevSiblingFor(aOldFrame);
if (nsnull != prevSibling) {
prevSibling->SetNextSibling(aNewFrame);
aNewFrame->SetNextSibling(nextFrame);
}
}
if (nsnull != aParent) {
aNewFrame->SetParent(aParent);
}
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsFrameList::ReplaceAndDestroyFrame(nsIPresContext* aPresContext,
nsIFrame* aParent,
nsIFrame* aOldFrame,
nsIFrame* aNewFrame)
{
NS_PRECONDITION(nsnull != aOldFrame, "null ptr");
NS_PRECONDITION(nsnull != aNewFrame, "null ptr");
if (ReplaceFrame(aParent, aOldFrame, aNewFrame)) {
aNewFrame->Destroy(aPresContext);
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsFrameList::Split(nsIFrame* aAfterFrame, nsIFrame** aNextFrameResult)
{
NS_PRECONDITION(nsnull != aAfterFrame, "null ptr");
NS_PRECONDITION(nsnull != aNextFrameResult, "null ptr");
NS_ASSERTION(ContainsFrame(aAfterFrame), "split after unknown frame");
if ((nsnull != aNextFrameResult) && (nsnull != aAfterFrame)) {
nsIFrame* nextFrame;
aAfterFrame->GetNextSibling(&nextFrame);
aAfterFrame->SetNextSibling(nsnull);
*aNextFrameResult = nextFrame;
return PR_TRUE;
}
return PR_FALSE;
}
nsIFrame*
nsFrameList::PullFrame(nsIFrame* aParent,
nsIFrame* aLastChild,
nsFrameList& aFromList)
{
NS_PRECONDITION(nsnull != aParent, "null ptr");
nsIFrame* pulledFrame = nsnull;
if (nsnull != aParent) {
pulledFrame = aFromList.FirstChild();
if (nsnull != pulledFrame) {
// Take frame off old list
aFromList.RemoveFirstChild();
// Put it on the end of this list
if (nsnull == aLastChild) {
NS_ASSERTION(nsnull == mFirstChild, "bad aLastChild");
mFirstChild = pulledFrame;
}
else {
aLastChild->SetNextSibling(pulledFrame);
}
pulledFrame->SetParent(aParent);
}
}
return pulledFrame;
}
nsIFrame*
nsFrameList::LastChild() const
{
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* next;
frame->GetNextSibling(&next);
if (nsnull == next) {
break;
}
frame = next;
}
return frame;
}
nsIFrame*
nsFrameList::FrameAt(PRInt32 aIndex) const
{
NS_PRECONDITION(aIndex >= 0, "invalid arg");
if (aIndex < 0) return nsnull;
nsIFrame* frame = mFirstChild;
while ((aIndex-- > 0) && (nsnull != frame)) {
frame->GetNextSibling(&frame);
}
return frame;
}
PRBool
nsFrameList::ContainsFrame(const nsIFrame* aFrame) const
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
if (frame == aFrame) {
return PR_TRUE;
}
frame->GetNextSibling(&frame);
}
return PR_FALSE;
}
PRInt32
nsFrameList::GetLength() const
{
PRInt32 count = 0;
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
count++;
frame->GetNextSibling(&frame);
}
return count;
}
nsIFrame*
nsFrameList::GetPrevSiblingFor(nsIFrame* aFrame) const
{
NS_PRECONDITION(nsnull != aFrame, "null ptr");
if (aFrame == mFirstChild) {
return nsnull;
}
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* next;
frame->GetNextSibling(&next);
if (next == aFrame) {
break;
}
frame = next;
}
return frame;
}
void
nsFrameList::VerifyParent(nsIFrame* aParent) const
{
#ifdef NS_DEBUG
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrame* parent;
frame->GetParent(&parent);
NS_ASSERTION(parent == aParent, "bad parent");
frame->GetNextSibling(&frame);
}
#endif
}
#ifdef NS_DEBUG
void
nsFrameList::List(nsIPresContext* aPresContext, FILE* out) const
{
fputs("<\n", out);
nsIFrame* frame = mFirstChild;
while (nsnull != frame) {
nsIFrameDebug* frameDebug;
if (NS_SUCCEEDED(frame->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) {
frameDebug->List(aPresContext, out, 1);
}
frame->GetNextSibling(&frame);
}
fputs(">\n", out);
}
#endif

View File

@@ -0,0 +1,323 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsCOMPtr.h"
#include "nsLayoutAtoms.h"
#include "nsFrameTraversal.h"
#include "nsFrameList.h"
static NS_DEFINE_IID(kIEnumeratorIID, NS_IENUMERATOR_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
class nsFrameIterator: public nsIBidirectionalEnumerator
{
public:
NS_DECL_ISUPPORTS
NS_IMETHOD First();
NS_IMETHOD Last();
NS_IMETHOD Next()=0;
NS_IMETHOD Prev()=0;
NS_IMETHOD CurrentItem(nsISupports **aItem);
NS_IMETHOD IsDone();//what does this mean??off edge? yes
nsFrameIterator();
protected:
void setCurrent(nsIFrame *aFrame){mCurrent = aFrame;}
nsIFrame *getCurrent(){return mCurrent;}
void setStart(nsIFrame *aFrame){mStart = aFrame;}
nsIFrame *getStart(){return mStart;}
nsIFrame *getLast(){return mLast;}
void setLast(nsIFrame *aFrame){mLast = aFrame;}
PRInt8 getOffEdge(){return mOffEdge;}
void setOffEdge(PRInt8 aOffEdge){mOffEdge = aOffEdge;}
private:
nsIFrame *mStart;
nsIFrame *mCurrent;
nsIFrame *mLast; //the last one that was in current;
PRInt8 mOffEdge; //0= no -1 to far prev, 1 to far next;
};
/*
class nsFastFrameIterator: public nsFrameIterator
{
nsFastFrameIterator(nsIFrame *start);
private :
virtual nsresult Next();
virtual nsresult Prev();
}
*/
class nsLeafIterator: public nsFrameIterator
{
public:
nsLeafIterator(nsIPresContext* aPresContext, nsIFrame *start);
void SetExtensive(PRBool aExtensive) {mExtensive = aExtensive;}
PRBool GetExtensive(){return mExtensive;}
private :
NS_IMETHOD Next();
NS_IMETHOD Prev();
nsIPresContext* mPresContext;
PRBool mExtensive;
};
/************IMPLEMENTATIONS**************/
nsresult
NS_NewFrameTraversal(nsIBidirectionalEnumerator **aEnumerator,
nsTraversalType aType,
nsIPresContext* aPresContext,
nsIFrame *aStart)
{
if (!aEnumerator || !aStart)
return NS_ERROR_NULL_POINTER;
switch(aType)
{
case LEAF: {
nsLeafIterator *trav = new nsLeafIterator(aPresContext, aStart);
if (!trav)
return NS_ERROR_OUT_OF_MEMORY;
*aEnumerator = NS_STATIC_CAST(nsIBidirectionalEnumerator*, trav);
NS_ADDREF(trav);
trav->SetExtensive(PR_FALSE);
}
break;
case EXTENSIVE:{
nsLeafIterator *trav = new nsLeafIterator(aPresContext, aStart);
if (!trav)
return NS_ERROR_OUT_OF_MEMORY;
*aEnumerator = NS_STATIC_CAST(nsIBidirectionalEnumerator*, trav);
NS_ADDREF(trav);
trav->SetExtensive(PR_TRUE);
}
break;
#if 0
case FASTEST:{
nsFastestTraversal *trav = new nsFastestTraversal(aStart);
if (!trav)
return NS_ERROR_NOMEMORY;
*aEnumerator = NS_STATIC_CAST(nsIBidirectionalEnumerator*, trav);
NS_ADDREF(trav);
}
#endif
default:
return NS_ERROR_NOT_IMPLEMENTED;
break;
}
return NS_OK;
}
/*********nsFrameIterator************/
NS_IMPL_ISUPPORTS2(nsFrameIterator, nsIEnumerator, nsIBidirectionalEnumerator)
nsFrameIterator::nsFrameIterator()
{
mOffEdge = 0;
mLast = nsnull;
mCurrent = nsnull;
mStart = nsnull;
NS_INIT_REFCNT();
}
NS_IMETHODIMP
nsFrameIterator::CurrentItem(nsISupports **aItem)
{
if (!aItem)
return NS_ERROR_NULL_POINTER;
*aItem = mCurrent;
if (mOffEdge)
return NS_ENUMERATOR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsFrameIterator::IsDone()//what does this mean??off edge? yes
{
if (mOffEdge != 0)
return NS_OK;
return NS_ENUMERATOR_FALSE;
}
NS_IMETHODIMP
nsFrameIterator::First()
{
mCurrent = mStart;
return NS_OK;
}
NS_IMETHODIMP
nsFrameIterator::Last()
{
return NS_ERROR_FAILURE;
}
/*********LEAFITERATOR**********/
nsLeafIterator::nsLeafIterator(nsIPresContext* aPresContext, nsIFrame *aStart)
: mPresContext(aPresContext)
{
setStart(aStart);
setCurrent(aStart);
setLast(aStart);
}
static PRBool
IsRootFrame(nsIFrame* aFrame)
{
nsCOMPtr<nsIAtom>atom;
aFrame->GetFrameType(getter_AddRefs(atom));
return (atom.get() == nsLayoutAtoms::canvasFrame) ||
(atom.get() == nsLayoutAtoms::rootFrame);
}
NS_IMETHODIMP
nsLeafIterator::Next()
{
//recursive-oid method to get next frame
nsIFrame *result = nsnull;
nsIFrame *parent = getCurrent();
if (!parent)
parent = getLast();
if (!mExtensive)
{
while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result)
{
parent = result;
}
}
if (parent != getCurrent())
{
result = parent;
}
else {
while(parent && !IsRootFrame(parent)) {
if (NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){
parent = result;
while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result)
{
parent = result;
}
result = parent;
break;
}
else
{
parent->GetParent(&result);
if (!result || IsRootFrame(result)) {
result = nsnull;
break;
}
else
{
parent = result;
if (mExtensive)
break;
}
}
}
}
setCurrent(result);
if (!result)
setOffEdge(1);
return NS_OK;
}
NS_IMETHODIMP
nsLeafIterator::Prev()
{
//recursive-oid method to get prev frame
nsIFrame *result;
nsIFrame *parent = getCurrent();
if (!parent)
parent = getLast();
while(parent){
nsIFrame *grandParent;
if (NS_SUCCEEDED(parent->GetParent(&grandParent)) && grandParent &&
NS_SUCCEEDED(grandParent->FirstChild(mPresContext, nsnull,&result))){
nsFrameList list(result);
result = list.GetPrevSiblingFor(parent);
if (result){
parent = result;
while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result){
parent = result;
while(NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){
parent = result;
}
}
result = parent;
break;
}
else if (NS_FAILED(parent->GetParent(&result)) || !result){
result = nsnull;
break;
}
else
{
parent = result;
if (mExtensive)
break;
}
}
else{
setLast(parent);
result = nsnull;
break;
}
}
setCurrent(result);
if (!result)
setOffEdge(-1);
return NS_OK;
}

View File

@@ -0,0 +1,637 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIFrameUtil.h"
#include "nsFrame.h"
#include "nsHTMLEntities.h"
#include "nsString.h"
#include "nsRect.h"
#include <stdlib.h>
#include "plstr.h"
static NS_DEFINE_IID(kIFrameUtilIID, NS_IFRAME_UTIL_IID);
#ifdef NS_DEBUG
class nsFrameUtil : public nsIFrameUtil {
public:
nsFrameUtil();
virtual ~nsFrameUtil();
NS_DECL_ISUPPORTS
NS_IMETHOD CompareRegressionData(FILE* aFile1, FILE* aFile2);
NS_IMETHOD DumpRegressionData(FILE* aInputFile, FILE* aOutputFile);
struct Node;
struct Tag;
struct NodeList {
NodeList();
~NodeList();
static void Destroy(NodeList* aLists);
NodeList* next; // for lists of lists
Node* node;
char* name;
};
struct Node {
Node();
~Node();
static void Destroy(Node* aNode);
static Node* Read(FILE* aFile, Tag* aTag);
static Node* ReadTree(FILE* aFile);
Node* next;
char* type;
PRUint32 state;
nsRect bbox;
NodeList* lists;
};
struct Tag {
Tag();
~Tag();
static Tag* Parse(FILE* aFile);
void AddAttr(char* aAttr, char* aValue);
char* GetAttr(char* aAttr);
void ReadAttrs(FILE* aFile);
void ToString(nsString& aResult);
enum Type {
open,
close,
openClose
};
char* name;
Type type;
char** attributes;
PRInt32 num;
PRInt32 size;
char** values;
};
static char* Copy(char* aString);
static void DumpNode(Node* aNode, FILE* aOutputFile, PRInt32 aIndent);
static void DumpTree(Node* aNode, FILE* aOutputFile, PRInt32 aIndent);
static PRBool CompareTrees(Node* aNode1, Node* aNode2);
};
char*
nsFrameUtil::Copy(char* aString)
{
if (aString) {
int l = ::strlen(aString);
char* c = new char[l+1];
memcpy(c, aString, l+1);
return c;
}
return aString;
}
//----------------------------------------------------------------------
nsFrameUtil::NodeList::NodeList()
: next(nsnull), node(nsnull), name(nsnull)
{
}
nsFrameUtil::NodeList::~NodeList()
{
if (nsnull != name) {
delete name;
}
if (nsnull != node) {
Node::Destroy(node);
}
}
void
nsFrameUtil::NodeList::Destroy(NodeList* aLists)
{
while (nsnull != aLists) {
NodeList* next = aLists->next;
delete aLists;
aLists = next;
}
}
//----------------------------------------------------------------------
nsFrameUtil::Node::Node()
: next(nsnull), type(nsnull), state(0), lists(nsnull)
{
}
nsFrameUtil::Node::~Node()
{
if (nsnull != type) {
delete type;
}
if (nsnull != lists) {
NodeList::Destroy(lists);
}
}
void
nsFrameUtil::Node::Destroy(Node* aList)
{
while (nsnull != aList) {
Node* next = aList->next;
delete aList;
aList = next;
}
}
static PRInt32 GetInt(nsFrameUtil::Tag* aTag, char* aAttr)
{
char* value = aTag->GetAttr(aAttr);
if (nsnull != value) {
return PRInt32( atoi(value) );
}
return 0;
}
nsFrameUtil::Node*
nsFrameUtil::Node::ReadTree(FILE* aFile)
{
Tag* tag = Tag::Parse(aFile);
if (nsnull == tag) {
return nsnull;
}
if (PL_strcmp(tag->name, "frame") != 0) {
delete tag;
return nsnull;
}
Node* result = Read(aFile, tag);
fclose(aFile);
return result;
}
nsFrameUtil::Node*
nsFrameUtil::Node::Read(FILE* aFile, Tag* tag)
{
Node* node = new Node;
node->type = Copy(tag->GetAttr("type"));
node->state = GetInt(tag, "state");
delete tag;
for (;;) {
tag = Tag::Parse(aFile);
if (nsnull == tag) break;
if (PL_strcmp(tag->name, "frame") == 0) {
delete tag;
break;
}
if (PL_strcmp(tag->name, "bbox") == 0) {
nscoord x = nscoord( GetInt(tag, "x") );
nscoord y = nscoord( GetInt(tag, "y") );
nscoord w = nscoord( GetInt(tag, "w") );
nscoord h = nscoord( GetInt(tag, "h") );
node->bbox.SetRect(x, y, w, h);
}
else if (PL_strcmp(tag->name, "child-list") == 0) {
NodeList* list = new NodeList();
list->name = Copy(tag->GetAttr("name"));
list->next = node->lists;
node->lists = list;
delete tag;
Node** tailp = &list->node;
for (;;) {
tag = Tag::Parse(aFile);
if (nsnull == tag) {
break;
}
if (PL_strcmp(tag->name, "child-list") == 0) {
break;
}
if (PL_strcmp(tag->name, "frame") != 0) {
break;
}
Node* child = Node::Read(aFile, tag);
if (nsnull == child) {
break;
}
*tailp = child;
tailp = &child->next;
}
}
delete tag;
}
return node;
}
//----------------------------------------------------------------------
nsFrameUtil::Tag::Tag()
: name(nsnull), type(open), attributes(nsnull), num(0), size(0),
values(nsnull)
{
}
nsFrameUtil::Tag::~Tag()
{
PRInt32 i, n = num;
if (0 != n) {
for (i = 0; i < n; i++) {
delete attributes[i];
delete values[i];
}
delete attributes;
delete values;
}
}
void
nsFrameUtil::Tag::AddAttr(char* aAttr, char* aValue)
{
if (num == size) {
PRInt32 newSize = size * 2 + 4;
char** a = new char*[newSize];
char** v = new char*[newSize];
if (0 != num) {
memcpy(a, attributes, num * sizeof(char*));
memcpy(v, values, num * sizeof(char*));
delete attributes;
delete values;
}
attributes = a;
values = v;
size = newSize;
}
attributes[num] = aAttr;
values[num] = aValue;
num = num + 1;
}
char*
nsFrameUtil::Tag::GetAttr(char* aAttr)
{
PRInt32 i, n = num;
for (i = 0; i < n; i++) {
if (PL_strcmp(attributes[i], aAttr) == 0) {
return values[i];
}
}
return nsnull;
}
static inline int IsWhiteSpace(int c) {
return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
}
static PRBool EatWS(FILE* aFile)
{
for (;;) {
int c = getc(aFile);
if (c < 0) {
return PR_FALSE;
}
if (!IsWhiteSpace(c)) {
ungetc(c, aFile);
break;
}
}
return PR_TRUE;
}
static PRBool Expect(FILE* aFile, char aChar)
{
int c = getc(aFile);
if (c < 0) return PR_FALSE;
if (c != aChar) {
ungetc(c, aFile);
return PR_FALSE;
}
return PR_TRUE;
}
static char* ReadIdent(FILE* aFile)
{
char id[1000];
char* ip = id;
char* end = ip + sizeof(id) - 1;
while (ip < end) {
int c = fgetc(aFile);
if (c < 0) return nsnull;
if ((c == '=') || (c == '>') || (c == '/') || IsWhiteSpace(c)) {
ungetc(c, aFile);
break;
}
*ip++ = char(c);
}
*ip = '\0';
return nsFrameUtil::Copy(id);
}
static char* ReadString(FILE* aFile)
{
if (!Expect(aFile, '\"')) {
return nsnull;
}
char id[1000];
char* ip = id;
char* end = ip + sizeof(id) - 1;
while (ip < end) {
int c = fgetc(aFile);
if (c < 0) return nsnull;
if (c == '\"') {
break;
}
*ip++ = char(c);
}
*ip = '\0';
return nsFrameUtil::Copy(id);
}
void
nsFrameUtil::Tag::ReadAttrs(FILE* aFile)
{
for (;;) {
if (!EatWS(aFile)) {
break;
}
int c = getc(aFile);
if (c < 0) break;
if (c == '/') {
if (!EatWS(aFile)) {
return;
}
if (Expect(aFile, '>')) {
type = openClose;
break;
}
}
else if (c == '>') {
break;
}
ungetc(c, aFile);
char* attr = ReadIdent(aFile);
if ((nsnull == attr) || !EatWS(aFile)) {
break;
}
char* value = nsnull;
if (Expect(aFile, '=')) {
value = ReadString(aFile);
if (nsnull == value) {
break;
}
}
AddAttr(attr, value);
}
}
nsFrameUtil::Tag*
nsFrameUtil::Tag::Parse(FILE* aFile)
{
if (!EatWS(aFile)) {
return nsnull;
}
if (Expect(aFile, '<')) {
Tag* tag = new Tag;
if (Expect(aFile, '/')) {
tag->type = close;
}
else {
tag->type = open;
}
tag->name = ReadIdent(aFile);
tag->ReadAttrs(aFile);
return tag;
}
return nsnull;
}
void
nsFrameUtil::Tag::ToString(nsString& aResult)
{
aResult.Truncate();
aResult.Append(PRUnichar('<'));
if (type == close) {
aResult.Append(PRUnichar('/'));
}
aResult.AppendWithConversion(name);
if (0 != num) {
PRInt32 i, n = num;
for (i = 0; i < n; i++) {
aResult.Append(PRUnichar(' '));
aResult.AppendWithConversion(attributes[i]);
if (values[i]) {
aResult.AppendWithConversion("=\"");
aResult.AppendWithConversion(values[i]);
aResult.AppendWithConversion('\"');
}
}
}
if (type == openClose) {
aResult.Append(PRUnichar('/'));
}
aResult.Append(PRUnichar('>'));
}
//----------------------------------------------------------------------
nsresult NS_NewFrameUtil(nsIFrameUtil** aResult);
nsresult
NS_NewFrameUtil(nsIFrameUtil** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null pointer");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = nsnull;
nsFrameUtil* it = new nsFrameUtil();
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIFrameUtilIID, (void**) aResult);
}
nsFrameUtil::nsFrameUtil()
{
NS_INIT_REFCNT();
}
nsFrameUtil::~nsFrameUtil()
{
}
NS_IMPL_ISUPPORTS(nsFrameUtil, kIFrameUtilIID);
void
nsFrameUtil::DumpNode(Node* aNode, FILE* aOutputFile, PRInt32 aIndent)
{
nsFrame::IndentBy(aOutputFile, aIndent);
fprintf(aOutputFile, "%s 0x%x %d,%d,%d,%d\n", aNode->type, aNode->state,
aNode->bbox.x, aNode->bbox.y,
aNode->bbox.width, aNode->bbox.height);
}
void
nsFrameUtil::DumpTree(Node* aNode, FILE* aOutputFile, PRInt32 aIndent)
{
while (nsnull != aNode) {
DumpNode(aNode, aOutputFile, aIndent);
nsFrameUtil::NodeList* lists = aNode->lists;
if (nsnull != lists) {
while (nsnull != lists) {
nsFrame::IndentBy(aOutputFile, aIndent);
fprintf(aOutputFile, " list: %s\n",
lists->name ? lists->name : "primary");
DumpTree(lists->node, aOutputFile, aIndent + 1);
lists = lists->next;
}
}
aNode = aNode->next;
}
}
PRBool
nsFrameUtil::CompareTrees(Node* tree1, Node* tree2)
{
for (;;) {
// Make sure both nodes are non-null, or at least agree with each other
if (nsnull == tree1) {
if (nsnull == tree2) {
break;
}
printf("first tree prematurely ends\n");
return PR_FALSE;
}
else if (nsnull == tree2) {
printf("second tree prematurely ends\n");
return PR_FALSE;
}
// Check the attributes that we care about
if (0 != PL_strcmp(tree1->type, tree2->type)) {
printf("frame type mismatch: %s vs. %s\n", tree1->type, tree2->type);
printf("Node 1:\n");
DumpNode(tree1, stdout, 1);
printf("Node 2:\n");
DumpNode(tree2, stdout, 1);
return PR_FALSE;
}
if (tree1->state != tree2->state) {
printf("frame state mismatch: 0x%x vs. 0x%x\n",
tree1->state, tree2->state);
}
if (tree1->bbox != tree2->bbox) {
printf("frame bbox mismatch: %d,%d,%d,%d vs. %d,%d,%d,%d\n",
tree1->bbox.x, tree1->bbox.y,
tree1->bbox.width, tree1->bbox.height,
tree2->bbox.x, tree2->bbox.y,
tree2->bbox.width, tree2->bbox.height);
}
// Check child lists too
NodeList* list1 = tree1->lists;
NodeList* list2 = tree2->lists;
for (;;) {
if (nsnull == list1) {
if (nsnull != list2) {
printf("first tree prematurely ends (no child lists)\n");
printf("Node 1:\n");
DumpNode(tree1, stdout, 1);
printf("Node 2:\n");
DumpNode(tree2, stdout, 1);
return PR_FALSE;
}
else {
break;
}
}
if (nsnull == list2) {
printf("second tree prematurely ends (no child lists)\n");
printf("Node 1:\n");
DumpNode(tree1, stdout, 1);
printf("Node 2:\n");
DumpNode(tree2, stdout, 1);
return PR_FALSE;
}
if (0 != PL_strcmp(list1->name, list2->name)) {
printf("child-list name mismatch: %s vs. %s\n",
list1->name ? list1->name : "(null)",
list2->name ? list2->name : "(null)");
}
else {
PRBool equiv = CompareTrees(list1->node, list2->node);
if (!equiv) {
return equiv;
}
}
list1 = list1->next;
list2 = list2->next;
}
// Check siblings next
tree1 = tree1->next;
tree2 = tree2->next;
}
return PR_TRUE;
}
NS_IMETHODIMP
nsFrameUtil::CompareRegressionData(FILE* aFile1, FILE* aFile2)
{
Node* tree1 = Node::ReadTree(aFile1);
Node* tree2 = Node::ReadTree(aFile2);
nsresult rv = NS_OK;
if (!CompareTrees(tree1, tree2)) {
printf("Regression data 1:\n");
DumpTree(tree1, stdout, 0);
printf("Regression data 2:\n");
DumpTree(tree2, stdout, 0);
rv = NS_ERROR_FAILURE;
}
Node::Destroy(tree1);
Node::Destroy(tree2);
return rv;
}
NS_IMETHODIMP
nsFrameUtil::DumpRegressionData(FILE* aInputFile, FILE* aOutputFile)
{
Node* tree1 = Node::ReadTree(aInputFile);
if (nsnull != tree1) {
DumpTree(tree1, aOutputFile, 0);
Node::Destroy(tree1);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
#endif

View File

@@ -0,0 +1,106 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsPresContext.h"
#include "nsGfxCIID.h"
#include "nsLayoutAtoms.h"
static NS_DEFINE_IID(kIPresContextIID, NS_IPRESCONTEXT_IID);
class GalleyContext : public nsPresContext {
public:
GalleyContext();
~GalleyContext();
NS_IMETHOD GetMedium(nsIAtom** aMedium);
NS_IMETHOD IsPaginated(PRBool* aResult);
NS_IMETHOD GetPageWidth(nscoord* aResult);
NS_IMETHOD GetPageHeight(nscoord* aResult);
};
GalleyContext::GalleyContext()
{
}
GalleyContext::~GalleyContext()
{
}
NS_IMETHODIMP
GalleyContext::GetMedium(nsIAtom** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = nsLayoutAtoms::screen;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
GalleyContext::IsPaginated(PRBool* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
GalleyContext::GetPageWidth(nscoord* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = 0;
return NS_OK;
}
NS_IMETHODIMP
GalleyContext::GetPageHeight(nscoord* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = 0;
return NS_OK;
}
NS_LAYOUT nsresult
NS_NewGalleyContext(nsIPresContext** aInstancePtrResult)
{
if (aInstancePtrResult == nsnull) {
return NS_ERROR_NULL_POINTER;
}
GalleyContext *it = new GalleyContext();
if (it == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIPresContextIID, (void **) aInstancePtrResult);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
#include "nscore.h"
#include "nsCaretProperties.h"
//-----------------------------------------------------------------------------
nsCaretProperties::nsCaretProperties()
: mCaretWidth(eDefaultCaretWidth)
, mBlinkRate(eDefaulBlinkRate)
{
// in your platform-specific class, get data from the OS in your constructor
}
//-----------------------------------------------------------------------------
nsCaretProperties* NewCaretProperties()
{
return new nsCaretProperties();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,652 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsGenericDOMDataNode_h___
#define nsGenericDOMDataNode_h___
#include "nsCOMPtr.h"
#include "nsIDOMCharacterData.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIContent.h"
#include "nsTextFragment.h"
#include "nsVoidArray.h"
#include "nsINameSpaceManager.h"
#include "nsITextContent.h"
#include "nsDOMError.h"
#include "nsIEventListenerManager.h"
extern const nsIID kIDOMCharacterDataIID;
extern const nsIID kIDOMNodeIID;
extern const nsIID kIDOMEventReceiverIID;
extern const nsIID kIDOMEventTargetIID;
extern const nsIID kIScriptObjectOwnerIID;
extern const nsIID kISupportsIID;
extern const nsIID kIContentIID;
class nsIDOMAttr;
class nsIDOMEventListener;
class nsIDOMNodeList;
class nsIFrame;
class nsIStyleContext;
class nsIStyleRule;
class nsISupportsArray;
class nsIDOMText;
class nsINodeInfo;
struct nsGenericDOMDataNode {
nsGenericDOMDataNode();
virtual ~nsGenericDOMDataNode();
// Implementation for nsIDOMNode
nsresult GetNodeValue(nsString& aNodeValue);
nsresult SetNodeValue(nsIContent *aOuterContent,
const nsString& aNodeValue);
nsresult GetParentNode(nsIDOMNode** aParentNode);
nsresult GetAttributes(nsIDOMNamedNodeMap** aAttributes) {
NS_ENSURE_ARG_POINTER(aAttributes);
*aAttributes = nsnull;
return NS_OK;
}
nsresult GetPreviousSibling(nsIContent *aOuterContent,
nsIDOMNode** aPreviousSibling);
nsresult GetNextSibling(nsIContent *aOuterContent,
nsIDOMNode** aNextSibling);
nsresult GetChildNodes(nsIDOMNodeList** aChildNodes);
nsresult HasChildNodes(PRBool* aHasChildNodes) {
NS_ENSURE_ARG_POINTER(aHasChildNodes);
*aHasChildNodes = PR_FALSE;
return NS_OK;
}
nsresult GetFirstChild(nsIDOMNode** aFirstChild) {
NS_ENSURE_ARG_POINTER(aFirstChild);
*aFirstChild = nsnull;
return NS_OK;
}
nsresult GetLastChild(nsIDOMNode** aLastChild) {
NS_ENSURE_ARG_POINTER(aLastChild);
*aLastChild = nsnull;
return NS_OK;
}
nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
nsIDOMNode** aReturn) {
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
nsIDOMNode** aReturn) {
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
/*
* Data nodes can't have children, i.e. aOldChild can't be a child of
* this node.
*/
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) {
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
/*
* Data nodes can't have children, i.e. aOldChild can't be a child of
* this node.
*/
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn) {
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = nsnull;
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
nsresult GetOwnerDocument(nsIDOMDocument** aOwnerDocument);
nsresult GetNamespaceURI(nsString& aNamespaceURI);
nsresult GetPrefix(nsString& aPrefix);
nsresult SetPrefix(const nsString& aPrefix);
nsresult Normalize();
nsresult Supports(const nsString& aFeature, const nsString& aVersion,
PRBool* aReturn);
// Implementation for nsIDOMCharacterData
nsresult GetData(nsString& aData);
nsresult SetData(nsIContent *aOuterContent, const nsString& aData);
nsresult GetLength(PRUint32* aLength);
nsresult SubstringData(PRUint32 aOffset, PRUint32 aCount, nsString& aReturn);
nsresult AppendData(nsIContent *aOuterContent, const nsString& aArg);
nsresult InsertData(nsIContent *aOuterContent, PRUint32 aOffset,
const nsString& aArg);
nsresult DeleteData(nsIContent *aOuterContent, PRUint32 aOffset,
PRUint32 aCount);
nsresult ReplaceData(nsIContent *aOuterContent, PRUint32 aOffset,
PRUint32 aCount, const nsString& aArg);
// nsIScriptObjectOwner interface
nsresult GetScriptObject(nsIContent *aOuterContent,
nsIScriptContext* aContext, void** aScriptObject);
nsresult SetScriptObject(void *aScriptObject);
// Implementation for nsIContent
nsresult GetDocument(nsIDocument*& aResult) const;
nsresult SetDocument(nsIDocument* aDocument, PRBool aDeep, PRBool aCompileEventHandlers);
nsresult GetParent(nsIContent*& aResult) const;
nsresult SetParent(nsIContent* aParent);
nsresult IsSynthetic(PRBool& aResult) {
aResult = PR_FALSE;
return NS_OK;
}
nsresult GetNameSpaceID(PRInt32& aID) const {
aID = kNameSpaceID_None;
return NS_OK;
}
nsresult ParseAttributeString(const nsString& aStr,
nsIAtom*& aName,
PRInt32& aNameSpaceID) {
aName = nsnull;
aNameSpaceID = kNameSpaceID_None;
return NS_OK;
}
NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID,
nsIAtom*& aPrefix) {
aPrefix = nsnull;
return NS_OK;
}
nsresult SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify) {
return NS_OK;
}
nsresult SetAttribute(nsINodeInfo *aNodeInfo, const nsString& aValue,
PRBool aNotify) {
return NS_OK;
}
nsresult UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRBool aNotify) {
return NS_OK;
}
nsresult GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, nsString &aResult) const {
return NS_CONTENT_ATTR_NOT_THERE;
}
nsresult GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, nsIAtom*& aPrefix, nsString &aResult) const {
aPrefix = nsnull;
return NS_CONTENT_ATTR_NOT_THERE;
}
nsresult GetAttributeNameAt(PRInt32 aIndex, PRInt32& aNameSpaceID,
nsIAtom*& aName, nsIAtom*& aPrefix) const {
aNameSpaceID = kNameSpaceID_None;
aName = nsnull;
aPrefix = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult GetAttributeCount(PRInt32& aResult) const {
aResult = 0;
return NS_OK;
}
nsresult List(FILE* out, PRInt32 aIndent) const;
nsresult DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const;
nsresult HandleDOMEvent(nsIPresContext* aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus* aEventStatus);
nsresult RangeAdd(nsIDOMRange& aRange);
nsresult RangeRemove(nsIDOMRange& aRange);
nsresult GetRangeList(nsVoidArray*& aResult) const;
nsresult SetFocus(nsIPresContext *aPresContext);
nsresult RemoveFocus(nsIPresContext *aPresContext);
nsresult SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult,
size_t aInstanceSize) const;
// Implementation for nsIContent
nsresult BeginConvertToXIF(nsIXIFConverter * aConverter) const;
nsresult ConvertContentToXIF(const nsIContent *aOuterContent,
nsIXIFConverter * aConverter) const;
nsresult FinishConvertToXIF(nsIXIFConverter * aConverter) const;
nsresult CanContainChildren(PRBool& aResult) const {
aResult = PR_FALSE;
return NS_OK;
}
nsresult ChildCount(PRInt32& aResult) const {
aResult = 0;
return NS_OK;
}
nsresult ChildAt(PRInt32 aIndex, nsIContent*& aResult) const {
aResult = nsnull;
return NS_OK;
}
nsresult IndexOf(nsIContent* aPossibleChild, PRInt32& aResult) const {
aResult = -1;
return NS_OK;
}
nsresult InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
nsresult ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify) {
return NS_OK;
}
nsresult RemoveChildAt(PRInt32 aIndex, PRBool aNotify) {
return NS_OK;
}
nsresult SplitText(nsIContent *aOuterContent, PRUint32 aOffset,
nsIDOMText** aReturn);
nsresult GetText(const nsTextFragment** aFragmentsResult);
nsresult GetTextLength(PRInt32* aLengthResult);
nsresult CopyText(nsString& aResult);
nsresult SetText(nsIContent *aOuterContent,
const PRUnichar* aBuffer,
PRInt32 aLength,
PRBool aNotify);
nsresult SetText(nsIContent *aOuterContent,
const char* aBuffer,
PRInt32 aLength,
PRBool aNotify);
nsresult IsOnlyWhitespace(PRBool* aResult);
//----------------------------------------
nsresult GetListenerManager(nsIContent* aOuterContent, nsIEventListenerManager** aInstancePtrResult);
void ToCString(nsString& aBuf, PRInt32 aOffset, PRInt32 aLen) const;
nsIDocument* mDocument;
nsIContent* mParent;
void* mScriptObject;
nsIEventListenerManager* mListenerManager;
nsIContent* mCapturer;
nsTextFragment mText;
nsVoidArray *mRangeList;
};
//----------------------------------------------------------------------
/**
* Mostly implement the nsIDOMNode API by forwarding the methods to a
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*
* Note that classes using this macro will need to implement:
* NS_IMETHOD GetNodeType(PRUint16* aNodeType);
* NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
*/
#define NS_IMPL_IDOMNODE_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetNodeName(nsString& aNodeName); \
NS_IMETHOD GetLocalName(nsString& aLocalName) { \
return GetNodeName(aLocalName); \
} \
NS_IMETHOD GetNodeValue(nsString& aNodeValue) { \
return _g.GetNodeValue(aNodeValue); \
} \
NS_IMETHOD SetNodeValue(const nsString& aNodeValue) { \
return _g.SetNodeValue(this, aNodeValue); \
} \
NS_IMETHOD GetNodeType(PRUint16* aNodeType); \
NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) { \
return _g.GetParentNode(aParentNode); \
} \
NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) { \
return _g.GetChildNodes(aChildNodes); \
} \
NS_IMETHOD HasChildNodes(PRBool* aHasChildNodes) { \
return _g.HasChildNodes(aHasChildNodes); \
} \
NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) { \
return _g.GetFirstChild(aFirstChild); \
} \
NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) { \
return _g.GetLastChild(aLastChild); \
} \
NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) { \
return _g.GetPreviousSibling(this, aPreviousSibling); \
} \
NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) { \
return _g.GetNextSibling(this, aNextSibling); \
} \
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) { \
return _g.GetAttributes(aAttributes); \
} \
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, \
nsIDOMNode** aReturn) { \
return _g.InsertBefore(aNewChild, aRefChild, aReturn); \
} \
NS_IMETHOD AppendChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { \
return _g.AppendChild(aOldChild, aReturn); \
} \
NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, \
nsIDOMNode** aReturn) { \
return _g.ReplaceChild(aNewChild, aOldChild, aReturn); \
} \
NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn) { \
return _g.RemoveChild(aOldChild, aReturn); \
} \
NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) { \
return _g.GetOwnerDocument(aOwnerDocument); \
} \
NS_IMETHOD GetNamespaceURI(nsString& aNamespaceURI) { \
return _g.GetNamespaceURI(aNamespaceURI); \
} \
NS_IMETHOD GetPrefix(nsString& aPrefix) { \
return _g.GetPrefix(aPrefix); \
} \
NS_IMETHOD SetPrefix(const nsString& aPrefix) { \
return _g.SetPrefix(aPrefix); \
} \
NS_IMETHOD Normalize() { \
return NS_OK; \
} \
NS_IMETHOD Supports(const nsString& aFeature, const nsString& aVersion,\
PRBool* aReturn) { \
return _g.Supports(aFeature, aVersion, aReturn); \
} \
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
#define NS_IMPL_IDOMCHARACTERDATA_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetData(nsString& aData) { \
return _g.GetData(aData); \
} \
NS_IMETHOD SetData(const nsString& aData) { \
return _g.SetData(this, aData); \
} \
NS_IMETHOD GetLength(PRUint32* aLength) { \
return _g.GetLength(aLength); \
} \
NS_IMETHOD SubstringData(PRUint32 aStart, PRUint32 aEnd, nsString& aReturn) { \
return _g.SubstringData(aStart, aEnd, aReturn); \
} \
NS_IMETHOD AppendData(const nsString& aData) { \
return _g.AppendData(this, aData); \
} \
NS_IMETHOD InsertData(PRUint32 aOffset, const nsString& aData) { \
return _g.InsertData(this, aOffset, aData); \
} \
NS_IMETHOD DeleteData(PRUint32 aOffset, PRUint32 aCount) { \
return _g.DeleteData(this, aOffset, aCount); \
} \
NS_IMETHOD ReplaceData(PRUint32 aOffset, PRUint32 aCount, \
const nsString& aData) { \
return _g.ReplaceData(this, aOffset, aCount, aData); \
}
/**
* Implement the nsIDOMEventReceiver API by forwarding the methods to a
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*/
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
} \
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent) { \
return _g.HandleEvent(aEvent); \
} \
NS_IMETHOD AddEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aUseCapture) { \
return _g.AddEventListener(aType, aListener, aUseCapture); \
} \
NS_IMETHOD RemoveEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aUseCapture) { \
return _g.RemoveEventListener(aType, aListener, aUseCapture); \
}
/**
* Implement the nsIScriptObjectOwner API by forwarding the methods to a
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*/
#define NS_IMPL_ISCRIPTOBJECTOWNER_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetScriptObject(nsIScriptContext* aContext, \
void** aScriptObject) { \
return _g.GetScriptObject(this, aContext, aScriptObject); \
} \
NS_IMETHOD SetScriptObject(void *aScriptObject) { \
return _g.SetScriptObject(aScriptObject); \
}
#define NS_IMPL_ICONTENT_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetDocument(nsIDocument*& aResult) const { \
return _g.GetDocument(aResult); \
} \
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep, PRBool aCompileEventHandlers) { \
return _g.SetDocument(aDocument, aDeep, aCompileEventHandlers); \
} \
NS_IMETHOD GetParent(nsIContent*& aResult) const { \
return _g.GetParent(aResult); \
} \
NS_IMETHOD SetParent(nsIContent* aParent) { \
return _g.SetParent(aParent); \
} \
NS_IMETHOD CanContainChildren(PRBool& aResult) const { \
return _g.CanContainChildren(aResult); \
} \
NS_IMETHOD ChildCount(PRInt32& aResult) const { \
return _g.ChildCount(aResult); \
} \
NS_IMETHOD ChildAt(PRInt32 aIndex, nsIContent*& aResult) const { \
return _g.ChildAt(aIndex, aResult); \
} \
NS_IMETHOD IndexOf(nsIContent* aPossibleChild, PRInt32& aResult) const { \
return _g.IndexOf(aPossibleChild, aResult); \
} \
NS_IMETHOD InsertChildAt(nsIContent* aKid, PRInt32 aIndex, \
PRBool aNotify) { \
return _g.InsertChildAt(aKid, aIndex, aNotify); \
} \
NS_IMETHOD ReplaceChildAt(nsIContent* aKid, PRInt32 aIndex, \
PRBool aNotify) { \
return _g.ReplaceChildAt(aKid, aIndex, aNotify); \
} \
NS_IMETHOD AppendChildTo(nsIContent* aKid, PRBool aNotify) { \
return _g.AppendChildTo(aKid, aNotify); \
} \
NS_IMETHOD RemoveChildAt(PRInt32 aIndex, PRBool aNotify) { \
return _g.RemoveChildAt(aIndex, aNotify); \
} \
NS_IMETHOD IsSynthetic(PRBool& aResult) { \
return _g.IsSynthetic(aResult); \
} \
NS_IMETHOD GetNameSpaceID(PRInt32& aID) const { \
return _g.GetNameSpaceID(aID); \
} \
NS_IMETHOD GetTag(nsIAtom*& aResult) const; \
NS_IMETHOD GetNodeInfo(nsINodeInfo*& aResult) const; \
NS_IMETHOD ParseAttributeString(const nsString& aStr, \
nsIAtom*& aName, \
PRInt32& aNameSpaceID) { \
return _g.ParseAttributeString(aStr, aName, aNameSpaceID); \
} \
NS_IMETHOD GetNameSpacePrefixFromId(PRInt32 aNameSpaceID, \
nsIAtom*& aPrefix) { \
return _g.GetNameSpacePrefixFromId(aNameSpaceID, aPrefix); \
} \
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, \
nsString &aResult) const { \
return _g.GetAttribute(aNameSpaceID, aAttribute, aResult); \
} \
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom *aAttribute, \
nsIAtom*& aPrefix, nsString &aResult) const { \
return _g.GetAttribute(aNameSpaceID, aAttribute, aPrefix, aResult); \
} \
NS_IMETHOD SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, \
const nsString& aValue, PRBool aNotify) { \
return _g.SetAttribute(aNameSpaceID, aAttribute, aValue, aNotify); \
} \
NS_IMETHOD SetAttribute(nsINodeInfo* aNodeInfo, \
const nsString& aValue, PRBool aNotify) { \
return _g.SetAttribute(aNodeInfo, aValue, aNotify); \
} \
NS_IMETHOD UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute, \
PRBool aNotify) { \
return _g.UnsetAttribute(aNameSpaceID, aAttribute, aNotify); \
} \
NS_IMETHOD GetAttributeNameAt(PRInt32 aIndex, \
PRInt32& aNameSpaceID, \
nsIAtom*& aName, \
nsIAtom*& aPrefix) const { \
return _g.GetAttributeNameAt(aIndex, aNameSpaceID, aName, aPrefix); \
} \
NS_IMETHOD GetAttributeCount(PRInt32& aResult) const { \
return _g.GetAttributeCount(aResult); \
} \
NS_IMETHOD List(FILE* out, PRInt32 aIndent) const; \
NS_IMETHOD DumpContent(FILE* out, \
PRInt32 aIndent, \
PRBool aDumpAll) const; \
NS_IMETHOD BeginConvertToXIF(nsIXIFConverter * aConverter) const { \
return _g.BeginConvertToXIF(aConverter); \
} \
NS_IMETHOD ConvertContentToXIF(nsIXIFConverter * aConverter) const { \
return _g.ConvertContentToXIF(this, aConverter); \
} \
NS_IMETHOD FinishConvertToXIF(nsIXIFConverter * aConverter) const { \
return _g.FinishConvertToXIF(aConverter); \
} \
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext, \
nsEvent* aEvent, \
nsIDOMEvent** aDOMEvent, \
PRUint32 aFlags, \
nsEventStatus* aEventStatus); \
NS_IMETHOD GetContentID(PRUint32* aID); \
NS_IMETHOD SetContentID(PRUint32 aID); \
NS_IMETHOD RangeAdd(nsIDOMRange& aRange){ \
return _g.RangeAdd(aRange); \
} \
NS_IMETHOD RangeRemove(nsIDOMRange& aRange){ \
return _g.RangeRemove(aRange); \
} \
NS_IMETHOD GetRangeList(nsVoidArray*& aResult) const { \
return _g.GetRangeList(aResult); \
} \
NS_IMETHOD SetFocus(nsIPresContext* aPresContext) { \
return _g.SetFocus(aPresContext); \
} \
NS_IMETHOD RemoveFocus(nsIPresContext* aPresContext) { \
return _g.RemoveFocus(aPresContext); \
}
/**
* Implement the nsIDOMText API by forwarding the methods to a
* generic character data content object.
*/
#define NS_IMPL_IDOMTEXT_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD SplitText(PRUint32 aOffset, nsIDOMText** aReturn){ \
return _g.SplitText(this, aOffset, aReturn); \
}
/**
* Implement the nsITextContent API by forwarding the methods to a
* generic character data content object.
*/
#define NS_IMPL_ITEXTCONTENT_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD GetText(const nsTextFragment** aFragmentsResult) { \
return mInner.GetText(aFragmentsResult); \
} \
NS_IMETHOD GetTextLength(PRInt32* aLengthResult) { \
return mInner.GetTextLength(aLengthResult); \
} \
NS_IMETHOD CopyText(nsString& aResult) { \
return mInner.CopyText(aResult); \
} \
NS_IMETHOD SetText(const PRUnichar* aBuffer, \
PRInt32 aLength, \
PRBool aNotify){ \
return mInner.SetText(this, aBuffer, aLength, aNotify); \
} \
NS_IMETHOD SetText(const char* aBuffer, \
PRInt32 aLength, \
PRBool aNotify){ \
return mInner.SetText(this, aBuffer, aLength, aNotify); \
} \
NS_IMETHOD IsOnlyWhitespace(PRBool* aResult){ \
return mInner.IsOnlyWhitespace(aResult); \
} \
NS_IMETHOD CloneContent(PRBool aCloneText, nsITextContent** aClone);
/**
* This macro implements the portion of query interface that is
* generic to all html content objects.
*/
#define NS_IMPL_DOM_DATA_QUERY_INTERFACE(_id, _iptr, _this) \
if (_id.Equals(kISupportsIID)) { \
nsIContent* tmp = _this; \
nsISupports* tmp2 = tmp; \
*_iptr = (void*) tmp2; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMNodeIID)) { \
nsIDOMNode* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMCharacterDataIID)) { \
nsIDOMCharacterData* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMEventReceiverIID)) { \
nsCOMPtr<nsIEventListenerManager> man; \
if (NS_SUCCEEDED(mInner.GetListenerManager(this, getter_AddRefs(man)))){ \
return man->QueryInterface(kIDOMEventReceiverIID, (void**)_iptr); \
} \
return NS_NOINTERFACE; \
} \
if (_id.Equals(kIDOMEventTargetIID)) { \
nsCOMPtr<nsIEventListenerManager> man; \
if (NS_SUCCEEDED(mInner.GetListenerManager(this, getter_AddRefs(man)))){ \
return man->QueryInterface(kIDOMEventTargetIID, (void**)_iptr); \
} \
return NS_NOINTERFACE; \
} \
if (_id.Equals(kIScriptObjectOwnerIID)) { \
nsIScriptObjectOwner* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIContentIID)) { \
nsIContent* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
}
#endif /* nsGenericDOMDataNode_h___ */

View File

@@ -0,0 +1,89 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsGenericDOMNodeList.h"
#include "nsIDOMScriptObjectFactory.h"
#include "nsGenericElement.h"
nsGenericDOMNodeList::nsGenericDOMNodeList()
{
NS_INIT_REFCNT();
mScriptObject = nsnull;
}
nsGenericDOMNodeList::~nsGenericDOMNodeList()
{
}
nsresult
nsGenericDOMNodeList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kIDOMNodeListIID, NS_IDOMNODELIST_IID);
if (aIID.Equals(kIDOMNodeListIID)) {
*aInstancePtr = (void*)(nsIDOMNodeList*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMNodeList*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsGenericDOMNodeList)
NS_IMPL_RELEASE(nsGenericDOMNodeList)
NS_IMETHODIMP
nsGenericDOMNodeList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
nsIDOMScriptObjectFactory *factory;
res = nsGenericElement::GetScriptObjectFactory(&factory);
if (NS_OK != res) {
return res;
}
res = factory->NewScriptNodeList(aContext, (nsISupports *)(nsIDOMNodeList *)this, nsnull, (void**)&mScriptObject);
NS_RELEASE(factory);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
nsGenericDOMNodeList::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}

View File

@@ -0,0 +1,60 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsGenericDOMNodeList_h__
#define nsGenericDOMNodeList_h__
#include "nsISupports.h"
#include "nsIDOMNodeList.h"
#include "nsIScriptObjectOwner.h"
/**
* This is a base class for a generic DOM Node List. The base class
* provides implementations for nsISupports and nsIScriptObjectOwner,
* but it is up to the subclass to implement the core node list
* methods:
* GetLength
* Item
*
*/
class nsGenericDOMNodeList : public nsIDOMNodeList,
public nsIScriptObjectOwner
{
public:
nsGenericDOMNodeList();
virtual ~nsGenericDOMNodeList();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
// The following need to be defined in the subclass
// nsIDOMNodeList interface
NS_IMETHOD GetLength(PRUint32* aLength)=0;
NS_IMETHOD Item(PRUint32 aIndex, nsIDOMNode** aReturn)=0;
protected:
void* mScriptObject;
};
#endif // nsGenericDOMNodeList_h__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsLayoutAtoms.h"
// define storage for all atoms
#define LAYOUT_ATOM(_name, _value) nsIAtom* nsLayoutAtoms::_name;
#include "nsLayoutAtomList.h"
#undef LAYOUT_ATOM
static nsrefcnt gRefCnt;
void nsLayoutAtoms::AddRefAtoms()
{
if (0 == gRefCnt++) {
// create atoms
#define LAYOUT_ATOM(_name, _value) _name = NS_NewAtom(_value);
#include "nsLayoutAtomList.h"
#undef LAYOUT_ATOM
}
}
void nsLayoutAtoms::ReleaseAtoms()
{
NS_PRECONDITION(gRefCnt != 0, "bad release atoms");
if (--gRefCnt == 0) {
// release atoms
#define LAYOUT_ATOM(_name, _value) NS_RELEASE(_name);
#include "nsLayoutAtomList.h"
#undef LAYOUT_ATOM
}
}

View File

@@ -0,0 +1,131 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsILayoutDebugger.h"
#include "nsIFrame.h"
#include "nsIFrameDebug.h"
static NS_DEFINE_IID(kILayoutDebuggerIID, NS_ILAYOUT_DEBUGGER_IID);
#ifdef NS_DEBUG
class nsLayoutDebugger : public nsILayoutDebugger {
public:
nsLayoutDebugger();
virtual ~nsLayoutDebugger();
NS_DECL_ISUPPORTS
NS_IMETHOD SetShowFrameBorders(PRBool aEnable);
NS_IMETHOD GetShowFrameBorders(PRBool* aResult);
NS_IMETHOD SetShowEventTargetFrameBorder(PRBool aEnable);
NS_IMETHOD GetShowEventTargetFrameBorder(PRBool* aResult);
NS_IMETHOD GetContentSize(nsIDocument* aDocument,
PRInt32* aSizeInBytesResult);
NS_IMETHOD GetFrameSize(nsIPresShell* aPresentation,
PRInt32* aSizeInBytesResult);
NS_IMETHOD GetStyleSize(nsIPresShell* aPresentation,
PRInt32* aSizeInBytesResult);
};
nsresult
NS_NewLayoutDebugger(nsILayoutDebugger** aResult)
{
NS_PRECONDITION(aResult, "null OUT ptr");
if (!aResult) {
return NS_ERROR_NULL_POINTER;
}
nsLayoutDebugger* it = new nsLayoutDebugger();
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kILayoutDebuggerIID, (void**)aResult);
}
nsLayoutDebugger::nsLayoutDebugger()
{
NS_INIT_REFCNT();
}
nsLayoutDebugger::~nsLayoutDebugger()
{
}
NS_IMPL_ISUPPORTS(nsLayoutDebugger, kILayoutDebuggerIID);
NS_IMETHODIMP
nsLayoutDebugger::SetShowFrameBorders(PRBool aEnable)
{
nsIFrameDebug::ShowFrameBorders(aEnable);
return NS_OK;
}
NS_IMETHODIMP
nsLayoutDebugger::GetShowFrameBorders(PRBool* aResult)
{
*aResult = nsIFrameDebug::GetShowFrameBorders();
return NS_OK;
}
NS_IMETHODIMP
nsLayoutDebugger::SetShowEventTargetFrameBorder(PRBool aEnable)
{
nsIFrameDebug::ShowEventTargetFrameBorder(aEnable);
return NS_OK;
}
NS_IMETHODIMP
nsLayoutDebugger::GetShowEventTargetFrameBorder(PRBool* aResult)
{
*aResult = nsIFrameDebug::GetShowEventTargetFrameBorder();
return NS_OK;
}
NS_IMETHODIMP
nsLayoutDebugger::GetContentSize(nsIDocument* aDocument,
PRInt32* aSizeInBytesResult)
{
*aSizeInBytesResult = 0;
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsLayoutDebugger::GetFrameSize(nsIPresShell* aPresentation,
PRInt32* aSizeInBytesResult)
{
*aSizeInBytesResult = 0;
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsLayoutDebugger::GetStyleSize(nsIPresShell* aPresentation,
PRInt32* aSizeInBytesResult)
{
*aSizeInBytesResult = 0;
return NS_ERROR_FAILURE;
}
#endif

View File

@@ -0,0 +1,166 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsILayoutHistoryState.h"
#include "nsHashtable.h"
#include "nsIStatefulFrame.h" // Get StateType enum
MOZ_DECL_CTOR_COUNTER(HistoryKey);
class HistoryKey: public nsHashKey {
private:
PRUint32 itsHash;
public:
HistoryKey(PRUint32 aContentID, nsIStatefulFrame::StateType aStateType) {
MOZ_COUNT_CTOR(HistoryKey);
itsHash = aContentID * nsIStatefulFrame::eNumStateTypes + aStateType;
}
HistoryKey(PRUint32 aKey) {
MOZ_COUNT_CTOR(HistoryKey);
itsHash = aKey;
}
~HistoryKey() {
MOZ_COUNT_DTOR(HistoryKey);
}
PRUint32 HashValue(void) const {
return itsHash;
}
PRBool Equals(const nsHashKey *aKey) const {
return (itsHash == (((const HistoryKey *) aKey)->HashValue())) ? PR_TRUE : PR_FALSE;
}
nsHashKey *Clone(void) const {
return new HistoryKey(itsHash);
}
};
class nsLayoutHistoryState : public nsILayoutHistoryState
{
public:
nsLayoutHistoryState();
virtual ~nsLayoutHistoryState();
NS_DECL_ISUPPORTS
// nsILayoutHistoryState
NS_IMETHOD AddState(PRUint32 aContentID,
nsIPresState* aState,
nsIStatefulFrame::StateType aStateType = nsIStatefulFrame::eNoType);
NS_IMETHOD GetState(PRUint32 aContentID,
nsIPresState** aState,
nsIStatefulFrame::StateType aStateType = nsIStatefulFrame::eNoType);
NS_IMETHOD RemoveState(PRUint32 aContentID,
nsIStatefulFrame::StateType aStateType = nsIStatefulFrame::eNoType);
private:
nsSupportsHashtable mStates;
};
nsresult
NS_NewLayoutHistoryState(nsILayoutHistoryState** aState)
{
NS_PRECONDITION(aState != nsnull, "null ptr");
if (! aState)
return NS_ERROR_NULL_POINTER;
*aState = new nsLayoutHistoryState();
if (! *aState)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aState);
return NS_OK;
}
nsLayoutHistoryState::nsLayoutHistoryState()
{
NS_INIT_REFCNT();
}
nsLayoutHistoryState::~nsLayoutHistoryState()
{
}
NS_IMPL_ISUPPORTS(nsLayoutHistoryState,
NS_GET_IID(nsILayoutHistoryState));
NS_IMETHODIMP
nsLayoutHistoryState::AddState(PRUint32 aContentID,
nsIPresState* aState,
nsIStatefulFrame::StateType aStateType)
{
HistoryKey key(aContentID, aStateType);
/*
* nsSupportsHashtable::Put() returns false when no object has been
* replaced when inserting the new one, true if it some one was.
*
*/
PRBool replaced = mStates.Put (&key, aState);
if (replaced)
{
// done this way by indication of warren@netscape.com [ipg]
#if 0
printf("nsLayoutHistoryState::AddState OOPS!. There was already a state in the hash table for the key\n");
#endif
}
return NS_OK;
}
NS_IMETHODIMP
nsLayoutHistoryState::GetState(PRUint32 aContentID,
nsIPresState** aState,
nsIStatefulFrame::StateType aStateType)
{
nsresult rv = NS_OK;
HistoryKey key(aContentID, aStateType);
nsISupports *state = nsnull;
state = mStates.Get(&key);
if (state) {
*aState = (nsIPresState *)state;
}
else {
#if 0
printf("nsLayoutHistoryState::GetState, ERROR getting History state for the key\n");
#endif
*aState = nsnull;
rv = NS_OK;
}
return rv;
}
NS_IMETHODIMP
nsLayoutHistoryState::RemoveState(PRUint32 aContentID,
nsIStatefulFrame::StateType aStateType)
{
nsresult rv = NS_OK;
HistoryKey key(aContentID, aStateType);
mStates.Remove(&key);
return rv;
}

View File

@@ -0,0 +1,121 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
/* A namespace class for static layout utilities. */
#include "jsapi.h"
#include "nsCOMPtr.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsLayoutUtils.h"
// static
nsresult
nsLayoutUtils::GetStaticScriptGlobal(JSContext* aContext,
JSObject* aObj,
nsIScriptGlobalObject** aNativeGlobal)
{
nsISupports* supports;
JSClass* clazz;
JSObject* parent;
JSObject* glob = aObj; // starting point for search
if (!glob)
return NS_ERROR_FAILURE;
while (nsnull != (parent = JS_GetParent(aContext, glob)))
glob = parent;
#ifdef JS_THREADSAFE
clazz = JS_GetClass(aContext, glob);
#else
clazz = JS_GetClass(glob);
#endif
if (!clazz ||
!(clazz->flags & JSCLASS_HAS_PRIVATE) ||
!(clazz->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) ||
!(supports = (nsISupports*) JS_GetPrivate(aContext, glob))) {
return NS_ERROR_FAILURE;
}
return supports->QueryInterface(NS_GET_IID(nsIScriptGlobalObject),
(void**) aNativeGlobal);
}
//static
nsresult
nsLayoutUtils::GetStaticScriptContext(JSContext* aContext,
JSObject* aObj,
nsIScriptContext** aScriptContext)
{
nsCOMPtr<nsIScriptGlobalObject> nativeGlobal;
GetStaticScriptGlobal(aContext, aObj, getter_AddRefs(nativeGlobal));
if (!nativeGlobal)
return NS_ERROR_FAILURE;
nsIScriptContext* scriptContext = nsnull;
nativeGlobal->GetContext(&scriptContext);
*aScriptContext = scriptContext;
return scriptContext ? NS_OK : NS_ERROR_FAILURE;
}
//static
nsresult
nsLayoutUtils::GetDynamicScriptGlobal(JSContext* aContext,
nsIScriptGlobalObject** aNativeGlobal)
{
nsIScriptGlobalObject* nativeGlobal = nsnull;
nsCOMPtr<nsIScriptContext> scriptCX;
GetDynamicScriptContext(aContext, getter_AddRefs(scriptCX));
if (scriptCX) {
*aNativeGlobal = nativeGlobal = scriptCX->GetGlobalObject();
}
return nativeGlobal ? NS_OK : NS_ERROR_FAILURE;
}
//static
nsresult
nsLayoutUtils::GetDynamicScriptContext(JSContext *aContext,
nsIScriptContext** aScriptContext)
{
// XXX We rely on the rule that if any JSContext in our JSRuntime has a
// private set then that private *must* be a pointer to an nsISupports.
nsISupports *supports = (nsIScriptContext*) JS_GetContextPrivate(aContext);
if (!supports)
return nsnull;
return supports->QueryInterface(NS_GET_IID(nsIScriptContext),
(void**)aScriptContext);
}

View File

@@ -0,0 +1,489 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsINameSpaceManager.h"
#include "nsINameSpace.h"
#include "nsHashtable.h"
#include "nsVoidArray.h"
#include "nsLayoutAtoms.h"
#include "nsString.h"
#include "nsCRT.h"
static NS_DEFINE_IID(kINameSpaceManagerIID, NS_INAMESPACEMANAGER_IID);
static NS_DEFINE_IID(kINameSpaceIID, NS_INAMESPACE_IID);
static const char kXMLNSNameSpaceURI[] = "http://www.w3.org/2000/xmlns";
static const char kXMLNameSpaceURI[] = "http://www.w3.org/XML/1998/namespace";
static const char kHTMLNameSpaceURI[] = "http://www.w3.org/TR/REC-html40"; // XXX?? "urn:w3-org-ns:HTML"??
// XXX To be removed: Bug 7834 ---
static const char kXHTMLNameSpaceURI[] = "http://www.w3.org/1999/xhtml";
static const char kXLinkNameSpaceURI[] = "http://www.w3.org/1999/xlink";
//-----------------------------------------------------------
// Name Space ID table support
static PRInt32 gNameSpaceTableRefs;
static nsHashtable* gURIToIDTable;
static nsVoidArray* gURIArray;
MOZ_DECL_CTOR_COUNTER(NameSpaceURIKey);
class NameSpaceURIKey : public nsHashKey {
public:
NameSpaceURIKey(const nsString* aString)
: mString(aString)
{
MOZ_COUNT_CTOR(NameSpaceURIKey);
}
virtual ~NameSpaceURIKey(void)
{
MOZ_COUNT_DTOR(NameSpaceURIKey);
}
virtual PRUint32 HashValue(void) const
{
#if 1 // case insensitive XXX should this be case sensitive???
PRUint32 hash = 0;
const PRUnichar* string = mString->GetUnicode();
PRUnichar ch;
while ((ch = *string++) != 0) {
// FYI: hash = hash*37 + ch
ch = nsCRT::ToLower(ch);
hash = ((hash << 5) + (hash << 2) + hash) + ch;
}
return hash;
#else
if (nsnull != mString) {
return nsCRT::HashValue(mString->GetUnicode());
}
return 0;
#endif
}
virtual PRBool Equals(const nsHashKey *aKey) const
{
const nsString* other = ((const NameSpaceURIKey*)aKey)->mString;
if (nsnull != mString) {
if (nsnull != other) {
return mString->EqualsIgnoreCase(*other); // XXX case sensitive?
}
return PR_FALSE;
}
return PRBool(nsnull == other);
}
virtual nsHashKey *Clone(void) const
{
return new NameSpaceURIKey(mString);
}
const nsString* mString;
};
static void AddRefTable()
{
if (0 == gNameSpaceTableRefs++) {
NS_ASSERTION(nsnull == gURIToIDTable, "already have URI table");
NS_ASSERTION(nsnull == gURIArray, "already have URI array");
gURIToIDTable = new nsHashtable();
gURIArray = new nsVoidArray();
nsString* xmlns = new nsString( NS_ConvertToString(kXMLNSNameSpaceURI) );
nsString* xml = new nsString( NS_ConvertToString(kXMLNameSpaceURI) );
nsString* xhtml = new nsString( NS_ConvertToString(kXHTMLNameSpaceURI) );
nsString* xlink = new nsString( NS_ConvertToString(kXLinkNameSpaceURI) );
nsString* html = new nsString( NS_ConvertToString(kHTMLNameSpaceURI) );
gURIArray->AppendElement(xmlns); // ordering here needs to match IDs
gURIArray->AppendElement(xml);
gURIArray->AppendElement(xhtml);
gURIArray->AppendElement(xlink);
gURIArray->AppendElement(html);
NameSpaceURIKey xmlnsKey(xmlns);
NameSpaceURIKey xmlKey(xml);
NameSpaceURIKey xhtmlKey(xhtml);
NameSpaceURIKey xlinkKey(xlink);
NameSpaceURIKey htmlKey(html);
gURIToIDTable->Put(&xmlnsKey, (void*)kNameSpaceID_XMLNS);
gURIToIDTable->Put(&xmlKey, (void*)kNameSpaceID_XML);
gURIToIDTable->Put(&xhtmlKey, (void*)kNameSpaceID_HTML);
gURIToIDTable->Put(&xlinkKey, (void*)kNameSpaceID_XLink);
gURIToIDTable->Put(&htmlKey, (void*)kNameSpaceID_HTML);
}
NS_ASSERTION(nsnull != gURIToIDTable, "no URI table");
NS_ASSERTION(nsnull != gURIArray, "no URI array");
}
static void ReleaseTable()
{
if (0 == --gNameSpaceTableRefs) {
delete gURIToIDTable;
PRInt32 index = gURIArray->Count();
while (0 < index--) {
nsString* str = (nsString*)gURIArray->ElementAt(index);
delete str;
}
delete gURIArray;
gURIToIDTable = nsnull;
gURIArray = nsnull;
}
}
static PRInt32 FindNameSpaceID(const nsString& aURI)
{
NS_ASSERTION(nsnull != gURIToIDTable, "no URI table");
NameSpaceURIKey key(&aURI);
void* value = gURIToIDTable->Get(&key);
if (nsnull != value) {
return PRInt32(value);
}
return kNameSpaceID_Unknown;
}
static const nsString* FindNameSpaceURI(PRInt32 aID)
{
NS_ASSERTION(nsnull != gURIArray, "no URI array");
return (const nsString*)gURIArray->ElementAt(aID - 1);
}
//-----------------------------------------------------------
// Name Space
class NameSpaceImpl : public nsINameSpace {
public:
NameSpaceImpl(nsINameSpaceManager* aManager,
NameSpaceImpl* aParent,
nsIAtom* aPrefix,
const nsString& aURI);
NameSpaceImpl(nsINameSpaceManager* aManager,
NameSpaceImpl* aParent,
nsIAtom* aPrefix,
PRInt32 aNameSpaceID);
virtual ~NameSpaceImpl();
NS_DECL_ISUPPORTS
NS_IMETHOD GetNameSpaceManager(nsINameSpaceManager*& aManager) const;
NS_IMETHOD GetNameSpaceID(PRInt32& aID) const;
NS_IMETHOD GetNameSpaceURI(nsString& aURI) const;
NS_IMETHOD GetNameSpacePrefix(nsIAtom*& aPrefix) const;
NS_IMETHOD GetParentNameSpace(nsINameSpace*& aParent) const;
NS_IMETHOD FindNameSpace(nsIAtom* aPrefix, nsINameSpace*& aNameSpace) const;
NS_IMETHOD FindNameSpaceID(nsIAtom* aPrefix, PRInt32& aNameSpaceID) const;
NS_IMETHOD FindNameSpacePrefix(PRInt32 aNameSpaceID, nsIAtom*& aPrefix) const;
NS_IMETHOD CreateChildNameSpace(nsIAtom* aPrefix, const nsString& aURI,
nsINameSpace*& aChildNameSpace);
NS_IMETHOD CreateChildNameSpace(nsIAtom* aPrefix, PRInt32 aNameSpaceID,
nsINameSpace*& aChildNameSpace);
private:
// These are not supported and are not implemented!
NameSpaceImpl(const NameSpaceImpl& aCopy);
NameSpaceImpl& operator=(const NameSpaceImpl& aCopy);
public:
nsINameSpaceManager* mManager;
NameSpaceImpl* mParent;
nsIAtom* mPrefix;
PRInt32 mID;
};
NameSpaceImpl::NameSpaceImpl(nsINameSpaceManager* aManager,
NameSpaceImpl* aParent,
nsIAtom* aPrefix,
const nsString& aURI)
: mManager(aManager),
mParent(aParent),
mPrefix(aPrefix)
{
NS_ASSERTION(nsnull != aManager, "null namespace manager");
NS_INIT_REFCNT();
NS_ADDREF(mManager);
NS_IF_ADDREF(mParent);
NS_IF_ADDREF(mPrefix);
mManager->RegisterNameSpace(aURI, mID);
}
NameSpaceImpl::NameSpaceImpl(nsINameSpaceManager* aManager,
NameSpaceImpl* aParent,
nsIAtom* aPrefix,
PRInt32 aNameSpaceID)
: mManager(aManager),
mParent(aParent),
mPrefix(aPrefix),
mID(aNameSpaceID)
{
NS_ASSERTION(nsnull != aManager, "null namespace manager");
NS_INIT_REFCNT();
NS_ADDREF(mManager);
NS_IF_ADDREF(mParent);
NS_IF_ADDREF(mPrefix);
}
NameSpaceImpl::~NameSpaceImpl()
{
NS_RELEASE(mManager);
NS_IF_RELEASE(mParent);
NS_IF_RELEASE(mPrefix);
}
NS_IMPL_ISUPPORTS(NameSpaceImpl, kINameSpaceIID)
NS_IMETHODIMP
NameSpaceImpl::GetNameSpaceManager(nsINameSpaceManager*& aManager) const
{
NS_ASSERTION(nsnull != aManager, "null namespace manager");
aManager = mManager;
NS_ADDREF(aManager);
return NS_OK;
}
NS_IMETHODIMP
NameSpaceImpl::GetNameSpaceID(PRInt32& aID) const
{
aID = mID;
return NS_OK;
}
NS_IMETHODIMP
NameSpaceImpl::GetNameSpaceURI(nsString& aURI) const
{
NS_ASSERTION(nsnull != mManager, "null namespace manager");
return mManager->GetNameSpaceURI(mID, aURI);
}
NS_IMETHODIMP
NameSpaceImpl::GetNameSpacePrefix(nsIAtom*& aPrefix) const
{
aPrefix = mPrefix;
NS_IF_ADDREF(aPrefix);
return NS_OK;
}
NS_IMETHODIMP
NameSpaceImpl::GetParentNameSpace(nsINameSpace*& aParent) const
{
aParent = mParent;
NS_IF_ADDREF(aParent);
return NS_OK;
}
NS_IMETHODIMP
NameSpaceImpl::FindNameSpace(nsIAtom* aPrefix, nsINameSpace*& aNameSpace) const
{
const NameSpaceImpl* nameSpace = this;
do {
if (aPrefix == nameSpace->mPrefix) {
aNameSpace = (nsINameSpace*)nameSpace;
NS_ADDREF(aNameSpace);
return NS_OK;
}
nameSpace = nameSpace->mParent;
}
while (nsnull != nameSpace);
aNameSpace = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceImpl::FindNameSpaceID(nsIAtom* aPrefix, PRInt32& aNameSpaceID) const
{
const NameSpaceImpl* nameSpace = this;
do {
if (aPrefix == nameSpace->mPrefix) {
aNameSpaceID = nameSpace->mID;
return NS_OK;
}
nameSpace = nameSpace->mParent;
}
while (nsnull != nameSpace);
if (nsnull == aPrefix) {
aNameSpaceID = kNameSpaceID_None;
}
else {
aNameSpaceID = kNameSpaceID_Unknown;
}
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceImpl::FindNameSpacePrefix(PRInt32 aNameSpaceID, nsIAtom*& aPrefix) const
{
const NameSpaceImpl* nameSpace = this;
do {
if (aNameSpaceID == nameSpace->mID) {
aPrefix = nameSpace->mPrefix;
NS_IF_ADDREF(aPrefix);
return NS_OK;
}
nameSpace = nameSpace->mParent;
}
while (nsnull != nameSpace);
aPrefix = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceImpl::CreateChildNameSpace(nsIAtom* aPrefix, const nsString& aURI,
nsINameSpace*& aChildNameSpace)
{
NameSpaceImpl* child = new NameSpaceImpl(mManager, this, aPrefix, aURI);
if (child) {
return child->QueryInterface(kINameSpaceIID, (void**)&aChildNameSpace);
}
aChildNameSpace = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
NameSpaceImpl::CreateChildNameSpace(nsIAtom* aPrefix, PRInt32 aNameSpaceID,
nsINameSpace*& aChildNameSpace)
{
if (FindNameSpaceURI(aNameSpaceID)) {
NameSpaceImpl* child = new NameSpaceImpl(mManager, this, aPrefix, aNameSpaceID);
if (child) {
return child->QueryInterface(kINameSpaceIID, (void**)&aChildNameSpace);
}
aChildNameSpace = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
aChildNameSpace = nsnull;
return NS_ERROR_ILLEGAL_VALUE;
}
//-----------------------------------------------------------
// Name Space Manager
class NameSpaceManagerImpl : public nsINameSpaceManager {
public:
NameSpaceManagerImpl();
NS_DECL_ISUPPORTS
NS_IMETHOD CreateRootNameSpace(nsINameSpace*& aRootNameSpace);
NS_IMETHOD RegisterNameSpace(const nsString& aURI,
PRInt32& aNameSpaceID);
NS_IMETHOD GetNameSpaceURI(PRInt32 aNameSpaceID, nsString& aURI);
NS_IMETHOD GetNameSpaceID(const nsString& aURI, PRInt32& aNameSpaceID);
private:
// These are not supported and are not implemented!
NameSpaceManagerImpl(const NameSpaceManagerImpl& aCopy);
NameSpaceManagerImpl& operator=(const NameSpaceManagerImpl& aCopy);
protected:
virtual ~NameSpaceManagerImpl();
};
NameSpaceManagerImpl::NameSpaceManagerImpl()
{
NS_INIT_REFCNT();
AddRefTable();
}
NameSpaceManagerImpl::~NameSpaceManagerImpl()
{
ReleaseTable();
}
NS_IMPL_ISUPPORTS(NameSpaceManagerImpl, kINameSpaceManagerIID)
NS_IMETHODIMP
NameSpaceManagerImpl::CreateRootNameSpace(nsINameSpace*& aRootNameSpace)
{
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
aRootNameSpace = nsnull;
NameSpaceImpl* xmlns = new NameSpaceImpl(this, nsnull, nsLayoutAtoms::xmlnsNameSpace, kNameSpaceID_XMLNS);
if (nsnull != xmlns) {
NameSpaceImpl* xml = new NameSpaceImpl(this, xmlns, nsLayoutAtoms::xmlNameSpace, kNameSpaceID_XML);
if (nsnull != xml) {
rv = xml->QueryInterface(kINameSpaceIID, (void**)&aRootNameSpace);
}
else {
delete xmlns;
}
}
return rv;
}
NS_IMETHODIMP
NameSpaceManagerImpl::RegisterNameSpace(const nsString& aURI,
PRInt32& aNameSpaceID)
{
PRInt32 id = FindNameSpaceID(aURI);
if (kNameSpaceID_Unknown == id) {
nsString* uri = new nsString(aURI);
gURIArray->AppendElement(uri);
id = gURIArray->Count(); // id is index + 1
NameSpaceURIKey key(uri);
gURIToIDTable->Put(&key, (void*)id);
}
aNameSpaceID = id;
return NS_OK;
}
NS_IMETHODIMP
NameSpaceManagerImpl::GetNameSpaceURI(PRInt32 aNameSpaceID, nsString& aURI)
{
const nsString* result = FindNameSpaceURI(aNameSpaceID);
if (nsnull != result) {
aURI = *result;
return NS_OK;
}
aURI.Truncate();
return NS_ERROR_ILLEGAL_VALUE;
}
NS_IMETHODIMP
NameSpaceManagerImpl::GetNameSpaceID(const nsString& aURI, PRInt32& aNameSpaceID)
{
aNameSpaceID = FindNameSpaceID(aURI);
return NS_OK;
}
NS_LAYOUT nsresult
NS_NewNameSpaceManager(nsINameSpaceManager** aInstancePtrResult)
{
if (aInstancePtrResult == nsnull) {
return NS_ERROR_NULL_POINTER;
}
NameSpaceManagerImpl *it = new NameSpaceManagerImpl();
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kINameSpaceManagerIID, (void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,400 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsNodeInfo.h"
#include "nsNodeInfoManager.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIAtom.h"
#include "nsINameSpaceManager.h"
#include "nsIServiceManager.h"
#include "nsIPref.h" // Used by the temp pref, should be removed!
static PRBool kStrictDOMLevel2 = PR_FALSE;
nsNodeInfo::nsNodeInfo()
: mInner(), mOwnerManager(nsnull)
{
NS_INIT_REFCNT();
static PRInt32 been_here = 0;
// Temporary hack that tells if some new DOM Level 2 features are on or off
if (!been_here) {
kStrictDOMLevel2 = PR_FALSE; // Default in case of failure
nsresult rv;
NS_WITH_SERVICE(nsIPref, prefs, NS_PREF_PROGID, &rv);
if (NS_SUCCEEDED(rv)) {
prefs->GetBoolPref("temp.DOMLevel2update.enabled", &kStrictDOMLevel2);
}
been_here = 1;
}
// End of temp hack.
}
nsNodeInfo::~nsNodeInfo()
{
if (mOwnerManager) {
mOwnerManager->RemoveNodeInfo(this);
NS_RELEASE(mOwnerManager);
}
NS_IF_RELEASE(mInner.mName);
NS_IF_RELEASE(mInner.mPrefix);
}
nsresult
nsNodeInfo::Init(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
nsNodeInfoManager *aOwnerManager)
{
NS_ENSURE_TRUE(!mInner.mName && !mInner.mPrefix && !mOwnerManager,
NS_ERROR_ALREADY_INITIALIZED);
NS_ENSURE_ARG_POINTER(aName);
NS_ENSURE_ARG_POINTER(aOwnerManager);
mInner.mName = aName;
NS_ADDREF(mInner.mName);
mInner.mPrefix = aPrefix;
NS_IF_ADDREF(mInner.mPrefix);
mInner.mNamespaceID = aNamespaceID;
mOwnerManager = aOwnerManager;
NS_ADDREF(mOwnerManager);
return NS_OK;
}
// nsISupports
NS_IMPL_THREADSAFE_ISUPPORTS(nsNodeInfo, NS_GET_IID(nsINodeInfo));
// nsINodeInfo
NS_IMETHODIMP
nsNodeInfo::GetName(nsString& aName)
{
NS_ENSURE_TRUE(mInner.mName, NS_ERROR_NOT_INITIALIZED);
return mInner.mName->ToString(aName);
}
NS_IMETHODIMP
nsNodeInfo::GetNameAtom(nsIAtom*& aAtom)
{
NS_ABORT_IF_FALSE(mInner.mName, "nsNodeInfo not initialized!");
aAtom = mInner.mName;
NS_IF_ADDREF(aAtom);
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetQualifiedName(nsString& aQualifiedName)
{
NS_ENSURE_TRUE(mInner.mName, NS_ERROR_NOT_INITIALIZED);
if (mInner.mPrefix && kStrictDOMLevel2) {
mInner.mPrefix->ToString(aQualifiedName);
aQualifiedName.Append(PRUnichar(':'));
}
const PRUnichar *name;
mInner.mName->GetUnicode(&name);
aQualifiedName.Append(name);
if (kStrictDOMLevel2 && mInner.mPrefix) {
nsCAutoString tmp; tmp.AssignWithConversion(aQualifiedName);
printf ("Possible DOM Error: .name, .nodeName or .tagName requested on a namespace element/attribute with the qulaified name '%s', is this OK?\n", (const char *)tmp);
}
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetLocalName(nsString& aLocalName)
{
NS_ENSURE_TRUE(mInner.mName, NS_ERROR_NOT_INITIALIZED);
#ifdef STRICT_DOM_LEVEL2_LOCALNAME
if (mInner.mNamespaceID > 0) {
return mInner.mName->ToString(aLocalName);
}
aLocalName.Truncate();
return NS_OK;
#else
return mInner.mName->ToString(aLocalName);
#endif
}
NS_IMETHODIMP
nsNodeInfo::GetPrefix(nsString& aPrefix)
{
if (mInner.mPrefix) {
mInner.mPrefix->ToString(aPrefix);
} else {
aPrefix.Truncate();
}
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetPrefixAtom(nsIAtom*& aAtom)
{
aAtom = mInner.mPrefix;
NS_IF_ADDREF(aAtom);
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetNamespaceURI(nsString& aNameSpaceURI)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
nsresult rv = NS_OK;
if (mInner.mNamespaceID > 0) {
nsCOMPtr<nsINameSpaceManager> nsm;
mOwnerManager->GetNamespaceManager(*getter_AddRefs(nsm));
NS_ENSURE_TRUE(nsm, NS_ERROR_NOT_INITIALIZED);
rv = nsm->GetNameSpaceURI(mInner.mNamespaceID, aNameSpaceURI);
} else {
aNameSpaceURI.Truncate();
}
return rv;
}
NS_IMETHODIMP
nsNodeInfo::GetNamespaceID(PRInt32& aResult)
{
aResult = mInner.mNamespaceID;
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfo::GetNodeInfoManager(nsINodeInfoManager*& aNodeInfoManager)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
aNodeInfoManager = mOwnerManager;
NS_ADDREF(aNodeInfoManager);
return NS_OK;
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(nsIAtom *aNameAtom)
{
return mInner.mName == aNameAtom;
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(const nsString& aName)
{
if (!mInner.mName) return PR_FALSE;
const PRUnichar *name;
mInner.mName->GetUnicode(&name);
return aName.Equals(name);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom)
{
return (mInner.mName == aNameAtom) && (mInner.mPrefix == aPrefixAtom);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(const nsString& aName, const nsString& aPrefix)
{
if (!mInner.mName) return PR_FALSE;
const PRUnichar *name, *prefix = nsnull;
mInner.mName->GetUnicode(&name);
if (mInner.mPrefix)
mInner.mPrefix->GetUnicode(&prefix);
return aName.Equals(name) && aPrefix.Equals(prefix);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(nsIAtom *aNameAtom, PRInt32 aNamespaceID)
{
return (mInner.mName == aNameAtom) && (mInner.mNamespaceID == aNamespaceID);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(const nsString& aName, PRInt32 aNamespaceID)
{
if (!mInner.mName) return PR_FALSE;
const PRUnichar *name;
mInner.mName->GetUnicode(&name);
return aName.Equals(name) && (mInner.mNamespaceID == aNamespaceID);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom,
PRInt32 aNamespaceID)
{
return (mInner.mName == aNameAtom) &&
(mInner.mPrefix == aPrefixAtom) &&
(mInner.mNamespaceID == aNamespaceID);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::Equals(const nsString& aName, const nsString& aPrefix,
PRInt32 aNamespaceID)
{
if (!mInner.mName) return PR_FALSE;
const PRUnichar *name, *prefix = nsnull;
mInner.mName->GetUnicode(&name);
if (mInner.mPrefix)
mInner.mPrefix->GetUnicode(&prefix);
return aName.Equals(name) && aPrefix.Equals(prefix) &&
(mInner.mNamespaceID == aNamespaceID);
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::NamespaceEquals(PRInt32 aNamespaceID)
{
return mInner.mNamespaceID == aNamespaceID;
}
NS_IMETHODIMP_(PRBool)
nsNodeInfo::NamespaceEquals(const nsString& aNamespaceURI)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
nsCOMPtr<nsINameSpaceManager> nsmgr;
NS_ENSURE_SUCCESS(mOwnerManager->GetNamespaceManager(*getter_AddRefs(nsmgr)),
NS_ERROR_NOT_INITIALIZED);
PRInt32 nsid;
nsmgr->GetNameSpaceID(aNamespaceURI, nsid);
return mInner.mNamespaceID == nsid;
}
NS_IMETHODIMP
nsNodeInfo::NameChanged(nsIAtom *aName, nsINodeInfo*& aResult)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
return mOwnerManager->GetNodeInfo(aName, mInner.mPrefix, mInner.mNamespaceID,
aResult);
}
NS_IMETHODIMP
nsNodeInfo::PrefixChanged(nsIAtom *aPrefix, nsINodeInfo*& aResult)
{
NS_ENSURE_TRUE(mOwnerManager, NS_ERROR_NOT_INITIALIZED);
return mOwnerManager->GetNodeInfo(mInner.mName, aPrefix, mInner.mNamespaceID,
aResult);
}
PLHashNumber
nsNodeInfoInner::GetHashValue(const void *key)
{
#ifdef NS_DEBUG // Just to shut down a compiler warning
NS_WARN_IF_FALSE(key, "Null key passed to nsNodeInfo::GetHashValue!");
#endif
if (key) {
const nsNodeInfoInner *node = (const nsNodeInfoInner *)key;
// Is this an acceptable has value?
return (((PLHashNumber)node->mName) & 0xffff) >> 8;
}
return 0;
}
PRIntn
nsNodeInfoInner::KeyCompare(const void *key1, const void *key2)
{
#ifdef NS_DEBUG // Just to shut down a compiler warning
NS_WARN_IF_FALSE(key1 && key2, "Null key passed to nsNodeInfo::KeyCompare!");
#endif
if (!key1 || !key2) {
return PR_FALSE;
}
const nsNodeInfoInner *node1 = (const nsNodeInfoInner *)key1;
const nsNodeInfoInner *node2 = (const nsNodeInfoInner *)key2;
if (node1->mName == node2->mName &&
node1->mPrefix == node2->mPrefix &&
node1->mNamespaceID == node2->mNamespaceID) {
return PR_TRUE;
}
return PR_FALSE;
}

View File

@@ -0,0 +1,116 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsNodeInfo_h___
#define nsNodeInfo_h___
#include "nsINodeInfo.h"
#include "nsINameSpaceManager.h"
#include "plhash.h"
/*
* nsNodeInfoInner is used for two things:
*
* 1. as a member in nsNodeInfo for holding the name, prefix and
* namespace ID
* 2. as the hash key in the hash table in nsNodeInfoManager
*
* nsNodeInfoInner does not do any kind of reference counting, that's up
* to the user of this class, since nsNodeInfoInner is a member of
* nsNodeInfo the hash table doesn't need to delete the keys, when the
* value (nsNodeInfo) the key is automatically deleted.
*/
struct nsNodeInfoInner
{
nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
: mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID) {}
nsNodeInfoInner()
: mName(nsnull), mPrefix(nsnull), mNamespaceID(kNameSpaceID_None) {}
static PRIntn PR_CALLBACK KeyCompare(const void *key1, const void *key2);
static PLHashNumber PR_CALLBACK GetHashValue(const void *key);
nsIAtom* mName;
nsIAtom* mPrefix;
PRInt32 mNamespaceID;
};
class nsNodeInfoManager;
class nsNodeInfo : public nsINodeInfo
{
public:
NS_DECL_ISUPPORTS
// nsINodeInfo
NS_IMETHOD GetName(nsString& aName);
NS_IMETHOD GetNameAtom(nsIAtom*& aAtom);
NS_IMETHOD GetQualifiedName(nsString& aQualifiedName);
NS_IMETHOD GetLocalName(nsString& aLocalName);
NS_IMETHOD GetPrefix(nsString& aPrefix);
NS_IMETHOD GetPrefixAtom(nsIAtom*& aAtom);
NS_IMETHOD GetNamespaceURI(nsString& aNameSpaceURI);
NS_IMETHOD GetNamespaceID(PRInt32& aResult);
NS_IMETHOD GetNodeInfoManager(nsINodeInfoManager*& aNodeInfoManager);
NS_IMETHOD_(PRBool) Equals(nsIAtom *aNameAtom);
NS_IMETHOD_(PRBool) Equals(const nsString& aName);
NS_IMETHOD_(PRBool) Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom);
NS_IMETHOD_(PRBool) Equals(const nsString& aName,
const nsString& aPrefix);
NS_IMETHOD_(PRBool) Equals(nsIAtom *aNameAtom, PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) Equals(const nsString& aName, PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) Equals(nsIAtom *aNameAtom, nsIAtom *aPrefixAtom,
PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) Equals(const nsString& aName, const nsString& aPrefix,
PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) NamespaceEquals(PRInt32 aNamespaceID);
NS_IMETHOD_(PRBool) NamespaceEquals(const nsString& aNamespaceURI);
NS_IMETHOD NameChanged(nsIAtom *aName, nsINodeInfo*& aResult);
NS_IMETHOD PrefixChanged(nsIAtom *aPrefix, nsINodeInfo*& aResult);
// nsNodeInfo
nsNodeInfo();
virtual ~nsNodeInfo();
/*
* Note! Init() must be called exactly once on every nsNodeInfo before
* the object is used, if Init() returns an error code the nsNodeInfo
* should not be used.
*
* aName and aOwnerManager may not be null.
*/
nsresult Init(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
nsNodeInfoManager *aOwnerManager);
protected:
friend class nsNodeInfoManager; // The NodeInfoManager needs to pass this
// to the hash table.
nsNodeInfoInner mInner;
nsNodeInfoManager* mOwnerManager; // Strong reference!
};
#endif /* nsNodeInfo_h___ */

View File

@@ -0,0 +1,312 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsNodeInfoManager.h"
#include "nsNodeInfo.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIAtom.h"
nsNodeInfoManager* nsNodeInfoManager::gAnonymousNodeInfoManager = nsnull;
PRUint32 nsNodeInfoManager::gNodeManagerCount = 0;
nsresult NS_NewNodeInfoManager(nsINodeInfoManager** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = new nsNodeInfoManager;
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aResult);
return NS_OK;
}
nsNodeInfoManager::nsNodeInfoManager()
: mNameSpaceManager(nsnull)
{
NS_INIT_REFCNT();
if (gNodeManagerCount == 1 && gAnonymousNodeInfoManager) {
/*
* If we get here the global nodeinfo manager was the first one created,
* in that case we're not holding a strong reference to the global nodeinfo
* manager. Now we're creating one more nodeinfo manager so we'll grab
* a strong reference to the global nodeinfo manager so that it's
* lifetime will be longer than the lifetime of the other node managers.
*/
NS_ADDREF(gAnonymousNodeInfoManager);
}
gNodeManagerCount++;
mNodeInfoHash = PL_NewHashTable(32, nsNodeInfoInner::GetHashValue,
nsNodeInfoInner::KeyCompare,
PL_CompareValues, nsnull, nsnull);
#ifdef DEBUG_jst
printf ("Creating NodeInfoManager, gcount = %d\n", gNodeManagerCount);
#endif
}
nsNodeInfoManager::~nsNodeInfoManager()
{
gNodeManagerCount--;
if (gNodeManagerCount == 1 && gAnonymousNodeInfoManager) {
NS_RELEASE(gAnonymousNodeInfoManager);
} else if (!gNodeManagerCount) {
/*
* Here we just make sure that we don't leave a dangling pointer to
* the global nodeinfo manager after it's deleted.
*/
gAnonymousNodeInfoManager = nsnull;
}
if (mNodeInfoHash)
PL_HashTableDestroy(mNodeInfoHash);
#ifdef DEBUG_jst
printf ("Removing NodeInfoManager, gcount = %d\n", gNodeManagerCount);
#endif
}
NS_IMPL_THREADSAFE_ISUPPORTS(nsNodeInfoManager,
NS_GET_IID(nsINodeInfoManager));
// nsINodeInfoManager
NS_IMETHODIMP
nsNodeInfoManager::Init(nsINameSpaceManager *aNameSpaceManager)
{
NS_ENSURE_ARG_POINTER(aNameSpaceManager);
NS_ENSURE_TRUE(mNodeInfoHash, NS_ERROR_OUT_OF_MEMORY);
mNameSpaceManager = aNameSpaceManager;
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG_POINTER(aName);
nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID);
void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey);
if (node) {
aNodeInfo = NS_STATIC_CAST(nsINodeInfo *, node);
NS_ADDREF(aNodeInfo);
return NS_OK;
}
nsNodeInfo *newNodeInfo = new nsNodeInfo();
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(newNodeInfo);
nsresult rv = newNodeInfo->Init(aName, aPrefix, aNamespaceID, this);
NS_ENSURE_SUCCESS(rv, rv);
PLHashEntry *he;
he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
NS_ENSURE_TRUE(he, NS_ERROR_OUT_OF_MEMORY);
aNodeInfo = newNodeInfo;
return NS_OK;
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(const nsString& aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG(aName.Length());
nsCOMPtr<nsIAtom> name(dont_AddRef(NS_NewAtom(aName)));
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
return GetNodeInfo(name, aPrefix, aNamespaceID, aNodeInfo);
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(const nsString& aName, const nsString& aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG(aName.Length());
nsCOMPtr<nsIAtom> name(dont_AddRef(NS_NewAtom(aName)));
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIAtom> prefix;
if (aPrefix.Length()) {
prefix = dont_AddRef(NS_NewAtom(aPrefix));
NS_ENSURE_TRUE(prefix, NS_ERROR_OUT_OF_MEMORY);
}
return GetNodeInfo(name, prefix, aNamespaceID, aNodeInfo);
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(const nsString& aName, const nsString& aPrefix,
const nsString& aNamespaceURI,
nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG(aName.Length());
nsCOMPtr<nsIAtom> name(dont_AddRef(NS_NewAtom(aName)));
NS_ENSURE_TRUE(name, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIAtom> prefix;
if (aPrefix.Length()) {
prefix = dont_AddRef(NS_NewAtom(aPrefix));
NS_ENSURE_TRUE(prefix, NS_ERROR_OUT_OF_MEMORY);
}
PRInt32 nsid = kNameSpaceID_None;
if (aNamespaceURI.Length()) {
if (!mNameSpaceManager) {
return NS_ERROR_NOT_INITIALIZED;
}
nsresult rv = mNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsid);
NS_ENSURE_SUCCESS(rv, rv);
}
return GetNodeInfo(name, prefix, nsid, aNodeInfo);
}
NS_IMETHODIMP
nsNodeInfoManager::GetNodeInfo(const nsString& aQualifiedName,
const nsString& aNamespaceURI,
nsINodeInfo*& aNodeInfo)
{
NS_ENSURE_ARG(aQualifiedName.Length());
nsAutoString name(aQualifiedName);
nsAutoString prefix;
PRInt32 nsoffset = name.FindChar(':');
if (-1 != nsoffset) {
name.Left(prefix, nsoffset);
name.Cut(0, nsoffset+1);
}
nsCOMPtr<nsIAtom> nameAtom(dont_AddRef(NS_NewAtom(name)));
NS_ENSURE_TRUE(nameAtom, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIAtom> prefixAtom;
if (prefix.Length()) {
prefixAtom = dont_AddRef(NS_NewAtom(prefix));
NS_ENSURE_TRUE(prefixAtom, NS_ERROR_OUT_OF_MEMORY);
}
PRInt32 nsid = kNameSpaceID_None;
if (aNamespaceURI.Length()) {
NS_ENSURE_TRUE(mNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
nsresult rv = mNameSpaceManager->RegisterNameSpace(aNamespaceURI, nsid);
NS_ENSURE_SUCCESS(rv, rv);
}
return GetNodeInfo(nameAtom, prefixAtom, nsid, aNodeInfo);
}
NS_IMETHODIMP
nsNodeInfoManager::GetNamespaceManager(nsINameSpaceManager*& aNameSpaceManager)
{
NS_ENSURE_TRUE(mNameSpaceManager, NS_ERROR_NOT_INITIALIZED);
aNameSpaceManager = mNameSpaceManager;
NS_ADDREF(aNameSpaceManager);
return NS_OK;
}
void
nsNodeInfoManager::RemoveNodeInfo(nsNodeInfo *aNodeInfo)
{
NS_WARN_IF_FALSE(aNodeInfo, "Trying to remove null nodeinfo from manager!");
if (aNodeInfo) {
PRBool ret = PL_HashTableRemove(mNodeInfoHash, &aNodeInfo->mInner);
NS_WARN_IF_FALSE(ret, "Can't find nsINodeInfo to remove!!!");
}
}
nsresult
nsNodeInfoManager::GetAnonymousManager(nsINodeInfoManager*& aNodeInfoManager)
{
if (!gAnonymousNodeInfoManager) {
gAnonymousNodeInfoManager = new nsNodeInfoManager;
if (!gAnonymousNodeInfoManager)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(gAnonymousNodeInfoManager);
nsresult rv = NS_NewNameSpaceManager(getter_AddRefs(gAnonymousNodeInfoManager->mNameSpaceManager));
if (NS_FAILED(rv)) {
NS_RELEASE(gAnonymousNodeInfoManager);
return rv;
}
}
aNodeInfoManager = gAnonymousNodeInfoManager;
/*
* If the only nodeinfo manager is the global one we don't hold a ref
* since the global nodeinfo manager should be destroyed when it's released,
* even if it's the last one arround.
*/
if (gNodeManagerCount > 1) {
NS_ADDREF(aNodeInfoManager);
}
return NS_OK;
}

View File

@@ -0,0 +1,83 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsNodeInfoManager_h___
#define nsNodeInfoManager_h___
#include "nsINodeInfo.h"
#include "nsINameSpaceManager.h"
#include "nsCOMPtr.h"
#include "plhash.h"
class nsNodeInfo;
class nsNodeInfoManager : public nsINodeInfoManager
{
public:
NS_DECL_ISUPPORTS
// nsINodeInfoManager
NS_IMETHOD Init(nsINameSpaceManager *aNameSpaceManager);
NS_IMETHOD GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNodeInfo(const nsString& aName, nsIAtom *aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNodeInfo(const nsString& aName, const nsString& aPrefix,
PRInt32 aNamespaceID, nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNodeInfo(const nsString& aName, const nsString& aPrefix,
const nsString& aNamespaceURI,
nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNodeInfo(const nsString& aQualifiedName,
const nsString& aNamespaceURI,
nsINodeInfo*& aNodeInfo);
NS_IMETHOD GetNamespaceManager(nsINameSpaceManager*& aNameSpaceManager);
// nsNodeInfoManager
nsNodeInfoManager();
virtual ~nsNodeInfoManager();
void RemoveNodeInfo(nsNodeInfo *aNodeInfo);
static nsresult GetAnonymousManager(nsINodeInfoManager*& aNodeInfoManager);
private:
PLHashTable *mNodeInfoHash;
nsCOMPtr<nsINameSpaceManager> mNameSpaceManager;
/*
* gAnonymousNodeInfoManager is a global nodeinfo manager used for nodes
* that are no longer part of a document and for nodes that are created
* where no document is accessible.
*
* gAnonymousNodeInfoManager is allocated when requested for the first time
* and once the last nodeinfo manager (appart from gAnonymousNodeInfoManager)
* is destroyed gAnonymousNodeInfoManager is destroyed. If the global
* nodeinfo manager is the only nodeinfo manager used it can be deleted
* and later reallocated if all users of the nodeinfo manager drops the
* referernces to it.
*/
static nsNodeInfoManager *gAnonymousNodeInfoManager;
static PRUint32 gNodeManagerCount;
};
#endif /* nsNodeInfoManager_h___ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,205 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* IBM Corporation
*
* This Original Code has been modified by IBM Corporation.
* Modifications made by IBM described herein are
* Copyright (c) International Business Machines
* Corporation, 2000
*
* Modifications to Mozilla code or documentation
* identified per MPL Section 3.3
*
* Date Modified by Description of modification
* 03/20/2000 IBM Corp. BiDi - ability to change the default direction of the browser
* 04/20/2000 IBM Corp. OS/2 VisualAge build.
*
*/
#ifndef nsPresContext_h___
#define nsPresContext_h___
#include "nsIPresContext.h"
#include "nsIDeviceContext.h"
#include "nsVoidArray.h"
#include "nsFont.h"
#include "nsCRT.h"
#include "nsCOMPtr.h"
#include "nsIImageGroup.h"
#include "nsIPref.h"
#include "nsICharsetConverterManager.h"
#include "nsILanguageAtomService.h"
#include "nsIURL.h"
#include "nsIEventStateManager.h"
#include "nsIObserver.h"
// Base class for concrete presentation context classes
class nsPresContext : public nsIPresContext, public nsIObserver {
public:
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
// nsISupports methods
NS_DECL_ISUPPORTS
// nsIPresContext methods
NS_IMETHOD Init(nsIDeviceContext* aDeviceContext);
NS_IMETHOD Stop(void);
NS_IMETHOD SetShell(nsIPresShell* aShell);
NS_IMETHOD GetShell(nsIPresShell** aResult);
NS_IMETHOD GetCompatibilityMode(nsCompatibility* aModeResult);
NS_IMETHOD SetCompatibilityMode(nsCompatibility aMode);
NS_IMETHOD GetWidgetRenderingMode(nsWidgetRendering* aModeResult);
NS_IMETHOD SetWidgetRenderingMode(nsWidgetRendering aMode);
NS_IMETHOD GetImageAnimationMode(nsImageAnimation* aModeResult);
NS_IMETHOD SetImageAnimationMode(nsImageAnimation aMode);
NS_IMETHOD GetLookAndFeel(nsILookAndFeel** aLookAndFeel);
NS_IMETHOD GetBaseURL(nsIURI** aURLResult);
NS_IMETHOD GetMedium(nsIAtom** aMediumResult) = 0;
NS_IMETHOD RemapStyleAndReflow(void);
NS_IMETHOD ResolveStyleContextFor(nsIContent* aContent,
nsIStyleContext* aParentContext,
PRBool aForceUnique,
nsIStyleContext** aResult);
NS_IMETHOD ResolvePseudoStyleContextFor(nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
PRBool aForceUnique,
nsIStyleContext** aResult);
NS_IMETHOD ProbePseudoStyleContextFor(nsIContent* aParentContent,
nsIAtom* aPseudoTag,
nsIStyleContext* aParentContext,
PRBool aForceUnique,
nsIStyleContext** aResult);
NS_IMETHOD ReParentStyleContext(nsIFrame* aFrame,
nsIStyleContext* aNewParentContext);
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIFontMetrics** aResult);
NS_IMETHOD GetDefaultFont(nsFont& aResult);
NS_IMETHOD SetDefaultFont(const nsFont& aFont);
virtual const nsFont& GetDefaultFontDeprecated();
NS_IMETHOD GetDefaultFixedFont(nsFont& aResult);
NS_IMETHOD SetDefaultFixedFont(const nsFont& aFont);
virtual const nsFont& GetDefaultFixedFontDeprecated();
NS_IMETHOD GetFontScaler(PRInt32* aResult);
NS_IMETHOD SetFontScaler(PRInt32 aScaler);
NS_IMETHOD GetDefaultColor(nscolor* aColor);
NS_IMETHOD GetDefaultBackgroundColor(nscolor* aColor);
NS_IMETHOD GetDefaultBackgroundImage(nsString& aImage);
NS_IMETHOD GetDefaultBackgroundImageRepeat(PRUint8* aRepeat);
NS_IMETHOD GetDefaultBackgroundImageOffset(nscoord* aX, nscoord* aY);
NS_IMETHOD GetDefaultBackgroundImageAttachment(PRUint8* aRepeat);
NS_IMETHOD SetDefaultColor(nscolor aColor);
NS_IMETHOD SetDefaultBackgroundColor(nscolor aColor);
NS_IMETHOD SetDefaultBackgroundImage(const nsString& aImage);
NS_IMETHOD SetDefaultBackgroundImageRepeat(PRUint8 aRepeat);
NS_IMETHOD SetDefaultBackgroundImageOffset(nscoord aX, nscoord aY);
NS_IMETHOD SetDefaultBackgroundImageAttachment(PRUint8 aRepeat);
NS_IMETHOD GetImageGroup(nsIImageGroup** aGroupResult);
NS_IMETHOD StartLoadImage(const nsString& aURL,
const nscolor* aBackgroundColor,
const nsSize* aDesiredSize,
nsIFrame* aTargetFrame,
nsIFrameImageLoaderCB aCallBack,
void* aClosure,
nsIFrameImageLoader** aResult);
NS_IMETHOD StopLoadImage(nsIFrame* aForFrame, nsIFrameImageLoader* aLoader);
NS_IMETHOD StopAllLoadImagesFor(nsIFrame* aForFrame);
NS_IMETHOD SetContainer(nsISupports* aContainer);
NS_IMETHOD GetContainer(nsISupports** aResult);
NS_IMETHOD SetLinkHandler(nsILinkHandler* aHandler);
NS_IMETHOD GetLinkHandler(nsILinkHandler** aResult);
NS_IMETHOD GetVisibleArea(nsRect& aResult);
NS_IMETHOD SetVisibleArea(const nsRect& r);
NS_IMETHOD IsPaginated(PRBool* aResult) = 0;
NS_IMETHOD GetPageWidth(nscoord* aResult) = 0;
NS_IMETHOD GetPageHeight(nscoord* aResult) = 0;
NS_IMETHOD GetPixelsToTwips(float* aResult) const;
NS_IMETHOD GetTwipsToPixels(float* aResult) const;
NS_IMETHOD GetScaledPixelsToTwips(float* aScale) const;
NS_IMETHOD GetDeviceContext(nsIDeviceContext** aResult) const;
NS_IMETHOD GetEventStateManager(nsIEventStateManager** aManager);
NS_IMETHOD GetDefaultDirection(PRUint8* aDirection);
NS_IMETHOD SetDefaultDirection(PRUint8 aDirection);
NS_IMETHOD GetLanguage(nsILanguageAtom** aLanguage);
#ifdef MOZ_REFLOW_PERF
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType);
#endif
// nsIObserver method
NS_IMETHOD Observe(nsISupports* aSubject, const PRUnichar* aTopic,
const PRUnichar* aData);
protected:
nsPresContext();
virtual ~nsPresContext();
// IMPORTANT: The ownership implicit in the following member variables has been
// explicitly checked and set using nsCOMPtr for owning pointers and raw COM interface
// pointers for weak (ie, non owning) references. If you add any members to this
// class, please make the ownership explicit (pinkerton, scc).
nsIPresShell* mShell; // [WEAK]
nsCOMPtr<nsIPref> mPrefs;
nsRect mVisibleArea;
nsCOMPtr<nsIDeviceContext> mDeviceContext; // could be weak, but better safe than sorry. Cannot reintroduce cycles
// since there is no dependency from gfx back to layout.
nsCOMPtr<nsILanguageAtomService> mLangService;
nsCOMPtr<nsILanguageAtom> mLanguage;
nsCOMPtr<nsIImageGroup> mImageGroup;
nsILinkHandler* mLinkHandler; // [WEAK]
nsISupports* mContainer; // [WEAK]
nsILookAndFeel* mLookAndFeel;
nsFont mDefaultFont;
nsFont mDefaultFixedFont;
PRInt32 mFontScaler;
nscolor mDefaultColor;
nscolor mDefaultBackgroundColor;
nsString mDefaultBackgroundImage;
PRUint8 mDefaultBackgroundImageRepeat;
nscoord mDefaultBackgroundImageOffsetX;
nscoord mDefaultBackgroundImageOffsetY;
PRUint8 mDefaultBackgroundImageAttachment;
nsVoidArray mImageLoaders;
nsCOMPtr<nsIEventStateManager> mEventManager;
nsCOMPtr<nsIURI> mBaseURL;
nsCompatibility mCompatibilityMode;
PRPackedBool mCompatibilityLocked;
nsWidgetRendering mWidgetRenderingMode;
nsImageAnimation mImageAnimationMode;
PRPackedBool mImageAnimationStopped; // image animation stopped
PRPackedBool mStopped; // loading stopped
PRUint8 mDefaultDirection;
#ifdef DEBUG
PRBool mInitialized;
#endif
protected:
void GetUserPreferences();
void GetFontPreferences();
private:
friend int PR_CALLBACK PrefChangedCallback(const char*, void*);
void PreferenceChanged(const char* aPrefName);
};
#endif /* nsPresContext_h___ */

View File

@@ -0,0 +1,135 @@
#include "nsCOMPtr.h"
#include "nsIPresState.h"
#include "nsHashtable.h"
#include "nsISupportsPrimitives.h"
#include "nsIComponentManager.h"
// Static IIDs/CIDs. Try to minimize these.
// None
class nsPresState: public nsIPresState
{
NS_DECL_ISUPPORTS
NS_IMETHOD GetStatePropertyAsSupports(const nsString& aName, nsISupports** aResult);
NS_IMETHOD SetStatePropertyAsSupports(const nsString& aName, nsISupports* aValue);
NS_IMETHOD GetStateProperty(const nsString& aProperty, nsString& aResult);
NS_IMETHOD SetStateProperty(const nsString& aProperty, const nsString& aValue);
public:
nsPresState();
virtual ~nsPresState();
// Static members
// Internal member functions
protected:
// MEMBER VARIABLES
protected:
// A string table that holds property/value pairs.
nsSupportsHashtable* mPropertyTable;
};
// Static initialization
// Implementation /////////////////////////////////////////////////////////////////
// Implement our nsISupports methods
NS_IMPL_ISUPPORTS1(nsPresState, nsIPresState)
// Constructors/Destructors
nsPresState::nsPresState(void)
:mPropertyTable(nsnull)
{
NS_INIT_REFCNT();
}
nsPresState::~nsPresState(void)
{
delete mPropertyTable;
}
// nsIPresState Interface ////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsPresState::GetStateProperty(const nsString& aName, nsString& aResult)
{
// Retrieve from hashtable.
nsCOMPtr<nsISupportsWString> str;
nsStringKey key(aName);
if (mPropertyTable)
str = dont_AddRef(NS_STATIC_CAST(nsISupportsWString*, mPropertyTable->Get(&key)));
if (str) {
PRUnichar* data;
str->GetData(&data);
aResult = data;
nsMemory::Free(data);
} else {
aResult.SetLength(0);
}
return NS_OK;
}
NS_IMETHODIMP
nsPresState::SetStateProperty(const nsString& aName, const nsString& aValue)
{
if (!mPropertyTable)
mPropertyTable = new nsSupportsHashtable(8);
// Add to hashtable
nsStringKey key(aName);
nsCOMPtr<nsISupportsWString> supportsStr;
nsresult rv = nsComponentManager::CreateInstance(NS_SUPPORTS_WSTRING_PROGID, nsnull,
NS_GET_IID(nsISupportsWString), getter_AddRefs(supportsStr));
PRUnichar* val = aValue.ToNewUnicode();
supportsStr->SetData(val);
nsMemory::Free(val);
mPropertyTable->Put(&key, supportsStr);
return NS_OK;
}
NS_IMETHODIMP
nsPresState::GetStatePropertyAsSupports(const nsString& aName, nsISupports** aResult)
{
// Retrieve from hashtable.
nsCOMPtr<nsISupports> supp;
nsStringKey key(aName);
if (mPropertyTable)
supp = dont_AddRef(NS_STATIC_CAST(nsISupports*, mPropertyTable->Get(&key)));
*aResult = supp;
NS_IF_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsPresState::SetStatePropertyAsSupports(const nsString& aName, nsISupports* aValue)
{
if (!mPropertyTable)
mPropertyTable = new nsSupportsHashtable(8);
// Add to hashtable
nsStringKey key(aName);
mPropertyTable->Put(&key, aValue);
return NS_OK;
}
// Creation Routine ///////////////////////////////////////////////////////////////////////
nsresult
NS_NewPresState(nsIPresState** aResult)
{
*aResult = new nsPresState;
if (!*aResult)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult);
return NS_OK;
}

View File

@@ -0,0 +1,122 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsPresContext.h"
#include "nsIDeviceContext.h"
#include "nsUnitConversion.h"
#include "nsIView.h"
#include "nsIWidget.h"
#include "nsGfxCIID.h"
#include "nsLayoutAtoms.h"
static NS_DEFINE_IID(kIPresContextIID, NS_IPRESCONTEXT_IID);
class PrintContext : public nsPresContext {
public:
PrintContext();
~PrintContext();
NS_IMETHOD GetMedium(nsIAtom** aMedium);
NS_IMETHOD IsPaginated(PRBool* aResult);
NS_IMETHOD GetPageWidth(nscoord* aResult);
NS_IMETHOD GetPageHeight(nscoord* aResult);
};
PrintContext::PrintContext()
{
}
PrintContext::~PrintContext()
{
}
NS_IMETHODIMP
PrintContext::GetMedium(nsIAtom** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = nsLayoutAtoms::print;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
PrintContext::IsPaginated(PRBool* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
PrintContext::GetPageWidth(nscoord* aResult)
{
PRInt32 width,height;
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
mDeviceContext->GetDeviceSurfaceDimensions(width,height);
// a xp margin can be added here
*aResult = width;
return NS_OK;
}
NS_IMETHODIMP
PrintContext::GetPageHeight(nscoord* aResult)
{
PRInt32 width,height;
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
mDeviceContext->GetDeviceSurfaceDimensions(width,height);
// a xp margin or header/footer space can be added here
*aResult = height;
return NS_OK;
}
NS_LAYOUT nsresult
NS_NewPrintContext(nsIPresContext** aInstancePtrResult)
{
if (aInstancePtrResult == nsnull) {
return NS_ERROR_NULL_POINTER;
}
PrintContext *it = new PrintContext;
if (it == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIPresContextIID, (void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,155 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsPresContext.h"
#include "nsIDeviceContext.h"
#include "nsUnitConversion.h"
#include "nsIView.h"
#include "nsIWidget.h"
#include "nsGfxCIID.h"
#include "nsLayoutAtoms.h"
#include "prlog.h"
static NS_DEFINE_IID(kIPresContextIID, NS_IPRESCONTEXT_IID);
class PrintPreviewContext : public nsPresContext {
public:
PrintPreviewContext();
~PrintPreviewContext();
NS_IMETHOD GetMedium(nsIAtom** aMedium);
NS_IMETHOD IsPaginated(PRBool* aResult);
NS_IMETHOD GetPageWidth(nscoord* aResult);
NS_IMETHOD GetPageHeight(nscoord* aResult);
#ifdef NS_DEBUG
static PRBool UseFakePageSize();
#endif
};
#ifdef NS_DEBUG
PRBool
PrintPreviewContext::UseFakePageSize()
{
static PRLogModuleInfo* pageSizeLM;
static PRBool useFakePageSize = PR_FALSE;
if (nsnull == pageSizeLM) {
pageSizeLM = PR_NewLogModule("pagesize");
if (nsnull != pageSizeLM) {
useFakePageSize = 0 != pageSizeLM->level;
}
}
return useFakePageSize;
}
#endif
PrintPreviewContext::PrintPreviewContext()
{
}
PrintPreviewContext::~PrintPreviewContext()
{
}
NS_IMETHODIMP
PrintPreviewContext::GetMedium(nsIAtom** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = nsLayoutAtoms::print;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
PrintPreviewContext::IsPaginated(PRBool* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
PrintPreviewContext::GetPageWidth(nscoord* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
#ifdef NS_DEBUG
if (UseFakePageSize()) {
// For testing purposes make the page width smaller than the visible
// area
float sbWidth, sbHeight;
mDeviceContext->GetScrollBarDimensions(sbWidth, sbHeight);
nscoord sbar = NSToCoordRound(sbWidth);
*aResult = mVisibleArea.width - sbar - 2*100;
return NS_OK;
}
#endif
// XXX assumes a 1/2 margin around all sides
*aResult = (nscoord) NS_INCHES_TO_TWIPS(7.5);
return NS_OK;
}
NS_IMETHODIMP
PrintPreviewContext::GetPageHeight(nscoord* aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
if (nsnull == aResult) {
return NS_ERROR_NULL_POINTER;
}
#ifdef NS_DEBUG
if (UseFakePageSize()) {
// For testing purposes make the page height 60% of the visible area
*aResult = mVisibleArea.height * 60 / 100;
return NS_OK;
}
#endif
// XXX assumes a 1/2 margin around all sides
*aResult = (nscoord) NS_INCHES_TO_TWIPS(10);
return NS_OK;
}
NS_LAYOUT nsresult
NS_NewPrintPreviewContext(nsIPresContext** aInstancePtrResult)
{
if (aInstancePtrResult == nsnull) {
return NS_ERROR_NULL_POINTER;
}
PrintPreviewContext *it = new PrintPreviewContext();
if (it == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIPresContextIID, (void **) aInstancePtrResult);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,232 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsRange_h___
#define nsRange_h___
/*
* nsRange.h: interface of the nsRange object.
*/
#include "nsIDOMRange.h"
#include "nsIDOMNSRange.h"
#include "nsCOMPtr.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIScriptObjectOwner.h"
#include "prmon.h"
class nsVoidArray;
class nsRange : public nsIDOMRange,
public nsIDOMNSRange,
public nsIScriptObjectOwner
{
public:
NS_DECL_ISUPPORTS
nsRange();
virtual ~nsRange();
// nsIDOMRange interface
NS_IMETHOD GetIsPositioned(PRBool* aIsPositioned);
NS_IMETHOD GetStartParent(nsIDOMNode** aStartParent);
NS_IMETHOD GetStartOffset(PRInt32* aStartOffset);
NS_IMETHOD GetEndParent(nsIDOMNode** aEndParent);
NS_IMETHOD GetEndOffset(PRInt32* aEndOffset);
NS_IMETHOD GetIsCollapsed(PRBool* aIsCollapsed);
NS_IMETHOD GetCommonParent(nsIDOMNode** aCommonParent);
NS_IMETHOD SetStart(nsIDOMNode* aParent, PRInt32 aOffset);
NS_IMETHOD SetStartBefore(nsIDOMNode* aSibling);
NS_IMETHOD SetStartAfter(nsIDOMNode* aSibling);
NS_IMETHOD SetEnd(nsIDOMNode* aParent, PRInt32 aOffset);
NS_IMETHOD SetEndBefore(nsIDOMNode* aSibling);
NS_IMETHOD SetEndAfter(nsIDOMNode* aSibling);
NS_IMETHOD Collapse(PRBool aToStart);
NS_IMETHOD Unposition();
NS_IMETHOD SelectNode(nsIDOMNode* aN);
NS_IMETHOD SelectNodeContents(nsIDOMNode* aN);
NS_IMETHOD CompareEndPoints(PRUint16 how, nsIDOMRange* srcRange, PRInt32* ret);
NS_IMETHOD DeleteContents();
NS_IMETHOD ExtractContents(nsIDOMDocumentFragment** aReturn);
NS_IMETHOD CloneContents(nsIDOMDocumentFragment** aReturn);
NS_IMETHOD InsertNode(nsIDOMNode* aN);
NS_IMETHOD SurroundContents(nsIDOMNode* aN);
NS_IMETHOD Clone(nsIDOMRange** aReturn);
NS_IMETHOD ToString(nsString& aReturn);
/*BEGIN nsIDOMNSRange interface implementations*/
NS_IMETHOD CreateContextualFragment(const nsString& aFragment,
nsIDOMDocumentFragment** aReturn);
NS_IMETHOD IsValidFragment(const nsString& aFragment, PRBool* aReturn);
NS_IMETHOD IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset,
PRBool* aResult);
NS_IMETHOD ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset,
PRInt16* aResult);
NS_IMETHOD IntersectsNode(nsIDOMNode* aNode, PRBool* aReturn);
NS_IMETHOD CompareNode(nsIDOMNode* aNode, PRInt16* aReturn);
/*END nsIDOMNSRange interface implementations*/
NS_IMETHOD GetHasGeneratedBefore(PRBool *aBool);
NS_IMETHOD GetHasGeneratedAfter(PRBool *aBool);
NS_IMETHOD SetHasGeneratedBefore(PRBool aBool);
NS_IMETHOD SetHasGeneratedAfter(PRBool aBool);
NS_IMETHOD SetBeforeAndAfter(PRBool aBefore, PRBool aAfter);
/*BEGIN nsIScriptObjectOwner interface implementations*/
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
/*END nsIScriptObjectOwner interface implementations*/
// nsRange interface extensions
static NS_METHOD OwnerGone(nsIContent* aParentNode);
static NS_METHOD OwnerChildInserted(nsIContent* aParentNode, PRInt32 aOffset);
static NS_METHOD OwnerChildRemoved(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aRemovedNode);
static NS_METHOD OwnerChildReplaced(nsIContent* aParentNode, PRInt32 aOffset, nsIContent* aReplacedNode);
static NS_METHOD TextOwnerChanged(nsIContent* aTextNode, PRInt32 aStartOffset, PRInt32 aEndOffset, PRInt32 aReplaceLength);
//private: I wish VC++ would give me a &&*@!#$ break
PRBool mIsPositioned;
PRInt32 mStartOffset;
PRInt32 mEndOffset;
nsCOMPtr<nsIDOMNode> mStartParent;
nsCOMPtr<nsIDOMNode> mEndParent;
static PRMonitor *mMonitor; // monitor to protect the following statics
static nsVoidArray *mStartAncestors; // just keeping these static to avoid reallocing the arrays.
static nsVoidArray *mEndAncestors; // the contents of these arrays are discarded across calls.
static nsVoidArray *mStartAncestorOffsets; // this also makes nsRange objects lighter weight.
static nsVoidArray *mEndAncestorOffsets; //
// no copy's or assigns
nsRange(const nsRange&);
nsRange& operator=(const nsRange&);
// helper routines
static PRBool InSameDoc(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
static PRInt32 IndexOf(nsIDOMNode* aNode);
static PRInt32 FillArrayWithAncestors(nsVoidArray* aArray,nsIDOMNode* aNode);
static nsCOMPtr<nsIDOMNode> CommonParent(nsIDOMNode* aNode1, nsIDOMNode* aNode2);
static nsresult GetDOMNodeFromContent(nsIContent* inContentNode, nsCOMPtr<nsIDOMNode>* outDomNode);
static nsresult GetContentFromDOMNode(nsIDOMNode* inDomNode, nsCOMPtr<nsIContent>* outContentNode);
static nsresult PopRanges(nsIDOMNode* aDestNode, PRInt32 aOffset, nsIContent* aSourceNode);
static nsresult Lock();
static nsresult Unlock();
static nsresult CloneSibsAndParents(nsIDOMNode* parentNode,
PRInt32 nodeOffset,
nsIDOMNode* clonedNode,
nsIDOMNode* commonParent,
nsIDOMDocumentFragment* docfrag,
PRBool leftP);
nsresult DoSetRange(nsIDOMNode* aStartN, PRInt32 aStartOffset,
nsIDOMNode* aEndN, PRInt32 aEndOffset);
PRBool IsIncreasing(nsIDOMNode* aStartN, PRInt32 aStartOff,
nsIDOMNode* aEndN, PRInt32 aEndOff);
nsresult ComparePointToRange(nsIDOMNode* aParent, PRInt32 aOffset, PRInt32* aResult);
PRInt32 GetAncestorsAndOffsets(nsIDOMNode* aNode, PRInt32 aOffset,
nsVoidArray* aAncestorNodes, nsVoidArray* aAncestorOffsets);
nsresult AddToListOf(nsIDOMNode* aNode);
nsresult RemoveFromListOf(nsIDOMNode* aNode);
nsresult ContentOwnsUs(nsIDOMNode* domNode);
protected:
void* mScriptObject;
PRBool mBeforeGenContent;
PRBool mAfterGenContent;
};
// Make a new nsIDOMRange object
nsresult NS_NewRange(nsIDOMRange** aInstancePtrResult);
/*************************************************************************************
* Utility routine to compare two "points", were a point is a node/offset pair
* Returns -1 if point1 < point2, 1, if point1 > point2,
* 0 if error or if point1 == point2.
************************************************************************************/
PRInt32 ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
nsIDOMNode* aParent2, PRInt32 aOffset2);
/*************************************************************************************
* Utility routine to detect if a content node intersects a range
************************************************************************************/
PRBool IsNodeIntersectsRange(nsIContent* aNode, nsIDOMRange* aRange);
/*************************************************************************************
* Utility routine to detect if a content node starts before a range and/or
* ends after a range. If neither it is contained inside the range.
*
* XXX - callers responsibility to ensure node in same doc as range!
*
************************************************************************************/
nsresult CompareNodeToRange(nsIContent* aNode,
nsIDOMRange* aRange,
PRBool *outNodeBefore,
PRBool *outNodeAfter);
/*************************************************************************************
* Utility routine to create a pair of dom points to represent
* the start and end locations of a single node. Return false
* if we dont' succeed.
************************************************************************************/
PRBool GetNodeBracketPoints(nsIContent* aNode,
nsCOMPtr<nsIDOMNode>* outParent,
PRInt32* outStartOffset,
PRInt32* outEndOffset);
#endif /* nsRange_h___ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,177 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsSpaceManager_h___
#define nsSpaceManager_h___
#include "nsISpaceManager.h"
#include "prclist.h"
/**
* Implementation of nsISpaceManager that maintains a region data structure of
* unavailable space
*/
class nsSpaceManager : public nsISpaceManager {
public:
nsSpaceManager(nsIFrame* aFrame);
// nsISupports
NS_DECL_ISUPPORTS
// nsISpaceManager
NS_IMETHOD GetFrame(nsIFrame*& aFrame) const;
NS_IMETHOD Translate(nscoord aDx, nscoord aDy);
NS_IMETHOD GetTranslation(nscoord& aX, nscoord& aY) const;
NS_IMETHOD YMost(nscoord& aYMost) const;
NS_IMETHOD GetBandData(nscoord aYOffset,
const nsSize& aMaxSize,
nsBandData& aBandData) const;
NS_IMETHOD AddRectRegion(nsIFrame* aFrame,
const nsRect& aUnavailableSpace);
NS_IMETHOD ResizeRectRegion(nsIFrame* aFrame,
nscoord aDeltaWidth,
nscoord aDeltaHeight,
AffectedEdge aEdge);
NS_IMETHOD OffsetRegion(nsIFrame* aFrame, nscoord aDx, nscoord aDy);
NS_IMETHOD RemoveRegion(nsIFrame* aFrame);
NS_IMETHOD ClearRegions();
#ifdef DEBUG
NS_IMETHOD List(FILE* out);
void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
#endif
protected:
// Structure that maintains information about the region associated
// with a particular frame
struct FrameInfo {
nsIFrame* const mFrame;
nsRect mRect; // rectangular region
FrameInfo* mNext;
FrameInfo(nsIFrame* aFrame, const nsRect& aRect);
#ifdef DEBUG
~FrameInfo();
#endif
};
public:
// Doubly linked list of band rects
struct BandRect : PRCListStr {
nscoord mLeft, mTop;
nscoord mRight, mBottom;
PRIntn mNumFrames; // number of frames occupying this rect
union {
nsIFrame* mFrame; // single frame occupying the space
nsVoidArray* mFrames; // list of frames occupying the space
};
BandRect(nscoord aLeft, nscoord aTop,
nscoord aRight, nscoord aBottom,
nsIFrame*);
BandRect(nscoord aLeft, nscoord aTop,
nscoord aRight, nscoord aBottom,
nsVoidArray*);
~BandRect();
// List operations
BandRect* Next() const {return (BandRect*)PR_NEXT_LINK(this);}
BandRect* Prev() const {return (BandRect*)PR_PREV_LINK(this);}
void InsertBefore(BandRect* aBandRect) {PR_INSERT_BEFORE(aBandRect, this);}
void InsertAfter(BandRect* aBandRect) {PR_INSERT_AFTER(aBandRect, this);}
void Remove() {PR_REMOVE_LINK(this);}
// Split the band rect into two vertically, with this band rect becoming
// the top part, and a new band rect being allocated and returned for the
// bottom part
//
// Does not insert the new band rect into the linked list
BandRect* SplitVertically(nscoord aBottom);
// Split the band rect into two horizontally, with this band rect becoming
// the left part, and a new band rect being allocated and returned for the
// right part
//
// Does not insert the new band rect into the linked list
BandRect* SplitHorizontally(nscoord aRight);
// Accessor functions
PRBool IsOccupiedBy(const nsIFrame*) const;
void AddFrame(const nsIFrame*);
void RemoveFrame(const nsIFrame*);
PRBool HasSameFrameList(const BandRect* aBandRect) const;
PRInt32 Length() const;
};
// Circular linked list of band rects
struct BandList : BandRect {
BandList();
// Accessors
PRBool IsEmpty() const {return PR_CLIST_IS_EMPTY((PRCListStr*)this);}
BandRect* Head() const {return (BandRect*)PR_LIST_HEAD(this);}
BandRect* Tail() const {return (BandRect*)PR_LIST_TAIL(this);}
// Operations
void Append(BandRect* aBandRect) {PR_APPEND_LINK(aBandRect, this);}
// Remove and delete all the band rects in the list
void Clear();
};
protected:
nsIFrame* const mFrame; // frame associated with the space manager
nscoord mX, mY; // translation from local to global coordinate space
BandList mBandList; // header/sentinel for circular linked list of band rects
FrameInfo* mFrameInfoMap;
protected:
virtual ~nsSpaceManager();
FrameInfo* GetFrameInfoFor(nsIFrame* aFrame);
FrameInfo* CreateFrameInfo(nsIFrame* aFrame, const nsRect& aRect);
void DestroyFrameInfo(FrameInfo*);
void ClearFrameInfo();
void ClearBandRects();
BandRect* GetNextBand(const BandRect* aBandRect) const;
void DivideBand(BandRect* aBand, nscoord aBottom);
PRBool CanJoinBands(BandRect* aBand, BandRect* aPrevBand);
PRBool JoinBands(BandRect* aBand, BandRect* aPrevBand);
void AddRectToBand(BandRect* aBand, BandRect* aBandRect);
void InsertBandRect(BandRect* aBandRect);
nsresult GetBandAvailableSpace(const BandRect* aBand,
nscoord aY,
const nsSize& aMaxSize,
nsBandData& aAvailableSpace) const;
private:
nsSpaceManager(const nsSpaceManager&); // no implementation
void operator=(const nsSpaceManager&); // no implementation
};
#endif /* nsSpaceManager_h___ */

View File

@@ -0,0 +1,121 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsStyleChangeList.h"
#include "nsStyleConsts.h"
#include "nsIFrame.h"
#include "nsIContent.h"
#include "nsCRT.h"
static const PRUint32 kGrowArrayBy = 10;
MOZ_DECL_CTOR_COUNTER(nsStyleChangeList);
nsStyleChangeList::nsStyleChangeList(void)
: mArray(mBuffer),
mArraySize(kStyleChangeBufferSize),
mCount(0)
{
MOZ_COUNT_CTOR(nsStyleChangeList);
}
nsStyleChangeList::~nsStyleChangeList(void)
{
MOZ_COUNT_DTOR(nsStyleChangeList);
Clear();
}
nsresult
nsStyleChangeList::ChangeAt(PRInt32 aIndex, nsIFrame*& aFrame, nsIContent*& aContent,
PRInt32& aHint) const
{
if ((0 <= aIndex) && (aIndex < mCount)) {
aFrame = mArray[aIndex].mFrame;
aContent = mArray[aIndex].mContent;
aHint = mArray[aIndex].mHint;
return NS_OK;
}
return NS_ERROR_ILLEGAL_VALUE;
}
nsresult
nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, PRInt32 aHint)
{
NS_ASSERTION(aFrame || (aHint >= NS_STYLE_HINT_FRAMECHANGE), "must have frame");
NS_ASSERTION(aContent || (aHint < NS_STYLE_HINT_FRAMECHANGE), "must have content");
if ((0 < mCount) && (NS_STYLE_HINT_FRAMECHANGE == aHint)) { // filter out all other changes for same content
if (aContent) {
PRInt32 index = mCount;
while (0 < index--) {
if (aContent == mArray[index].mContent) { // remove this change
mCount--;
if (index < mCount) { // move later changes down
nsCRT::memcpy(&(mArray[index]), &(mArray[index + 1]),
(mCount - index) * sizeof(nsStyleChangeData));
}
}
}
}
}
PRInt32 last = mCount - 1;
if ((0 < mCount) && aFrame && (aFrame == mArray[last].mFrame)) { // same as last frame
if (mArray[last].mHint < aHint) {
mArray[last].mHint = aHint;
}
}
else {
if (mCount == mArraySize) {
PRInt32 newSize = mArraySize + kGrowArrayBy;
nsStyleChangeData* newArray = new nsStyleChangeData[newSize];
if (newArray) {
nsCRT::memcpy(newArray, mArray, mCount * sizeof(nsStyleChangeData));
if (mArray != mBuffer) {
delete [] mArray;
}
mArray = newArray;
mArraySize = newSize;
}
else {
return NS_ERROR_OUT_OF_MEMORY;
}
}
mArray[mCount].mFrame = aFrame;
mArray[mCount].mContent = aContent;
mArray[mCount].mHint = aHint;
mCount++;
}
return NS_OK;
}
void
nsStyleChangeList::Clear()
{
if (mArray != mBuffer) {
delete [] mArray;
mArray = mBuffer;
mArraySize = kStyleChangeBufferSize;
}
mCount = 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,284 @@
/* -*- 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.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsStyleCoord.h"
#include "nsString.h"
#include "nsCRT.h"
nsStyleCoord::nsStyleCoord(nsStyleUnit aUnit)
: mUnit(aUnit)
{
NS_ASSERTION(aUnit < eStyleUnit_Percent, "not a valueless unit");
if (aUnit >= eStyleUnit_Percent) {
mUnit = eStyleUnit_Null;
}
mValue.mInt = 0;
}
nsStyleCoord::nsStyleCoord(nscoord aValue)
: mUnit(eStyleUnit_Coord)
{
mValue.mInt = aValue;
}
nsStyleCoord::nsStyleCoord(PRInt32 aValue, nsStyleUnit aUnit)
: mUnit(aUnit)
{
//if you want to pass in eStyleUnit_Coord, don't. instead, use the
//constructor just above this one... MMP
NS_ASSERTION((aUnit == eStyleUnit_Proportional) ||
(aUnit == eStyleUnit_Enumerated) ||
(aUnit == eStyleUnit_Integer), "not an int value");
if ((aUnit == eStyleUnit_Proportional) ||
(aUnit == eStyleUnit_Enumerated) ||
(aUnit == eStyleUnit_Integer)) {
mValue.mInt = aValue;
}
else {
mUnit = eStyleUnit_Null;
mValue.mInt = 0;
}
}
nsStyleCoord::nsStyleCoord(float aValue, nsStyleUnit aUnit)
: mUnit(aUnit)
{
NS_ASSERTION((aUnit == eStyleUnit_Percent) ||
(aUnit == eStyleUnit_Factor), "not a float value");
if ((aUnit == eStyleUnit_Percent) ||
(aUnit == eStyleUnit_Factor)) {
mValue.mFloat = aValue;
}
else {
mUnit = eStyleUnit_Null;
mValue.mInt = 0;
}
}
nsStyleCoord::nsStyleCoord(const nsStyleCoord& aCopy)
: mUnit(aCopy.mUnit)
{
if ((eStyleUnit_Percent <= mUnit) && (mUnit < eStyleUnit_Coord)) {
mValue.mFloat = aCopy.mValue.mFloat;
}
else {
mValue.mInt = aCopy.mValue.mInt;
}
}
nsStyleCoord& nsStyleCoord::operator=(const nsStyleCoord& aCopy)
{
mUnit = aCopy.mUnit;
if ((eStyleUnit_Percent <= mUnit) && (mUnit < eStyleUnit_Coord)) {
mValue.mFloat = aCopy.mValue.mFloat;
}
else {
mValue.mInt = aCopy.mValue.mInt;
}
return *this;
}
PRBool nsStyleCoord::operator==(const nsStyleCoord& aOther) const
{
if (mUnit == aOther.mUnit) {
if ((eStyleUnit_Percent <= mUnit) && (mUnit < eStyleUnit_Coord)) {
return PRBool(mValue.mFloat == aOther.mValue.mFloat);
}
else {
return PRBool(mValue.mInt == aOther.mValue.mInt);
}
}
return PR_FALSE;
}
void nsStyleCoord::Reset(void)
{
mUnit = eStyleUnit_Null;
mValue.mInt = 0;
}
void nsStyleCoord::SetCoordValue(nscoord aValue)
{
mUnit = eStyleUnit_Coord;
mValue.mInt = aValue;
}
void nsStyleCoord::SetIntValue(PRInt32 aValue, nsStyleUnit aUnit)
{
NS_ASSERTION((aUnit == eStyleUnit_Proportional) ||
(aUnit == eStyleUnit_Enumerated) ||
(aUnit == eStyleUnit_Chars) ||
(aUnit == eStyleUnit_Integer), "not an int value");
if ((aUnit == eStyleUnit_Proportional) ||
(aUnit == eStyleUnit_Enumerated) ||
(aUnit == eStyleUnit_Chars) ||
(aUnit == eStyleUnit_Integer)) {
mUnit = aUnit;
mValue.mInt = aValue;
}
else {
Reset();
}
}
void nsStyleCoord::SetPercentValue(float aValue)
{
mUnit = eStyleUnit_Percent;
mValue.mFloat = aValue;
}
void nsStyleCoord::SetFactorValue(float aValue)
{
mUnit = eStyleUnit_Factor;
mValue.mFloat = aValue;
}
void nsStyleCoord::SetNormalValue(void)
{
mUnit = eStyleUnit_Normal;
mValue.mInt = 0;
}
void nsStyleCoord::SetAutoValue(void)
{
mUnit = eStyleUnit_Auto;
mValue.mInt = 0;
}
void nsStyleCoord::SetInheritValue(void)
{
mUnit = eStyleUnit_Inherit;
mValue.mInt = 0;
}
void nsStyleCoord::SetUnionValue(const nsStyleUnion& aValue, nsStyleUnit aUnit)
{
mUnit = aUnit;
#if PR_BYTES_PER_INT == PR_BYTES_PER_FLOAT
mValue.mInt = aValue.mInt;
#else
nsCRT::memcpy(&mValue, &aValue, sizeof(nsStyleUnion));
#endif
}
void nsStyleCoord::AppendToString(nsString& aBuffer) const
{
if ((eStyleUnit_Percent <= mUnit) && (mUnit < eStyleUnit_Coord)) {
aBuffer.AppendFloat(mValue.mFloat);
}
else if ((eStyleUnit_Coord == mUnit) ||
(eStyleUnit_Proportional == mUnit) ||
(eStyleUnit_Enumerated == mUnit) ||
(eStyleUnit_Integer == mUnit)) {
aBuffer.AppendInt(mValue.mInt, 10);
aBuffer.AppendWithConversion("[0x");
aBuffer.AppendInt(mValue.mInt, 16);
aBuffer.AppendWithConversion(']');
}
switch (mUnit) {
case eStyleUnit_Null: aBuffer.AppendWithConversion("Null"); break;
case eStyleUnit_Coord: aBuffer.AppendWithConversion("tw"); break;
case eStyleUnit_Percent: aBuffer.AppendWithConversion("%"); break;
case eStyleUnit_Factor: aBuffer.AppendWithConversion("f"); break;
case eStyleUnit_Normal: aBuffer.AppendWithConversion("Normal"); break;
case eStyleUnit_Auto: aBuffer.AppendWithConversion("Auto"); break;
case eStyleUnit_Inherit: aBuffer.AppendWithConversion("Inherit"); break;
case eStyleUnit_Proportional: aBuffer.AppendWithConversion("*"); break;
case eStyleUnit_Enumerated: aBuffer.AppendWithConversion("enum"); break;
case eStyleUnit_Integer: aBuffer.AppendWithConversion("int"); break;
case eStyleUnit_Chars: aBuffer.AppendWithConversion("chars"); break;
}
aBuffer.AppendWithConversion(' ');
}
void nsStyleCoord::ToString(nsString& aBuffer) const
{
aBuffer.Truncate();
AppendToString(aBuffer);
}
nsStyleSides::nsStyleSides(void)
{
nsCRT::memset(this, 0x00, sizeof(nsStyleSides));
}
#define COMPARE_SIDE(side) \
if ((eStyleUnit_Percent <= m##side##Unit) && (m##side##Unit < eStyleUnit_Coord)) { \
if (m##side##Value.mFloat != aOther.m##side##Value.mFloat) \
return PR_FALSE; \
} \
else { \
if (m##side##Value.mInt != aOther.m##side##Value.mInt) \
return PR_FALSE; \
}
PRBool nsStyleSides::operator==(const nsStyleSides& aOther) const
{
if ((mLeftUnit == aOther.mLeftUnit) &&
(mTopUnit == aOther.mTopUnit) &&
(mRightUnit == aOther.mRightUnit) &&
(mBottomUnit == aOther.mBottomUnit)) {
COMPARE_SIDE(Left);
COMPARE_SIDE(Top);
COMPARE_SIDE(Right);
COMPARE_SIDE(Bottom);
return PR_TRUE;
}
return PR_FALSE;
}
void nsStyleSides::Reset(void)
{
nsCRT::memset(this, 0x00, sizeof(nsStyleSides));
}
void nsStyleSides::AppendToString(nsString& aBuffer) const
{
nsStyleCoord temp;
GetLeft(temp);
aBuffer.AppendWithConversion("left: ");
temp.AppendToString(aBuffer);
GetTop(temp);
aBuffer.AppendWithConversion("top: ");
temp.AppendToString(aBuffer);
GetRight(temp);
aBuffer.AppendWithConversion("right: ");
temp.AppendToString(aBuffer);
GetBottom(temp);
aBuffer.AppendWithConversion("bottom: ");
temp.AppendToString(aBuffer);
}
void nsStyleSides::ToString(nsString& aBuffer) const
{
aBuffer.Truncate();
AppendToString(aBuffer);
}

Some files were not shown because too many files have changed in this diff Show More