mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-27 15:55:16 +00:00
Fix for bug 251025 (document.importNode does not set the right owner document.). r=jst, sr=bz.
This commit is contained in:
parent
28e03d4aa6
commit
86ca4e41cc
@ -40,6 +40,7 @@
|
|||||||
#ifndef nsIAttribute_h___
|
#ifndef nsIAttribute_h___
|
||||||
#define nsIAttribute_h___
|
#define nsIAttribute_h___
|
||||||
|
|
||||||
|
#include "nsIContent.h"
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
#include "nsINodeInfo.h"
|
#include "nsINodeInfo.h"
|
||||||
#include "nsIContent.h"
|
#include "nsIContent.h"
|
||||||
@ -93,6 +94,13 @@ public:
|
|||||||
virtual void* UnsetProperty(nsIAtom *aPropertyName,
|
virtual void* UnsetProperty(nsIAtom *aPropertyName,
|
||||||
nsresult *aStatus = nsnull) = 0;
|
nsresult *aStatus = nsnull) = 0;
|
||||||
|
|
||||||
|
nsIDocument *GetOwnerDoc()
|
||||||
|
{
|
||||||
|
nsIContent *content = GetContent();
|
||||||
|
|
||||||
|
return content ? content->GetOwnerDoc() : mNodeInfo->GetDocument();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsIAttribute(nsDOMAttributeMap *aAttrMap, nsINodeInfo *aNodeInfo)
|
nsIAttribute(nsDOMAttributeMap *aAttrMap, nsINodeInfo *aNodeInfo)
|
||||||
: mAttrMap(aAttrMap), mNodeInfo(aNodeInfo)
|
: mAttrMap(aAttrMap), mNodeInfo(aNodeInfo)
|
||||||
|
@ -686,6 +686,23 @@ public:
|
|||||||
{ if (aStatus) *aStatus = NS_ERROR_NOT_IMPLEMENTED; return nsnull; }
|
{ if (aStatus) *aStatus = NS_ERROR_NOT_IMPLEMENTED; return nsnull; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clones this node, setting aOwnerDocument as the ownerDocument of the
|
||||||
|
* clone. When cloning an element, all attributes of the element will be
|
||||||
|
* cloned. If aDeep is set, all descendants will also be cloned (by calling
|
||||||
|
* the DOM method cloneNode on them if aOwnerDocument is the same as the
|
||||||
|
* ownerDocument of this content node or by calling the DOM method importNode
|
||||||
|
* if they differ).
|
||||||
|
*
|
||||||
|
* @param aOwnerDocument the document to use as the ownerDocument of the
|
||||||
|
* clone, it should not be null unless this element's
|
||||||
|
* ownerDocument is null and you don't want to set a
|
||||||
|
* different ownerDocument.
|
||||||
|
* @param aDeep whether to clone the descendants of this node
|
||||||
|
*/
|
||||||
|
virtual nsresult CloneContent(nsIDocument *aOwnerDocument,
|
||||||
|
PRBool aDeep, nsIContent **aResult) const = 0;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/**
|
/**
|
||||||
* List the content (and anything it contains) out to the given
|
* List the content (and anything it contains) out to the given
|
||||||
|
@ -74,9 +74,6 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual already_AddRefed<nsITextContent> CloneContent(PRBool aCloneText,
|
|
||||||
nsIDocument *aOwnerDocument);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
@ -161,28 +158,14 @@ nsCommentNode::GetNodeType(PRUint16* aNodeType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsGenericDOMDataNode*
|
||||||
nsCommentNode::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
nsCommentNode::Clone(nsIDocument *aOwnerDocument, PRBool aCloneText) const
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsITextContent> textContent = CloneContent(PR_TRUE, GetOwnerDoc());
|
nsCommentNode *it = new nsCommentNode(aOwnerDocument);
|
||||||
NS_ENSURE_TRUE(textContent, NS_ERROR_OUT_OF_MEMORY);
|
if (it && aCloneText) {
|
||||||
|
|
||||||
return CallQueryInterface(textContent, aReturn);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsITextContent>
|
|
||||||
nsCommentNode::CloneContent(PRBool aCloneText, nsIDocument *aOwnerDocument)
|
|
||||||
{
|
|
||||||
nsCommentNode* it = new nsCommentNode(nsnull);
|
|
||||||
if (!it)
|
|
||||||
return nsnull;
|
|
||||||
|
|
||||||
if (aCloneText) {
|
|
||||||
it->mText = mText;
|
it->mText = mText;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ADDREF(it);
|
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,22 +365,9 @@ nsDOMAttribute::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
|
|||||||
{
|
{
|
||||||
*aOwnerDocument = nsnull;
|
*aOwnerDocument = nsnull;
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsIDocument *document = GetOwnerDoc();
|
||||||
nsIContent* content = GetContentInternal();
|
|
||||||
if (content) {
|
|
||||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(content, &rv);
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
rv = node->GetOwnerDocument(aOwnerDocument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nsIDocument *document = mNodeInfo->GetDocument();
|
|
||||||
if (document) {
|
|
||||||
rv = CallQueryInterface(document, aOwnerDocument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return document ? CallQueryInterface(document, aOwnerDocument) : NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -192,18 +192,10 @@ nsDOMDocumentType::GetNodeType(PRUint16* aNodeType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsGenericDOMDataNode*
|
||||||
nsDOMDocumentType::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
nsDOMDocumentType::Clone(nsIDocument *aOwnerDocument, PRBool aCloneText) const
|
||||||
{
|
{
|
||||||
nsDOMDocumentType* it = new nsDOMDocumentType(mName,
|
// XXX ownerDocument
|
||||||
mEntities,
|
return new nsDOMDocumentType(mName, mEntities, mNotations, mPublicId,
|
||||||
mNotations,
|
mSystemId, mInternalSubset);
|
||||||
mPublicId,
|
|
||||||
mSystemId,
|
|
||||||
mInternalSubset);
|
|
||||||
if (!it) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CallQueryInterface(it, aReturn);
|
|
||||||
}
|
}
|
||||||
|
@ -2831,17 +2831,83 @@ nsDocument::GetCharacterSet(nsAString& aCharacterSet)
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocument::ImportNode(nsIDOMNode* aImportedNode,
|
nsDocument::ImportNode(nsIDOMNode* aImportedNode,
|
||||||
PRBool aDeep,
|
PRBool aDeep,
|
||||||
nsIDOMNode** aReturn)
|
nsIDOMNode** aResult)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(aImportedNode);
|
NS_ENSURE_ARG(aImportedNode);
|
||||||
NS_PRECONDITION(aReturn, "Null out param!");
|
|
||||||
|
*aResult = nsnull;
|
||||||
|
|
||||||
nsresult rv = nsContentUtils::CheckSameOrigin(this, aImportedNode);
|
nsresult rv = nsContentUtils::CheckSameOrigin(this, aImportedNode);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
return aImportedNode->CloneNode(aDeep, aReturn);
|
PRUint16 nodeType;
|
||||||
|
aImportedNode->GetNodeType(&nodeType);
|
||||||
|
switch (nodeType) {
|
||||||
|
case nsIDOMNode::ATTRIBUTE_NODE:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIAttribute> attr = do_QueryInterface(aImportedNode);
|
||||||
|
NS_ENSURE_TRUE(attr, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsIDocument *document = attr->GetOwnerDoc();
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMAttr> domAttr = do_QueryInterface(aImportedNode);
|
||||||
|
nsAutoString value;
|
||||||
|
rv = domAttr->GetValue(value);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsINodeInfo *nodeInfo = attr->NodeInfo();
|
||||||
|
nsCOMPtr<nsINodeInfo> newNodeInfo;
|
||||||
|
if (document != this) {
|
||||||
|
rv = mNodeInfoManager->GetNodeInfo(nodeInfo->NameAtom(),
|
||||||
|
nodeInfo->GetPrefixAtom(),
|
||||||
|
nodeInfo->NamespaceID(),
|
||||||
|
getter_AddRefs(newNodeInfo));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nodeInfo = newNodeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNode> clone = new nsDOMAttribute(nsnull, nodeInfo,
|
||||||
|
value);
|
||||||
|
if (!clone) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
clone.swap(*aResult);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
|
||||||
|
case nsIDOMNode::ELEMENT_NODE:
|
||||||
|
case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
|
||||||
|
case nsIDOMNode::TEXT_NODE:
|
||||||
|
case nsIDOMNode::CDATA_SECTION_NODE:
|
||||||
|
case nsIDOMNode::COMMENT_NODE:
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIContent> imported = do_QueryInterface(aImportedNode);
|
||||||
|
NS_ENSURE_TRUE(imported, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> clone;
|
||||||
|
rv = imported->CloneContent(this, aDeep, getter_AddRefs(clone));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return CallQueryInterface(clone, aResult);
|
||||||
|
}
|
||||||
|
case nsIDOMNode::ENTITY_NODE:
|
||||||
|
case nsIDOMNode::ENTITY_REFERENCE_NODE:
|
||||||
|
case nsIDOMNode::NOTATION_NODE:
|
||||||
|
{
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
NS_WARNING("Don't know how to clone this nodetype for importNode.");
|
||||||
|
|
||||||
|
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -55,7 +55,7 @@ class nsDocumentFragment : public nsGenericElement,
|
|||||||
public nsIDOM3Node
|
public nsIDOM3Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsDocumentFragment(nsINodeInfo *aNodeInfo, nsIDocument* aOwnerDocument);
|
nsDocumentFragment(nsINodeInfo *aNodeInfo);
|
||||||
virtual ~nsDocumentFragment();
|
virtual ~nsDocumentFragment();
|
||||||
|
|
||||||
// nsISupports
|
// nsISupports
|
||||||
@ -91,7 +91,8 @@ public:
|
|||||||
*aAttributes = nsnull;
|
*aAttributes = nsnull;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument);
|
NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
|
||||||
|
{ return nsGenericElement::GetOwnerDocument(aOwnerDocument); }
|
||||||
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
|
NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
|
||||||
nsIDOMNode** aReturn)
|
nsIDOMNode** aReturn)
|
||||||
{ return nsGenericElement::InsertBefore(aNewChild, aRefChild, aReturn); }
|
{ return nsGenericElement::InsertBefore(aNewChild, aRefChild, aReturn); }
|
||||||
@ -165,7 +166,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsIDocument> mOwnerDocument;
|
nsresult Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
@ -182,23 +184,19 @@ NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
|
|||||||
getter_AddRefs(nodeInfo));
|
getter_AddRefs(nodeInfo));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsDocumentFragment* it = new nsDocumentFragment(nodeInfo, aOwnerDocument);
|
nsDocumentFragment* it = new nsDocumentFragment(nodeInfo);
|
||||||
if (!it) {
|
if (!it) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
*aInstancePtrResult = NS_STATIC_CAST(nsIDOMDocumentFragment *, it);
|
NS_ADDREF(*aInstancePtrResult = it);
|
||||||
|
|
||||||
NS_ADDREF(*aInstancePtrResult);
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDocumentFragment::nsDocumentFragment(nsINodeInfo *aNodeInfo,
|
nsDocumentFragment::nsDocumentFragment(nsINodeInfo *aNodeInfo)
|
||||||
nsIDocument* aOwnerDocument)
|
|
||||||
: nsGenericElement(aNodeInfo)
|
: nsGenericElement(aNodeInfo)
|
||||||
{
|
{
|
||||||
mOwnerDocument = aOwnerDocument;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDocumentFragment::~nsDocumentFragment()
|
nsDocumentFragment::~nsDocumentFragment()
|
||||||
@ -293,64 +291,13 @@ nsDocumentFragment::GetNodeType(PRUint16* aNodeType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsDocumentFragment::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(aOwnerDocument);
|
|
||||||
|
|
||||||
if (!mOwnerDocument) {
|
|
||||||
*aOwnerDocument = nsnull;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CallQueryInterface(mOwnerDocument, aOwnerDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocumentFragment::SetPrefix(const nsAString& aPrefix)
|
nsDocumentFragment::SetPrefix(const nsAString& aPrefix)
|
||||||
{
|
{
|
||||||
return NS_ERROR_DOM_NAMESPACE_ERR;
|
return NS_ERROR_DOM_NAMESPACE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMPL_DOM_CLONENODE(nsDocumentFragment)
|
||||||
nsDocumentFragment::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(aReturn);
|
|
||||||
*aReturn = nsnull;
|
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
nsCOMPtr<nsIDOMDocumentFragment> newFragment;
|
|
||||||
|
|
||||||
rv = NS_NewDocumentFragment(getter_AddRefs(newFragment), mOwnerDocument);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (aDeep) {
|
|
||||||
nsCOMPtr<nsIDOMNodeList> childNodes;
|
|
||||||
|
|
||||||
GetChildNodes(getter_AddRefs(childNodes));
|
|
||||||
if (childNodes) {
|
|
||||||
PRUint32 index, count;
|
|
||||||
childNodes->GetLength(&count);
|
|
||||||
|
|
||||||
for (index = 0; index < count; ++index) {
|
|
||||||
nsCOMPtr<nsIDOMNode> child;
|
|
||||||
childNodes->Item(index, getter_AddRefs(child));
|
|
||||||
if (child) {
|
|
||||||
nsCOMPtr<nsIDOMNode> newChild;
|
|
||||||
rv = child->CloneNode(PR_TRUE, getter_AddRefs(newChild));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> dummyNode;
|
|
||||||
rv = newFragment->AppendChild(newChild,
|
|
||||||
getter_AddRefs(dummyNode));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
|
||||||
} // End of for loop
|
|
||||||
} // if (childNodes)
|
|
||||||
} // if (aDeep)
|
|
||||||
|
|
||||||
return CallQueryInterface(newFragment, aReturn);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocumentFragment::GetBaseURI(nsAString& aURI)
|
nsDocumentFragment::GetBaseURI(nsAString& aURI)
|
||||||
|
@ -275,6 +275,20 @@ nsGenericDOMDataNode::GetBaseURI(nsAString& aURI)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericDOMDataNode::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
||||||
|
{
|
||||||
|
*aResult = nsnull;
|
||||||
|
|
||||||
|
nsIDocument *document = GetOwnerDoc();
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> newContent;
|
||||||
|
nsresult rv = CloneContent(document, aDeep, getter_AddRefs(newContent));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return CallQueryInterface(newContent, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsGenericDOMDataNode::LookupPrefix(const nsAString& aNamespaceURI,
|
nsGenericDOMDataNode::LookupPrefix(const nsAString& aNamespaceURI,
|
||||||
nsAString& aPrefix)
|
nsAString& aPrefix)
|
||||||
@ -1039,11 +1053,11 @@ nsGenericDOMDataNode::SplitText(PRUint32 aOffset, nsIDOMText** aReturn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use CloneContent() for creating the new node so that the new node is of
|
* Use Clone for creating the new node so that the new node is of same class
|
||||||
* same class as this node!
|
* as this node!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nsCOMPtr<nsITextContent> newContent = CloneContent(PR_FALSE, nsnull);
|
nsCOMPtr<nsITextContent> newContent = Clone(nsnull, PR_FALSE);
|
||||||
if (!newContent) {
|
if (!newContent) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
@ -1314,11 +1328,18 @@ nsGenericDOMDataNode::GetCurrentValueAtom()
|
|||||||
return NS_NewAtom(val);
|
return NS_NewAtom(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsITextContent>
|
nsresult
|
||||||
nsGenericDOMDataNode::CloneContent(PRBool aCloneText,
|
nsGenericDOMDataNode::CloneContent(nsIDocument *aOwnerDocument, PRBool aDeep,
|
||||||
nsIDocument *aOwnerDocument)
|
nsIContent **aResult) const
|
||||||
{
|
{
|
||||||
NS_ERROR("Huh, this shouldn't be called!");
|
// XXX We really want to pass the document to the constructor, but can't
|
||||||
|
// yet. See https://bugzilla.mozilla.org/show_bug.cgi?id=27382
|
||||||
|
*aResult = Clone(nsnull, PR_TRUE);
|
||||||
|
if (!*aResult) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
return nsnull;
|
NS_ADDREF(*aResult);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -147,6 +147,16 @@ public:
|
|||||||
const nsAString& aVersion,
|
const nsAString& aVersion,
|
||||||
PRBool* aReturn);
|
PRBool* aReturn);
|
||||||
nsresult GetBaseURI(nsAString& aURI);
|
nsresult GetBaseURI(nsAString& aURI);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A basic implementation of the DOM cloneNode method. Calls CloneContent to
|
||||||
|
* do the actual cloning of the node.
|
||||||
|
*
|
||||||
|
* @param aDeep if true all descendants will be cloned too
|
||||||
|
* @param aResult the clone
|
||||||
|
*/
|
||||||
|
nsresult CloneNode(PRBool aDeep, nsIDOMNode **aResult);
|
||||||
|
|
||||||
nsresult LookupPrefix(const nsAString& aNamespaceURI,
|
nsresult LookupPrefix(const nsAString& aNamespaceURI,
|
||||||
nsAString& aPrefix);
|
nsAString& aPrefix);
|
||||||
nsresult LookupNamespaceURI(const nsAString& aNamespacePrefix,
|
nsresult LookupNamespaceURI(const nsAString& aNamespacePrefix,
|
||||||
@ -243,6 +253,13 @@ public:
|
|||||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||||
virtual PRBool MayHaveFrame() const;
|
virtual PRBool MayHaveFrame() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This calls Clone to do the actual cloning so that we end up with the
|
||||||
|
* right class for the clone.
|
||||||
|
*/
|
||||||
|
nsresult CloneContent(nsIDocument *aOwnerDocument, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const;
|
||||||
|
|
||||||
// nsITextContent
|
// nsITextContent
|
||||||
virtual const nsTextFragment *Text();
|
virtual const nsTextFragment *Text();
|
||||||
virtual PRUint32 TextLength();
|
virtual PRUint32 TextLength();
|
||||||
@ -256,9 +273,6 @@ public:
|
|||||||
|
|
||||||
//----------------------------------------
|
//----------------------------------------
|
||||||
|
|
||||||
virtual already_AddRefed<nsITextContent> CloneContent(PRBool aCloneText,
|
|
||||||
nsIDocument *aOwnerDocument);
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void ToCString(nsAString& aBuf, PRInt32 aOffset, PRInt32 aLen) const;
|
void ToCString(nsAString& aBuf, PRInt32 aOffset, PRInt32 aLen) const;
|
||||||
#endif
|
#endif
|
||||||
@ -266,6 +280,22 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
nsresult SplitText(PRUint32 aOffset, nsIDOMText** aReturn);
|
nsresult SplitText(PRUint32 aOffset, nsIDOMText** aReturn);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to clone this node. This needs to be overriden by all derived
|
||||||
|
* classes. If aCloneText is true the text content will be cloned too.
|
||||||
|
*
|
||||||
|
* @param aOwnerDocument the ownerDocument of the clone
|
||||||
|
* @param aCloneText if true the text content will be cloned too
|
||||||
|
* @return the clone
|
||||||
|
*/
|
||||||
|
virtual nsGenericDOMDataNode *Clone(nsIDocument *aOwnerDocument,
|
||||||
|
PRBool aCloneText) const
|
||||||
|
{
|
||||||
|
NS_ERROR("This shouldn't be called!");
|
||||||
|
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
nsTextFragment mText;
|
nsTextFragment mText;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -316,7 +346,8 @@ private:
|
|||||||
*
|
*
|
||||||
* Note that classes using this macro will need to implement:
|
* Note that classes using this macro will need to implement:
|
||||||
* NS_IMETHOD GetNodeType(PRUint16* aNodeType);
|
* NS_IMETHOD GetNodeType(PRUint16* aNodeType);
|
||||||
* NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
|
* nsGenericDOMDataNode *Clone(nsIDocument *aOwnerDocument,
|
||||||
|
* PRBool aCloneText) const;
|
||||||
*/
|
*/
|
||||||
#define NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA \
|
#define NS_IMPL_NSIDOMNODE_USING_GENERIC_DOM_DATA \
|
||||||
NS_IMETHOD GetNodeName(nsAString& aNodeName); \
|
NS_IMETHOD GetNodeName(nsAString& aNodeName); \
|
||||||
@ -389,6 +420,10 @@ private:
|
|||||||
PRBool* aReturn) { \
|
PRBool* aReturn) { \
|
||||||
return nsGenericDOMDataNode::IsSupported(aFeature, aVersion, aReturn); \
|
return nsGenericDOMDataNode::IsSupported(aFeature, aVersion, aReturn); \
|
||||||
} \
|
} \
|
||||||
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
|
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn) { \
|
||||||
|
return nsGenericDOMDataNode::CloneNode(aDeep, aReturn); \
|
||||||
|
} \
|
||||||
|
virtual nsGenericDOMDataNode *Clone(nsIDocument *aOwnerDocument, \
|
||||||
|
PRBool aCloneText) const;
|
||||||
|
|
||||||
#endif /* nsGenericDOMDataNode_h___ */
|
#endif /* nsGenericDOMDataNode_h___ */
|
||||||
|
@ -3401,11 +3401,13 @@ nsGenericElement::InternalGetExistingAttrNameFromQName(const nsAString& aStr) co
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsGenericElement::CopyInnerTo(nsGenericElement* aDst, PRBool aDeep)
|
nsGenericElement::CopyInnerTo(nsGenericElement* aDst, PRBool aDeep) const
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv = NS_OK;
|
||||||
PRUint32 i, count = mAttrsAndChildren.AttrCount();
|
PRUint32 i, count = mAttrsAndChildren.AttrCount();
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
|
// XXX Once we have access to existing nsDOMAttributes for this element, we
|
||||||
|
// should call CloneNode or ImportNode on them.
|
||||||
const nsAttrName* name = mAttrsAndChildren.GetSafeAttrNameAt(i);
|
const nsAttrName* name = mAttrsAndChildren.GetSafeAttrNameAt(i);
|
||||||
const nsAttrValue* value = mAttrsAndChildren.AttrAt(i);
|
const nsAttrValue* value = mAttrsAndChildren.AttrAt(i);
|
||||||
nsAutoString valStr;
|
nsAutoString valStr;
|
||||||
@ -3415,21 +3417,63 @@ nsGenericElement::CopyInnerTo(nsGenericElement* aDst, PRBool aDeep)
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aDeep) {
|
if (aDeep) {
|
||||||
return NS_OK;
|
nsIDocument *doc = GetOwnerDoc();
|
||||||
|
nsIDocument *newDoc = aDst->GetOwnerDoc();
|
||||||
|
if (doc == newDoc) {
|
||||||
|
rv = CloneChildrenTo(aDst);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(newDoc);
|
||||||
|
rv = ImportChildrenTo(aDst, domDoc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
count = mAttrsAndChildren.ChildCount();
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericElement::ImportChildrenTo(nsGenericElement *aDst,
|
||||||
|
nsIDOMDocument *aImportDocument) const
|
||||||
|
{
|
||||||
|
PRUint32 i, count = mAttrsAndChildren.ChildCount();
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
|
nsresult rv;
|
||||||
nsCOMPtr<nsIDOMNode> node =
|
nsCOMPtr<nsIDOMNode> node =
|
||||||
do_QueryInterface(mAttrsAndChildren.ChildAt(i));
|
do_QueryInterface(mAttrsAndChildren.ChildAt(i), &rv);
|
||||||
NS_ASSERTION(node, "child doesn't implement nsIDOMNode");
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMNode> newNode;
|
||||||
|
rv = aImportDocument->ImportNode(node, PR_TRUE, getter_AddRefs(newNode));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> newContent = do_QueryInterface(newNode, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = aDst->AppendChildTo(newContent, PR_FALSE);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericElement::CloneChildrenTo(nsGenericElement *aDst) const
|
||||||
|
{
|
||||||
|
PRUint32 i, count = mAttrsAndChildren.ChildCount();
|
||||||
|
for (i = 0; i < count; ++i) {
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIDOMNode> node =
|
||||||
|
do_QueryInterface(mAttrsAndChildren.ChildAt(i), &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> newNode;
|
nsCOMPtr<nsIDOMNode> newNode;
|
||||||
rv = node->CloneNode(PR_TRUE, getter_AddRefs(newNode));
|
rv = node->CloneNode(PR_TRUE, getter_AddRefs(newNode));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> newContent = do_QueryInterface(newNode);
|
nsCOMPtr<nsIContent> newContent = do_QueryInterface(newNode, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = aDst->AppendChildTo(newContent, PR_FALSE);
|
rv = aDst->AppendChildTo(newContent, PR_FALSE);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
@ -3941,3 +3985,37 @@ nsGenericElement::UnsetProperty(nsIAtom *aPropertyName, nsresult *aStatus)
|
|||||||
|
|
||||||
return doc->PropertyTable()->UnsetProperty(this, aPropertyName, aStatus);
|
return doc->PropertyTable()->UnsetProperty(this, aPropertyName, aStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
||||||
|
{
|
||||||
|
*aResult = nsnull;
|
||||||
|
|
||||||
|
nsIDocument *document = GetOwnerDoc();
|
||||||
|
|
||||||
|
nsCOMPtr<nsIContent> newContent;
|
||||||
|
nsresult rv = CloneContent(document, aDeep, getter_AddRefs(newContent));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return CallQueryInterface(newContent, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericElement::CloneContent(nsIDocument *aOwnerDocument, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const
|
||||||
|
{
|
||||||
|
if (GetOwnerDoc() == aOwnerDocument) {
|
||||||
|
return Clone(mNodeInfo, aDeep, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsNodeInfoManager* nodeInfoManager = aOwnerDocument->NodeInfoManager();
|
||||||
|
|
||||||
|
nsCOMPtr<nsINodeInfo> newNodeInfo;
|
||||||
|
nsresult rv = nodeInfoManager->GetNodeInfo(mNodeInfo->NameAtom(),
|
||||||
|
mNodeInfo->GetPrefixAtom(),
|
||||||
|
mNodeInfo->NamespaceID(),
|
||||||
|
getter_AddRefs(newNodeInfo));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return Clone(newNodeInfo, aDeep, aResult);
|
||||||
|
}
|
||||||
|
@ -445,6 +445,13 @@ public:
|
|||||||
virtual void SetMayHaveFrame(PRBool aMayHaveFrame);
|
virtual void SetMayHaveFrame(PRBool aMayHaveFrame);
|
||||||
virtual PRBool MayHaveFrame() const;
|
virtual PRBool MayHaveFrame() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This calls Clone to do the actual cloning so that we end up with the
|
||||||
|
* right class for the clone.
|
||||||
|
*/
|
||||||
|
nsresult CloneContent(nsIDocument *aOwnerDocument, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
virtual void List(FILE* out, PRInt32 aIndent) const;
|
virtual void List(FILE* out, PRInt32 aIndent) const;
|
||||||
virtual void DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const;
|
virtual void DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const;
|
||||||
@ -655,11 +662,28 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Copy attributes and children from another content object
|
* Duplicate children by calling importNode and append them to another
|
||||||
* @param aSrcContent the object to copy from
|
* element.
|
||||||
|
*
|
||||||
|
* @param aDst the element to append the imported children to
|
||||||
|
* @param aImportDocument the document to use to call importNode
|
||||||
|
*/
|
||||||
|
nsresult ImportChildrenTo(nsGenericElement *aDst,
|
||||||
|
nsIDOMDocument *aImportDocument) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone children and append them to another element.
|
||||||
|
*
|
||||||
|
* @param aDst the element to append the imported children to
|
||||||
|
*/
|
||||||
|
nsresult CloneChildrenTo(nsGenericElement *aDst) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy attributes and children to another content object
|
||||||
|
* @param aDest the object to copy to
|
||||||
* @param aDeep whether to copy children
|
* @param aDeep whether to copy children
|
||||||
*/
|
*/
|
||||||
nsresult CopyInnerTo(nsGenericElement* aDest, PRBool aDeep);
|
nsresult CopyInnerTo(nsGenericElement* aDest, PRBool aDeep) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal hook for converting an attribute name-string to an atomized name
|
* Internal hook for converting an attribute name-string to an atomized name
|
||||||
@ -771,6 +795,37 @@ protected:
|
|||||||
*/
|
*/
|
||||||
void GetContentsAsText(nsAString& aText);
|
void GetContentsAsText(nsAString& aText);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to clone this element. This needs to be overriden by all element
|
||||||
|
* classes. aNodeInfo should be identical to this element's nodeInfo, except
|
||||||
|
* for the document which may be different. If aDeep is true all descendants
|
||||||
|
* will be cloned too (by calling the DOM method cloneNode on them if the
|
||||||
|
* ownerDocument of aNodeInfo is the same as the ownerDocument of this
|
||||||
|
* element or by calling the DOM method importNode if they differ).
|
||||||
|
*
|
||||||
|
* @param aNodeInfo the nodeinfo to use for the clone
|
||||||
|
* @param aDeep if true all descendants will be cloned too (attributes are
|
||||||
|
* always cloned)
|
||||||
|
* @param aResult the clone
|
||||||
|
*/
|
||||||
|
virtual nsresult Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const
|
||||||
|
{
|
||||||
|
NS_ERROR("This shouldn't be called!");
|
||||||
|
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A basic implementation of the DOM cloneNode method. Calls CloneContent to
|
||||||
|
* do the actual cloning of the element.
|
||||||
|
*
|
||||||
|
* @param aDeep if true all descendants will be cloned too (attributes on the
|
||||||
|
* element are always cloned)
|
||||||
|
* @param aResult the clone
|
||||||
|
*/
|
||||||
|
nsresult CloneNode(PRBool aDeep, nsIDOMNode **aResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about this type of node
|
* Information about this type of node
|
||||||
*/
|
*/
|
||||||
@ -900,56 +955,65 @@ public:
|
|||||||
NS_IMETHOD HasAttributes(PRBool* aReturn) { \
|
NS_IMETHOD HasAttributes(PRBool* aReturn) { \
|
||||||
return _to HasAttributes(aReturn); \
|
return _to HasAttributes(aReturn); \
|
||||||
} \
|
} \
|
||||||
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
|
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn); \
|
||||||
|
virtual nsresult Clone(nsINodeInfo *aNodeInfo, PRBool aDeep, \
|
||||||
|
nsIContent **aResult) const;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Macros to implement CloneNode().
|
* Macros to implement CloneNode().
|
||||||
*/
|
*/
|
||||||
#define NS_IMPL_DOM_CLONENODE(_elementName) \
|
#define NS_IMPL_DOM_CLONENODE(_elementName) \
|
||||||
NS_IMPL_DOM_CLONENODE_AMBIGUOUS(_elementName, nsIDOMNode)
|
nsresult \
|
||||||
|
_elementName::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep, \
|
||||||
#define NS_IMPL_DOM_CLONENODE_AMBIGUOUS(_elementName, _implClass) \
|
nsIContent **aResult) const \
|
||||||
NS_IMETHODIMP \
|
|
||||||
_elementName::CloneNode(PRBool aDeep, nsIDOMNode **aResult) \
|
|
||||||
{ \
|
{ \
|
||||||
*aResult = nsnull; \
|
*aResult = nsnull; \
|
||||||
\
|
\
|
||||||
_elementName *it = new _elementName(mNodeInfo); \
|
_elementName *it = new _elementName(aNodeInfo); \
|
||||||
if (!it) { \
|
if (!it) { \
|
||||||
return NS_ERROR_OUT_OF_MEMORY; \
|
return NS_ERROR_OUT_OF_MEMORY; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
nsCOMPtr<nsIDOMNode> kungFuDeathGrip = NS_STATIC_CAST(_implClass*, it); \
|
nsCOMPtr<nsIContent> kungFuDeathGrip = it; \
|
||||||
\
|
|
||||||
nsresult rv = CopyInnerTo(it, aDeep); \
|
nsresult rv = CopyInnerTo(it, aDeep); \
|
||||||
if (NS_SUCCEEDED(rv)) { \
|
if (NS_SUCCEEDED(rv)) { \
|
||||||
kungFuDeathGrip.swap(*aResult); \
|
kungFuDeathGrip.swap(*aResult); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
return rv; \
|
return rv; \
|
||||||
}
|
} \
|
||||||
|
|
||||||
#define NS_IMPL_DOM_CLONENODE_WITH_INIT(_elementName) \
|
|
||||||
NS_IMETHODIMP \
|
NS_IMETHODIMP \
|
||||||
_elementName::CloneNode(PRBool aDeep, nsIDOMNode **aResult) \
|
_elementName::CloneNode(PRBool aDeep, nsIDOMNode **aResult) \
|
||||||
|
{ \
|
||||||
|
return nsGenericElement::CloneNode(aDeep, aResult); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NS_IMPL_DOM_CLONENODE_WITH_INIT(_elementName) \
|
||||||
|
nsresult \
|
||||||
|
_elementName::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep, \
|
||||||
|
nsIContent **aResult) const \
|
||||||
{ \
|
{ \
|
||||||
*aResult = nsnull; \
|
*aResult = nsnull; \
|
||||||
\
|
\
|
||||||
_elementName *it = new _elementName(mNodeInfo); \
|
_elementName *it = new _elementName(aNodeInfo); \
|
||||||
if (!it) { \
|
if (!it) { \
|
||||||
return NS_ERROR_OUT_OF_MEMORY; \
|
return NS_ERROR_OUT_OF_MEMORY; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
nsCOMPtr<nsIDOMNode> kungFuDeathGrip(it); \
|
nsCOMPtr<nsIContent> kungFuDeathGrip = it; \
|
||||||
\
|
|
||||||
nsresult rv = it->Init(); \
|
nsresult rv = it->Init(); \
|
||||||
\
|
|
||||||
rv |= CopyInnerTo(it, aDeep); \
|
rv |= CopyInnerTo(it, aDeep); \
|
||||||
if (NS_SUCCEEDED(rv)) { \
|
if (NS_SUCCEEDED(rv)) { \
|
||||||
kungFuDeathGrip.swap(*aResult); \
|
kungFuDeathGrip.swap(*aResult); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
return rv; \
|
return rv; \
|
||||||
|
} \
|
||||||
|
NS_IMETHODIMP \
|
||||||
|
_elementName::CloneNode(PRBool aDeep, nsIDOMNode **aResult) \
|
||||||
|
{ \
|
||||||
|
return nsGenericElement::CloneNode(aDeep, aResult); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* nsGenericElement_h___ */
|
#endif /* nsGenericElement_h___ */
|
||||||
|
@ -74,9 +74,6 @@ public:
|
|||||||
virtual void List(FILE* out, PRInt32 aIndent) const;
|
virtual void List(FILE* out, PRInt32 aIndent) const;
|
||||||
virtual void DumpContent(FILE* out, PRInt32 aIndent, PRBool aDumpAll) const;
|
virtual void DumpContent(FILE* out, PRInt32 aIndent, PRBool aDumpAll) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual already_AddRefed<nsITextContent> CloneContent(PRBool aCloneText,
|
|
||||||
nsIDocument *aOwnerDocument);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,7 +109,7 @@ public:
|
|||||||
nsITextContent* mContent; // Weak ref; it owns us
|
nsITextContent* mContent; // Weak ref; it owns us
|
||||||
};
|
};
|
||||||
|
|
||||||
nsAttributeTextNode() : nsTextNode(nsnull) {
|
nsAttributeTextNode(nsIDocument *aDocument) : nsTextNode(aDocument) {
|
||||||
}
|
}
|
||||||
virtual ~nsAttributeTextNode() {
|
virtual ~nsAttributeTextNode() {
|
||||||
DetachListener();
|
DetachListener();
|
||||||
@ -124,6 +121,17 @@ public:
|
|||||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||||
PRBool aNullParent = PR_TRUE);
|
PRBool aNullParent = PR_TRUE);
|
||||||
|
|
||||||
|
virtual nsGenericDOMDataNode *Clone(nsIDocument *aOwnerDocument,
|
||||||
|
PRBool aCloneText) const
|
||||||
|
{
|
||||||
|
nsAttributeTextNode *it = new nsAttributeTextNode(aOwnerDocument);
|
||||||
|
if (it && aCloneText) {
|
||||||
|
it->mText = mText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
nsRefPtr<nsAttrChangeListener> mListener; // our listener
|
nsRefPtr<nsAttrChangeListener> mListener; // our listener
|
||||||
private:
|
private:
|
||||||
void DetachListener();
|
void DetachListener();
|
||||||
@ -197,37 +205,23 @@ nsTextNode::GetNodeType(PRUint16* aNodeType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsTextNode::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsITextContent> textContent = CloneContent(PR_TRUE, GetOwnerDoc());
|
|
||||||
NS_ENSURE_TRUE(textContent, NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
|
|
||||||
return CallQueryInterface(textContent, aReturn);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsITextContent>
|
|
||||||
nsTextNode::CloneContent(PRBool aCloneText, nsIDocument *aOwnerDocument)
|
|
||||||
{
|
|
||||||
nsTextNode* it = new nsTextNode(nsnull);
|
|
||||||
if (!it)
|
|
||||||
return nsnull;
|
|
||||||
|
|
||||||
if (aCloneText) {
|
|
||||||
it->mText = mText;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(it);
|
|
||||||
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
nsTextNode::IsContentOfType(PRUint32 aFlags) const
|
nsTextNode::IsContentOfType(PRUint32 aFlags) const
|
||||||
{
|
{
|
||||||
return !(aFlags & ~eTEXT);
|
return !(aFlags & ~eTEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsGenericDOMDataNode*
|
||||||
|
nsTextNode::Clone(nsIDocument *aOwnerDocument, PRBool aCloneText) const
|
||||||
|
{
|
||||||
|
nsTextNode *it = new nsTextNode(aOwnerDocument);
|
||||||
|
if (it && aCloneText) {
|
||||||
|
it->mText = mText;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
nsTextNode::List(FILE* out, PRInt32 aIndent) const
|
nsTextNode::List(FILE* out, PRInt32 aIndent) const
|
||||||
@ -304,15 +298,15 @@ nsAttributeTextNode::nsAttrChangeListener::HandleEvent(nsIDOMEvent* aEvent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewAttributeContent(PRInt32 aNameSpaceID, nsIAtom* aAttrName,
|
NS_NewAttributeContent(nsIDocument *aOwnerDoc, PRInt32 aNameSpaceID,
|
||||||
nsIContent** aResult)
|
nsIAtom* aAttrName, nsIContent** aResult)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aAttrName, "Must have an attr name");
|
NS_PRECONDITION(aAttrName, "Must have an attr name");
|
||||||
NS_PRECONDITION(aNameSpaceID != kNameSpaceID_Unknown, "Must know namespace");
|
NS_PRECONDITION(aNameSpaceID != kNameSpaceID_Unknown, "Must know namespace");
|
||||||
|
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
|
|
||||||
nsRefPtr<nsAttributeTextNode> textNode = new nsAttributeTextNode();
|
nsRefPtr<nsAttributeTextNode> textNode = new nsAttributeTextNode(aOwnerDoc);
|
||||||
NS_ENSURE_TRUE(textNode, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(textNode, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
textNode->mListener =
|
textNode->mListener =
|
||||||
|
@ -271,53 +271,47 @@ nsGenericHTMLElement::Shutdown()
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsGenericHTMLElement::CopyInnerTo(nsGenericElement* aDst, PRBool aDeep)
|
nsGenericHTMLElement::CopyInnerTo(nsGenericElement* aDst, PRBool aDeep) const
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
PRInt32 i, count = GetAttrCount();
|
PRInt32 i, count = GetAttrCount();
|
||||||
nsCOMPtr<nsIAtom> name, prefix;
|
|
||||||
PRInt32 namespace_id;
|
|
||||||
nsAutoString value;
|
nsAutoString value;
|
||||||
|
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
rv = GetAttrNameAt(i, &namespace_id, getter_AddRefs(name),
|
// XXX Once we have access to existing nsDOMAttributes for this element, we
|
||||||
getter_AddRefs(prefix));
|
// should call CloneNode or ImportNode on them.
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
const nsAttrName *name = mAttrsAndChildren.GetSafeAttrNameAt(i);
|
||||||
|
const nsAttrValue *value = mAttrsAndChildren.AttrAt(i);
|
||||||
if (name == nsHTMLAtoms::style && namespace_id == kNameSpaceID_None) {
|
if (name->Equals(nsHTMLAtoms::style, kNameSpaceID_None) &&
|
||||||
|
value->Type() == nsAttrValue::eCSSStyleRule) {
|
||||||
// We can't just set this as a string, because that will fail
|
// We can't just set this as a string, because that will fail
|
||||||
// to reparse the string into style data until the node is
|
// to reparse the string into style data until the node is
|
||||||
// inserted into the document. Clone the HTMLValue instead.
|
// inserted into the document. Clone the HTMLValue instead.
|
||||||
const nsAttrValue* styleVal =
|
nsCOMPtr<nsICSSRule> ruleClone;
|
||||||
mAttrsAndChildren.GetAttr(nsHTMLAtoms::style);
|
rv = value->GetCSSStyleRuleValue()->Clone(*getter_AddRefs(ruleClone));
|
||||||
if (styleVal && styleVal->Type() == nsAttrValue::eCSSStyleRule) {
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
nsCOMPtr<nsICSSRule> ruleClone;
|
|
||||||
rv = styleVal->GetCSSStyleRuleValue()->
|
|
||||||
Clone(*getter_AddRefs(ruleClone));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsICSSStyleRule> styleRule = do_QueryInterface(ruleClone);
|
nsCOMPtr<nsICSSStyleRule> styleRule = do_QueryInterface(ruleClone);
|
||||||
NS_ENSURE_TRUE(styleRule, NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(styleRule, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
rv = aDst->SetInlineStyleRule(styleRule, PR_FALSE);
|
rv = aDst->SetInlineStyleRule(styleRule, PR_FALSE);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = GetAttr(namespace_id, name, value);
|
nsAutoString valStr;
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
value->ToString(valStr);
|
||||||
|
rv = aDst->SetAttr(name->NamespaceID(), name->LocalName(),
|
||||||
rv = aDst->SetAttr(namespace_id, name, prefix, value, PR_FALSE);
|
name->GetPrefix(), valStr, PR_FALSE);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIDocument *doc = nsContentUtils::GetDocument(mNodeInfo);
|
nsIDocument *newDoc = aDst->GetOwnerDoc();
|
||||||
|
|
||||||
PRInt32 id;
|
PRInt32 id;
|
||||||
if (doc) {
|
if (newDoc) {
|
||||||
id = doc->GetAndIncrementContentID();
|
id = newDoc->GetAndIncrementContentID();
|
||||||
} else {
|
} else {
|
||||||
id = PR_INT32_MAX;
|
id = PR_INT32_MAX;
|
||||||
}
|
}
|
||||||
@ -325,25 +319,17 @@ nsGenericHTMLElement::CopyInnerTo(nsGenericElement* aDst, PRBool aDeep)
|
|||||||
aDst->SetContentID(id);
|
aDst->SetContentID(id);
|
||||||
|
|
||||||
if (aDeep) {
|
if (aDeep) {
|
||||||
PRInt32 i;
|
nsIDocument *doc = GetOwnerDoc();
|
||||||
PRInt32 count = mAttrsAndChildren.ChildCount();
|
if (doc == newDoc) {
|
||||||
for (i = 0; i < count; ++i) {
|
rv = CloneChildrenTo(aDst);
|
||||||
nsCOMPtr<nsIDOMNode> node =
|
}
|
||||||
do_QueryInterface(mAttrsAndChildren.ChildAt(i));
|
else {
|
||||||
NS_ASSERTION(node, "child doesn't implement nsIDOMNode");
|
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(newDoc);
|
||||||
|
rv = ImportChildrenTo(aDst, domDoc);
|
||||||
nsCOMPtr<nsIDOMNode> newNode;
|
|
||||||
rv = node->CloneNode(aDeep, getter_AddRefs(newNode));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> newContent(do_QueryInterface(newNode));
|
|
||||||
NS_ASSERTION(newContent, "clone doesn't implement nsIContent");
|
|
||||||
rv = aDst->AppendChildTo(newContent, PR_FALSE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -105,7 +105,7 @@ public:
|
|||||||
void **aInstancePtr);
|
void **aInstancePtr);
|
||||||
|
|
||||||
// From nsGenericElement
|
// From nsGenericElement
|
||||||
nsresult CopyInnerTo(nsGenericElement* aDest, PRBool aDeep);
|
nsresult CopyInnerTo(nsGenericElement* aDest, PRBool aDeep) const;
|
||||||
|
|
||||||
// Implementation for nsIDOMNode
|
// Implementation for nsIDOMNode
|
||||||
NS_METHOD GetNodeName(nsAString& aNodeName);
|
NS_METHOD GetNodeName(nsAString& aNodeName);
|
||||||
|
@ -386,18 +386,19 @@ NS_HTML_CONTENT_INTERFACE_MAP_END
|
|||||||
// nsIDOMNode
|
// nsIDOMNode
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLInputElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const
|
||||||
{
|
{
|
||||||
*aReturn = nsnull;
|
*aResult = nsnull;
|
||||||
|
|
||||||
nsHTMLInputElement* it = new nsHTMLInputElement(mNodeInfo, PR_FALSE);
|
nsHTMLInputElement *it = new nsHTMLInputElement(aNodeInfo, PR_FALSE);
|
||||||
if (!it) {
|
if (!it) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> kungFuDeathGrip(it);
|
nsCOMPtr<nsIContent> kungFuDeathGrip = it;
|
||||||
|
nsresult rv = CopyInnerTo(it, aDeep);
|
||||||
CopyInnerTo(it, aDeep);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case NS_FORM_INPUT_TEXT:
|
case NS_FORM_INPUT_TEXT:
|
||||||
@ -425,12 +426,17 @@ nsHTMLInputElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
kungFuDeathGrip.swap(*aReturn);
|
kungFuDeathGrip.swap(*aResult);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLInputElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
||||||
|
{
|
||||||
|
return nsGenericElement::CloneNode(aDeep, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsHTMLInputElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
nsHTMLInputElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||||
|
@ -114,8 +114,7 @@ NS_HTML_CONTENT_INTERFACE_MAP_AMBIGOUS_BEGIN(nsHTMLSharedListElement,
|
|||||||
NS_HTML_CONTENT_INTERFACE_MAP_END
|
NS_HTML_CONTENT_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_DOM_CLONENODE_AMBIGUOUS(nsHTMLSharedListElement,
|
NS_IMPL_DOM_CLONENODE(nsHTMLSharedListElement)
|
||||||
nsIDOMHTMLOListElement)
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_BOOL_ATTR(nsHTMLSharedListElement, Compact, compact)
|
NS_IMPL_BOOL_ATTR(nsHTMLSharedListElement, Compact, compact)
|
||||||
|
@ -485,18 +485,19 @@ nsHTMLScriptElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLScriptElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
nsHTMLScriptElement::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const
|
||||||
{
|
{
|
||||||
*aReturn = nsnull;
|
*aResult = nsnull;
|
||||||
|
|
||||||
nsHTMLScriptElement* it = new nsHTMLScriptElement(mNodeInfo, PR_FALSE);
|
nsHTMLScriptElement* it = new nsHTMLScriptElement(aNodeInfo, PR_FALSE);
|
||||||
if (!it) {
|
if (!it) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> kungFuDeathGrip(it);
|
nsCOMPtr<nsIContent> kungFuDeathGrip = it;
|
||||||
|
nsresult rv = CopyInnerTo(it, aDeep);
|
||||||
CopyInnerTo(it, aDeep);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// The clone should be marked evaluated if we are. It should also be marked
|
// The clone should be marked evaluated if we are. It should also be marked
|
||||||
// evaluated if we're evaluating, to handle the case when this script node's
|
// evaluated if we're evaluating, to handle the case when this script node's
|
||||||
@ -504,11 +505,17 @@ nsHTMLScriptElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|||||||
it->mIsEvaluated = mIsEvaluated || mEvaluating;
|
it->mIsEvaluated = mIsEvaluated || mEvaluating;
|
||||||
it->mLineNumber = mLineNumber;
|
it->mLineNumber = mLineNumber;
|
||||||
|
|
||||||
kungFuDeathGrip.swap(*aReturn);
|
kungFuDeathGrip.swap(*aResult);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLScriptElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
||||||
|
{
|
||||||
|
return nsGenericElement::CloneNode(aDeep, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLScriptElement::GetText(nsAString& aValue)
|
nsHTMLScriptElement::GetText(nsAString& aValue)
|
||||||
{
|
{
|
||||||
|
@ -198,7 +198,7 @@ NS_HTML_CONTENT_INTERFACE_MAP_AMBIGOUS_BEGIN(nsHTMLSharedElement,
|
|||||||
NS_HTML_CONTENT_INTERFACE_MAP_END
|
NS_HTML_CONTENT_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_DOM_CLONENODE_AMBIGUOUS(nsHTMLSharedElement, nsIDOMHTMLEmbedElement)
|
NS_IMPL_DOM_CLONENODE(nsHTMLSharedElement)
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////
|
/////////////////////////////////////////////
|
||||||
|
@ -124,7 +124,9 @@ public:
|
|||||||
nsHTMLUnknownElement(nsINodeInfo *aNodeInfo);
|
nsHTMLUnknownElement(nsINodeInfo *aNodeInfo);
|
||||||
|
|
||||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
|
||||||
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
|
nsresult Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const;
|
||||||
|
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode **aResult);
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_INTERFACE_MAP_BEGIN(nsHTMLUnknownElement)
|
NS_INTERFACE_MAP_BEGIN(nsHTMLUnknownElement)
|
||||||
|
@ -86,7 +86,7 @@ public:
|
|||||||
PRBool aNotify);
|
PRBool aNotify);
|
||||||
protected:
|
protected:
|
||||||
// Dummy init method to make the NS_IMPL_NS_NEW_SVG_ELEMENT and
|
// Dummy init method to make the NS_IMPL_NS_NEW_SVG_ELEMENT and
|
||||||
// NS_IMPL_SVG_DOM_CLONENODE usable with this class. This should be
|
// NS_IMPL_DOM_CLONENODE_WITH_INIT usable with this class. This should be
|
||||||
// completely optimized away.
|
// completely optimized away.
|
||||||
inline nsresult Init()
|
inline nsresult Init()
|
||||||
{
|
{
|
||||||
|
@ -71,11 +71,6 @@ public:
|
|||||||
virtual void List(FILE* out, PRInt32 aIndent) const;
|
virtual void List(FILE* out, PRInt32 aIndent) const;
|
||||||
virtual void DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const;
|
virtual void DumpContent(FILE* out, PRInt32 aIndent,PRBool aDumpAll) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual already_AddRefed<nsITextContent> CloneContent(PRBool aCloneText,
|
|
||||||
nsIDocument *aOwnerDocument);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
@ -154,28 +149,14 @@ nsXMLCDATASection::GetNodeType(PRUint16* aNodeType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsGenericDOMDataNode*
|
||||||
nsXMLCDATASection::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
nsXMLCDATASection::Clone(nsIDocument *aOwnerDocument, PRBool aCloneText) const
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsITextContent> textContent = CloneContent(PR_TRUE, GetOwnerDoc());
|
nsXMLCDATASection* it = new nsXMLCDATASection(aOwnerDocument);
|
||||||
NS_ENSURE_TRUE(textContent, NS_ERROR_OUT_OF_MEMORY);
|
if (it && aCloneText) {
|
||||||
|
|
||||||
return CallQueryInterface(textContent, aReturn);
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<nsITextContent>
|
|
||||||
nsXMLCDATASection::CloneContent(PRBool aCloneText, nsIDocument *aOwnerDocument)
|
|
||||||
{
|
|
||||||
nsXMLCDATASection* it = new nsXMLCDATASection(nsnull);
|
|
||||||
if (!it)
|
|
||||||
return nsnull;
|
|
||||||
|
|
||||||
if (aCloneText) {
|
|
||||||
it->mText = mText;
|
it->mText = mText;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ADDREF(it);
|
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,24 +166,14 @@ nsXMLProcessingInstruction::GetNodeType(PRUint16* aNodeType)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsGenericDOMDataNode*
|
||||||
nsXMLProcessingInstruction::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
nsXMLProcessingInstruction::Clone(nsIDocument *aOwnerDocument,
|
||||||
|
PRBool aCloneText) const
|
||||||
{
|
{
|
||||||
nsAutoString data;
|
nsAutoString data;
|
||||||
GetData(data);
|
GetData(data);
|
||||||
|
|
||||||
nsIDocument *document = GetOwnerDoc();
|
return new nsXMLProcessingInstruction(mTarget, data, aOwnerDocument);
|
||||||
// We really want to pass the document here, but can't yet. Waiting
|
|
||||||
// on BindToTree.
|
|
||||||
nsXMLProcessingInstruction *pi =
|
|
||||||
new nsXMLProcessingInstruction(mTarget, data, nsnull);
|
|
||||||
if (!pi) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*aReturn = pi);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -59,7 +59,6 @@ public:
|
|||||||
|
|
||||||
// nsIDOMNode
|
// nsIDOMNode
|
||||||
NS_IMETHOD SetNodeValue(const nsAString& aData);
|
NS_IMETHOD SetNodeValue(const nsAString& aData);
|
||||||
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn);
|
|
||||||
|
|
||||||
// nsIContent
|
// nsIContent
|
||||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
@ -78,6 +77,8 @@ protected:
|
|||||||
nsAString& aType,
|
nsAString& aType,
|
||||||
nsAString& aMedia,
|
nsAString& aMedia,
|
||||||
PRBool* aIsAlternate);
|
PRBool* aIsAlternate);
|
||||||
|
virtual nsGenericDOMDataNode* Clone(nsIDocument *aOwnerDocument,
|
||||||
|
PRBool aCloneText) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// nsISupports implementation
|
// nsISupports implementation
|
||||||
@ -141,22 +142,6 @@ nsXMLStylesheetPI::SetNodeValue(const nsAString& aNodeValue)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXMLStylesheetPI::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|
||||||
{
|
|
||||||
nsAutoString data;
|
|
||||||
GetData(data);
|
|
||||||
|
|
||||||
nsXMLStylesheetPI *pi = new nsXMLStylesheetPI(data, nsnull);
|
|
||||||
if (!pi) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*aReturn = pi);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// nsStyleLinkElement
|
// nsStyleLinkElement
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
@ -249,6 +234,15 @@ nsXMLStylesheetPI::GetStyleSheetInfo(nsAString& aTitle,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsGenericDOMDataNode*
|
||||||
|
nsXMLStylesheetPI::Clone(nsIDocument *aOwnerDocument, PRBool aCloneText) const
|
||||||
|
{
|
||||||
|
nsAutoString data;
|
||||||
|
GetData(data);
|
||||||
|
|
||||||
|
return new nsXMLStylesheetPI(data, aOwnerDocument);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewXMLStylesheetProcessingInstruction(nsIContent** aInstancePtrResult,
|
NS_NewXMLStylesheetProcessingInstruction(nsIContent** aInstancePtrResult,
|
||||||
const nsAString& aData,
|
const nsAString& aData,
|
||||||
|
@ -422,22 +422,20 @@ nsXTFElementWrapper::IntrinsicState() const
|
|||||||
return mIntrinsicState;
|
return mIntrinsicState;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
nsresult
|
||||||
// nsIDOMNode methods:
|
nsXTFElementWrapper::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const
|
||||||
NS_IMETHODIMP
|
|
||||||
nsXTFElementWrapper::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
|
||||||
{
|
{
|
||||||
*aResult = nsnull;
|
*aResult = nsnull;
|
||||||
nsCOMPtr<nsIContent> it;
|
nsCOMPtr<nsIContent> it;
|
||||||
nsContentUtils::GetXTFService()->CreateElement(getter_AddRefs(it),
|
nsContentUtils::GetXTFService()->CreateElement(getter_AddRefs(it),
|
||||||
mNodeInfo);
|
aNodeInfo);
|
||||||
if (!it)
|
if (!it)
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> kungFuDeathGrip(do_QueryInterface(it));
|
|
||||||
nsXTFElementWrapper* wrapper =
|
nsXTFElementWrapper* wrapper =
|
||||||
NS_STATIC_CAST(nsXTFElementWrapper*, NS_STATIC_CAST(nsIContent*, it.get()));
|
NS_STATIC_CAST(nsXTFElementWrapper*,
|
||||||
|
NS_STATIC_CAST(nsIContent*, it.get()));
|
||||||
nsresult rv = CopyInnerTo(wrapper, aDeep);
|
nsresult rv = CopyInnerTo(wrapper, aDeep);
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
@ -454,7 +452,7 @@ nsXTFElementWrapper::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kungFuDeathGrip.swap(*aResult);
|
it.swap(*aResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapper->CloneState(this);
|
wrapper->CloneState(this);
|
||||||
|
@ -105,9 +105,6 @@ public:
|
|||||||
virtual void BeginAddingChildren();
|
virtual void BeginAddingChildren();
|
||||||
virtual void DoneAddingChildren();
|
virtual void DoneAddingChildren();
|
||||||
|
|
||||||
// nsIDOMNode specializations:
|
|
||||||
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode **aResult);
|
|
||||||
|
|
||||||
// nsIDOMElement specializations:
|
// nsIDOMElement specializations:
|
||||||
NS_IMETHOD GetAttribute(const nsAString& aName,
|
NS_IMETHOD GetAttribute(const nsAString& aName,
|
||||||
nsAString& aReturn);
|
nsAString& aReturn);
|
||||||
@ -126,6 +123,8 @@ public:
|
|||||||
{
|
{
|
||||||
return GetXTFElement()->CloneState(aElement);
|
return GetXTFElement()->CloneState(aElement);
|
||||||
}
|
}
|
||||||
|
nsresult Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// to be implemented by subclasses:
|
// to be implemented by subclasses:
|
||||||
|
@ -154,9 +154,6 @@
|
|||||||
|
|
||||||
#include "nsIControllers.h"
|
#include "nsIControllers.h"
|
||||||
|
|
||||||
// The XUL interfaces implemented by the RDF content node.
|
|
||||||
#include "nsIDOMXULElement.h"
|
|
||||||
|
|
||||||
// The XUL doc interface
|
// The XUL doc interface
|
||||||
#include "nsIDOMXULDocument.h"
|
#include "nsIDOMXULDocument.h"
|
||||||
|
|
||||||
@ -345,7 +342,6 @@ PRUint32 nsXULPrototypeAttribute::gNumCacheFills;
|
|||||||
|
|
||||||
nsXULElement::nsXULElement(nsINodeInfo* aNodeInfo)
|
nsXULElement::nsXULElement(nsINodeInfo* aNodeInfo)
|
||||||
: nsGenericElement(aNodeInfo),
|
: nsGenericElement(aNodeInfo),
|
||||||
mPrototype(nsnull),
|
|
||||||
mBindingParent(nsnull)
|
mBindingParent(nsnull)
|
||||||
{
|
{
|
||||||
XUL_PROTOTYPE_ATTRIBUTE_METER(gNumElements);
|
XUL_PROTOTYPE_ATTRIBUTE_METER(gNumElements);
|
||||||
@ -364,11 +360,32 @@ nsXULElement::~nsXULElement()
|
|||||||
if (slots) {
|
if (slots) {
|
||||||
NS_IF_RELEASE(slots->mControllers); // Forces release
|
NS_IF_RELEASE(slots->mControllers); // Forces release
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPrototype)
|
|
||||||
mPrototype->Release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
already_AddRefed<nsXULElement>
|
||||||
|
nsXULElement::Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
|
||||||
|
PRBool aIsScriptable)
|
||||||
|
{
|
||||||
|
nsXULElement *element = new nsXULElement(aNodeInfo);
|
||||||
|
if (element) {
|
||||||
|
NS_ADDREF(element);
|
||||||
|
|
||||||
|
element->mPrototype = aPrototype;
|
||||||
|
|
||||||
|
if (aIsScriptable) {
|
||||||
|
// Check each attribute on the prototype to see if we need to do
|
||||||
|
// any additional processing and hookup that would otherwise be
|
||||||
|
// done 'automagically' by SetAttr().
|
||||||
|
for (PRUint32 i = 0; i < aPrototype->mNumAttributes; ++i) {
|
||||||
|
element->AddListenerFor(aPrototype->mAttributes[i].mName,
|
||||||
|
PR_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsXULElement::Create(nsXULPrototypeElement* aPrototype,
|
nsXULElement::Create(nsXULPrototypeElement* aPrototype,
|
||||||
@ -396,27 +413,19 @@ nsXULElement::Create(nsXULPrototypeElement* aPrototype,
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nodeInfo = aPrototype->mNodeInfo;
|
nodeInfo = aPrototype->mNodeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRefPtr<nsXULElement> element = new nsXULElement(nodeInfo);
|
nsRefPtr<nsXULElement> element = Create(aPrototype, nodeInfo,
|
||||||
|
aIsScriptable);
|
||||||
if (! element)
|
if (!element) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
element->mPrototype = aPrototype;
|
element->mPrototype = aPrototype;
|
||||||
|
|
||||||
aPrototype->AddRef();
|
|
||||||
|
|
||||||
if (aIsScriptable) {
|
|
||||||
// Check each attribute on the prototype to see if we need to do
|
|
||||||
// any additional processing and hookup that would otherwise be
|
|
||||||
// done 'automagically' by SetAttr().
|
|
||||||
for (PRUint32 i = 0; i < aPrototype->mNumAttributes; ++i)
|
|
||||||
element->AddListenerFor(aPrototype->mAttributes[i].mName, PR_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*aResult = element.get());
|
NS_ADDREF(*aResult = element.get());
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,10 +440,7 @@ NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo)
|
|||||||
nsXULElement* element = new nsXULElement(aNodeInfo);
|
nsXULElement* element = new nsXULElement(aNodeInfo);
|
||||||
NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
// Using kungFuDeathGrip so an early return will clean up properly.
|
NS_ADDREF(*aResult = element);
|
||||||
nsCOMPtr<nsIContent> kungFuDeathGrip = element;
|
|
||||||
|
|
||||||
kungFuDeathGrip.swap(*aResult);
|
|
||||||
|
|
||||||
#ifdef DEBUG_ATTRIBUTE_STATS
|
#ifdef DEBUG_ATTRIBUTE_STATS
|
||||||
{
|
{
|
||||||
@ -501,12 +507,11 @@ nsXULElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// nsIDOMNode interface
|
// nsIDOMNode interface
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
nsXULElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
nsXULElement::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||||
|
nsIContent **aResult) const
|
||||||
{
|
{
|
||||||
nsresult rv;
|
*aResult = nsnull;
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> result;
|
|
||||||
|
|
||||||
// XXX setting document on some nodes not in a document so XBL will bind
|
// XXX setting document on some nodes not in a document so XBL will bind
|
||||||
// and chrome won't break. Make XBL bind to document-less nodes!
|
// and chrome won't break. Make XBL bind to document-less nodes!
|
||||||
@ -522,26 +527,18 @@ nsXULElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|||||||
PRBool fakeBeingInDocument = PR_TRUE;
|
PRBool fakeBeingInDocument = PR_TRUE;
|
||||||
|
|
||||||
// If we have a prototype, so will our clone.
|
// If we have a prototype, so will our clone.
|
||||||
|
nsRefPtr<nsXULElement> element;
|
||||||
if (mPrototype) {
|
if (mPrototype) {
|
||||||
rv = nsXULElement::Create(mPrototype, GetOwnerDoc(), PR_TRUE,
|
element = nsXULElement::Create(mPrototype, aNodeInfo, PR_TRUE);
|
||||||
getter_AddRefs(result));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
fakeBeingInDocument = IsInDoc();
|
fakeBeingInDocument = IsInDoc();
|
||||||
} else {
|
}
|
||||||
rv = NS_NewXULElement(getter_AddRefs(result), mNodeInfo);
|
else {
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
element = new nsXULElement(aNodeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy attributes
|
if (!element) {
|
||||||
PRInt32 count = mAttrsAndChildren.AttrCount();
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
for (PRInt32 i = 0; i < count; ++i) {
|
|
||||||
const nsAttrName* name = mAttrsAndChildren.GetSafeAttrNameAt(i);
|
|
||||||
nsAutoString valStr;
|
|
||||||
mAttrsAndChildren.AttrAt(i)->ToString(valStr);
|
|
||||||
rv = result->SetAttr(name->NamespaceID(), name->LocalName(),
|
|
||||||
name->GetPrefix(), valStr, PR_FALSE);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX TODO: set up RDF generic builder n' stuff if there is a
|
// XXX TODO: set up RDF generic builder n' stuff if there is a
|
||||||
@ -551,44 +548,24 @@ nsXULElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
|||||||
|
|
||||||
// Note that we're _not_ copying mControllers.
|
// Note that we're _not_ copying mControllers.
|
||||||
|
|
||||||
if (aDeep) {
|
nsresult rv = CopyInnerTo(element, aDeep);
|
||||||
// Copy cloned children!
|
if (NS_SUCCEEDED(rv)) {
|
||||||
PRInt32 i, count = mAttrsAndChildren.ChildCount();
|
NS_ADDREF(*aResult = element);
|
||||||
for (i = 0; i < count; ++i) {
|
|
||||||
nsIContent* child = mAttrsAndChildren.ChildAt(i);
|
|
||||||
|
|
||||||
NS_ASSERTION(child != nsnull, "null ptr");
|
|
||||||
if (! child)
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> domchild = do_QueryInterface(child);
|
|
||||||
NS_ASSERTION(domchild != nsnull, "child is not a DOM node");
|
|
||||||
if (! domchild)
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> newdomchild;
|
|
||||||
rv = domchild->CloneNode(PR_TRUE, getter_AddRefs(newdomchild));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIContent> newchild = do_QueryInterface(newdomchild);
|
|
||||||
NS_ASSERTION(newchild != nsnull, "newdomchild is not an nsIContent");
|
|
||||||
if (! newchild)
|
|
||||||
return NS_ERROR_UNEXPECTED;
|
|
||||||
|
|
||||||
rv = result->AppendChildTo(newchild, PR_FALSE);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fakeBeingInDocument) {
|
if (fakeBeingInDocument) {
|
||||||
// Don't use BindToTree here so we don't confuse the descendant
|
// Don't use BindToTree here so we don't confuse the descendant
|
||||||
// non-XUL nodes.
|
// non-XUL nodes.
|
||||||
NS_STATIC_CAST(nsXULElement*,
|
element->mParentPtrBits |= PARENT_BIT_INDOCUMENT;
|
||||||
NS_STATIC_CAST(nsIContent*, result.get()))->
|
|
||||||
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return CallQueryInterface(result, aReturn);
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsXULElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
||||||
|
{
|
||||||
|
return nsGenericElement::CloneNode(aDeep, aResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -588,7 +588,7 @@ protected:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Required fields
|
// Required fields
|
||||||
nsXULPrototypeElement* mPrototype;
|
nsRefPtr<nsXULPrototypeElement> mPrototype;
|
||||||
nsCOMPtr<nsIEventListenerManager> mListenerManager; // [OWNER]
|
nsCOMPtr<nsIEventListenerManager> mListenerManager; // [OWNER]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -645,6 +645,10 @@ protected:
|
|||||||
|
|
||||||
friend nsresult
|
friend nsresult
|
||||||
NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
|
NS_NewXULElement(nsIContent** aResult, nsINodeInfo *aNodeInfo);
|
||||||
|
|
||||||
|
static already_AddRefed<nsXULElement>
|
||||||
|
Create(nsXULPrototypeElement* aPrototype, nsINodeInfo *aNodeInfo,
|
||||||
|
PRBool aIsScriptable);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2064,7 +2064,7 @@ nsCSSFrameConstructor::CreateGeneratedFrameFor(nsIFrame* aParentFram
|
|||||||
nsresult rv = NS_ERROR_FAILURE;
|
nsresult rv = NS_ERROR_FAILURE;
|
||||||
if (attrName) {
|
if (attrName) {
|
||||||
nsIFrame* textFrame = nsnull;
|
nsIFrame* textFrame = nsnull;
|
||||||
rv = NS_NewAttributeContent(attrNameSpace, attrName,
|
rv = NS_NewAttributeContent(mDocument, attrNameSpace, attrName,
|
||||||
getter_AddRefs(content));
|
getter_AddRefs(content));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ NS_NewBlockFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame,
|
|||||||
|
|
||||||
// Special Generated Content Frame
|
// Special Generated Content Frame
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewAttributeContent(PRInt32 aNameSpaceID, nsIAtom* aAttrName,
|
NS_NewAttributeContent(nsIDocument* aOwnerDoc, PRInt32 aNameSpaceID,
|
||||||
nsIContent** aResult);
|
nsIAtom* aAttrName, nsIContent** aResult);
|
||||||
|
|
||||||
// Create a basic area frame but the GetFrameForPoint is overridden to always
|
// Create a basic area frame but the GetFrameForPoint is overridden to always
|
||||||
// return the option frame
|
// return the option frame
|
||||||
|
Loading…
x
Reference in New Issue
Block a user