Fix for bug 264308 (Implement DOM Level 3 UserData API). r/sr=jst.
git-svn-id: svn://10.0.0.236/trunk@183126 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
28f860e4f4
commit
7645808305
@ -748,6 +748,8 @@ public:
|
||||
{ if (aStatus) *aStatus = NS_ERROR_NOT_IMPLEMENTED; return nsnull; }
|
||||
|
||||
|
||||
virtual void SetHasProperties() = 0;
|
||||
|
||||
/**
|
||||
* Clones this node, using aNodeInfoManager to get the nodeinfo for the
|
||||
* clone. When cloning an element, all attributes of the element will be
|
||||
|
||||
@ -54,8 +54,8 @@
|
||||
#include "nsPropertyTable.h"
|
||||
#include "nsHashSets.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
class nsIAtom;
|
||||
class nsIContent;
|
||||
class nsIStyledContent;
|
||||
class nsPresContext;
|
||||
@ -91,6 +91,8 @@ class nsICSSLoader;
|
||||
class nsHTMLStyleSheet;
|
||||
class nsIHTMLCSSStyleSheet;
|
||||
class nsILayoutHistoryState;
|
||||
class nsIVariant;
|
||||
class nsIDOMUserDataHandler;
|
||||
|
||||
// IID for the nsIDocument interface
|
||||
#define NS_IDOCUMENT_IID \
|
||||
@ -780,6 +782,114 @@ public:
|
||||
*/
|
||||
virtual void NotifyURIVisitednessChanged(nsIURI* aURI) = 0;
|
||||
|
||||
/**
|
||||
* Associate an object aData to aKey on node aObject. Should only be used to
|
||||
* implement the DOM Level 3 UserData API.
|
||||
*
|
||||
* @param aObject cannonical nsISupports pointer of the node to add aData to
|
||||
* @param aKey the key to associate the object to
|
||||
* @param aData the object to associate to aKey on aObject
|
||||
* @param aHandler the UserDataHandler to call when the node is
|
||||
* cloned/deleted/imported/renamed
|
||||
* @param aResult [out] the previously registered object for aKey on aObject,
|
||||
* if any
|
||||
* @return whether adding the object and UserDataHandler succeeded
|
||||
*/
|
||||
nsresult SetUserData(const nsISupports *aObject, const nsAString &aKey,
|
||||
nsIVariant *aData, nsIDOMUserDataHandler *aHandler,
|
||||
nsIVariant **aResult)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
|
||||
if (!key) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return SetUserData(aObject, key, aData, aHandler, aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate an object aData to aKey on node aObject. If aData is null any
|
||||
* previously registered object and UserDataHandler associated to aKey on
|
||||
* aObject will be removed. Should only be used to implement the DOM Level 3
|
||||
* UserData API.
|
||||
*
|
||||
* @param aObject cannonical nsISupports pointer of the node to add aData to
|
||||
* @param aKey the key to associate the object to
|
||||
* @param aData the object to associate to aKey on aObject (may be nulll)
|
||||
* @param aHandler the UserDataHandler to call when the node is
|
||||
* cloned/deleted/imported/renamed (may be nulll)
|
||||
* @param aResult [out] the previously registered object for aKey on aObject,
|
||||
* if any
|
||||
* @return whether adding the object and UserDataHandler succeeded
|
||||
*/
|
||||
virtual nsresult SetUserData(const nsISupports *aObject, nsIAtom *aKey,
|
||||
nsIVariant *aData,
|
||||
nsIDOMUserDataHandler *aHandler,
|
||||
nsIVariant **aResult) = 0;
|
||||
|
||||
/**
|
||||
* Get the object associated to aKey on node aObject. This will return NS_OK
|
||||
* if no object was associated to aKey on aObject. Should only be used to
|
||||
* implement the DOM Level 3 UserData API.
|
||||
*
|
||||
* @param aObject cannonical nsISupports pointer of the node to get the
|
||||
* object for
|
||||
* @param aKey the key the object is associated to
|
||||
* @param aResult [out] the registered object for aKey on aObject, if any
|
||||
* @return whether an error occured while looking up the registered object
|
||||
*/
|
||||
nsresult GetUserData(nsISupports *aObject, const nsAString &aKey,
|
||||
nsIVariant **aResult)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
|
||||
if (!key) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return GetUserData(aObject, key, aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object associated to aKey on node aObject. This will return NS_OK
|
||||
* if no object was associated to aKey on aObject. Should only be used to
|
||||
* implement the DOM Level 3 UserData API.
|
||||
*
|
||||
* @param aObject cannonical nsISupports pointer of the node to get the
|
||||
* object for
|
||||
* @param aKey the key the object is associated to
|
||||
* @param aResult [out] the registered object for aKey on aObject, if any
|
||||
* @return whether an error occured while looking up the registered object
|
||||
*/
|
||||
virtual nsresult GetUserData(const nsISupports *aObject, nsIAtom *aKey,
|
||||
nsIVariant **aResult) = 0;
|
||||
|
||||
/**
|
||||
* Call the UserDataHandler associated with aKey on node aObject. Should only
|
||||
* be used to implement the DOM Level 3 UserData API.
|
||||
*
|
||||
* @param aOperation the type of operation that is being performed on the
|
||||
* node. @see nsIDOMUserDataHandler
|
||||
* @param aObject cannonical nsISupports pointer of the node to call the
|
||||
* UserDataHandler for
|
||||
* @param aSource the node that aOperation is being performed on, or null if
|
||||
* the operation is a deletion
|
||||
* @param aDest the newly created node if any, or null
|
||||
*/
|
||||
virtual void CallUserDataHandler(PRUint16 aOperation,
|
||||
const nsISupports *aObject,
|
||||
nsIDOMNode *aSource, nsIDOMNode *aDest) = 0;
|
||||
|
||||
/**
|
||||
* Copy the objects and UserDataHandlers for node aObject to a new document.
|
||||
* Should only be used to implement the DOM Level 3 UserData API.
|
||||
*
|
||||
* @param aObject cannonical nsISupports pointer of the node to copy objects
|
||||
* and UserDataHandlers for
|
||||
* @param aDestination the new document
|
||||
*/
|
||||
virtual void CopyUserData(const nsISupports *aObject,
|
||||
nsIDocument *aDestination) = 0;
|
||||
|
||||
protected:
|
||||
~nsIDocument()
|
||||
{
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include "nsDOMString.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
PRBool nsDOMAttribute::sInitialized;
|
||||
@ -67,6 +68,9 @@ nsDOMAttribute::~nsDOMAttribute()
|
||||
{
|
||||
nsIDocument *doc = GetOwnerDoc();
|
||||
if (doc)
|
||||
doc->CallUserDataHandler(nsIDOMUserDataHandler::NODE_DELETED,
|
||||
NS_STATIC_CAST(nsIDOMAttr*, this), nsnull,
|
||||
nsnull);
|
||||
doc->PropertyTable()->DeleteAllPropertiesFor(this);
|
||||
|
||||
NS_IF_RELEASE(mChild);
|
||||
@ -347,17 +351,37 @@ nsDOMAttribute::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
|
||||
NS_IMETHODIMP
|
||||
nsDOMAttribute::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
||||
{
|
||||
nsDOMAttribute* newAttr;
|
||||
*aReturn = nsnull;
|
||||
|
||||
nsAutoString value;
|
||||
GetValue(value);
|
||||
newAttr = new nsDOMAttribute(nsnull, mNodeInfo, value);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> newAttr = new nsDOMAttribute(nsnull, mNodeInfo, value);
|
||||
if (!newAttr) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return CallQueryInterface(newAttr, aReturn);
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
if (document) {
|
||||
// XXX For now, nsDOMAttribute has only one child. We need to notify
|
||||
// about importing it, so we force creation here.
|
||||
nsCOMPtr<nsIDOMNode> child, newChild;
|
||||
GetFirstChild(getter_AddRefs(child));
|
||||
newAttr->GetFirstChild(getter_AddRefs(newChild));
|
||||
|
||||
nsCOMPtr<nsISupports> childSupports = do_QueryInterface(child);
|
||||
if (childSupports && newChild) {
|
||||
document->CallUserDataHandler(nsIDOMUserDataHandler::NODE_CLONED,
|
||||
childSupports, child, newChild);
|
||||
}
|
||||
document->CallUserDataHandler(nsIDOMUserDataHandler::NODE_CLONED,
|
||||
NS_STATIC_CAST(nsIDOMAttr*, this), this,
|
||||
newAttr);
|
||||
}
|
||||
|
||||
newAttr.swap(*aReturn);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -625,23 +649,25 @@ nsDOMAttribute::GetFeature(const nsAString& aFeature,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMAttribute::SetUserData(const nsAString& aKey,
|
||||
nsIVariant* aData,
|
||||
nsDOMAttribute::SetUserData(const nsAString& aKey, nsIVariant* aData,
|
||||
nsIDOMUserDataHandler* aHandler,
|
||||
nsIVariant** aReturn)
|
||||
nsIVariant** aResult)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsDocument::SetUserData()");
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return document->SetUserData(NS_STATIC_CAST(nsIDOMAttr*, this), aKey, aData,
|
||||
aHandler, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMAttribute::GetUserData(const nsAString& aKey,
|
||||
nsIVariant** aReturn)
|
||||
nsDOMAttribute::GetUserData(const nsAString& aKey, nsIVariant** aResult)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsDocument::GetUserData()");
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return document->GetUserData(NS_STATIC_CAST(nsIDOMAttr*, this), aKey,
|
||||
aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
@ -116,7 +116,7 @@
|
||||
static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
|
||||
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
#include "nsScriptEventManager.h"
|
||||
#include "nsIDOMXPathEvaluator.h"
|
||||
#include "nsIXPathEvaluatorInternal.h"
|
||||
@ -685,6 +685,9 @@ nsDocument::~nsDocument()
|
||||
{
|
||||
mInDestructor = PR_TRUE;
|
||||
|
||||
CallUserDataHandler(nsIDOMUserDataHandler::NODE_DELETED,
|
||||
NS_STATIC_CAST(nsIDocument*, this), nsnull, nsnull);
|
||||
|
||||
// XXX Inform any remaining observers that we are going away.
|
||||
// Note that this currently contradicts the rule that all
|
||||
// observers must hold on to live references to the document.
|
||||
@ -2821,6 +2824,7 @@ nsDocument::ImportNode(nsIDOMNode* aImportedNode,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsIDocument *document;
|
||||
PRUint16 nodeType;
|
||||
aImportedNode->GetNodeType(&nodeType);
|
||||
switch (nodeType) {
|
||||
@ -2829,7 +2833,7 @@ nsDocument::ImportNode(nsIDOMNode* aImportedNode,
|
||||
nsCOMPtr<nsIAttribute> attr = do_QueryInterface(aImportedNode);
|
||||
NS_ENSURE_TRUE(attr, NS_ERROR_FAILURE);
|
||||
|
||||
nsIDocument *document = attr->GetOwnerDoc();
|
||||
document = attr->GetOwnerDoc();
|
||||
|
||||
nsCOMPtr<nsIDOMAttr> domAttr = do_QueryInterface(aImportedNode);
|
||||
nsAutoString value;
|
||||
@ -2854,9 +2858,22 @@ nsDocument::ImportNode(nsIDOMNode* aImportedNode,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
clone.swap(*aResult);
|
||||
if (document) {
|
||||
// XXX For now, nsDOMAttribute has only one child. We need to notify
|
||||
// about importing it, so we force creation here.
|
||||
nsCOMPtr<nsIDOMNode> child, newChild;
|
||||
aImportedNode->GetFirstChild(getter_AddRefs(child));
|
||||
clone->GetFirstChild(getter_AddRefs(newChild));
|
||||
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsISupports> childSupports = do_QueryInterface(child);
|
||||
if (childSupports && newChild) {
|
||||
document->CallUserDataHandler(nsIDOMUserDataHandler::NODE_IMPORTED,
|
||||
childSupports, child, newChild);
|
||||
}
|
||||
}
|
||||
|
||||
clone.swap(*aResult);
|
||||
break;
|
||||
}
|
||||
case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
|
||||
case nsIDOMNode::ELEMENT_NODE:
|
||||
@ -2868,12 +2885,16 @@ nsDocument::ImportNode(nsIDOMNode* aImportedNode,
|
||||
nsCOMPtr<nsIContent> imported = do_QueryInterface(aImportedNode);
|
||||
NS_ENSURE_TRUE(imported, NS_ERROR_FAILURE);
|
||||
|
||||
document = imported->GetOwnerDoc();
|
||||
nsCOMPtr<nsIContent> clone;
|
||||
rv = imported->CloneContent(mNodeInfoManager, aDeep,
|
||||
getter_AddRefs(clone));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(clone, aResult);
|
||||
rv = CallQueryInterface(clone, aResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
break;
|
||||
}
|
||||
case nsIDOMNode::ENTITY_NODE:
|
||||
case nsIDOMNode::ENTITY_REFERENCE_NODE:
|
||||
@ -2888,6 +2909,14 @@ nsDocument::ImportNode(nsIDOMNode* aImportedNode,
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (document) {
|
||||
nsCOMPtr<nsISupports> importedNode = do_QueryInterface(aImportedNode);
|
||||
document->CallUserDataHandler(nsIDOMUserDataHandler::NODE_IMPORTED,
|
||||
importedNode, aImportedNode, *aResult);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -3743,25 +3772,206 @@ nsDocument::GetFeature(const nsAString& aFeature,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::SetUserData(const nsAString& aKey,
|
||||
nsIVariant* aData,
|
||||
nsIDOMUserDataHandler* aHandler,
|
||||
nsIVariant** aReturn)
|
||||
nsDocument::SetUserData(const nsAString &aKey,
|
||||
nsIVariant *aData,
|
||||
nsIDOMUserDataHandler *aHandler,
|
||||
nsIVariant **aResult)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsDocument::SetUserData()");
|
||||
nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
|
||||
if (!key) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return SetUserData(NS_STATIC_CAST(nsIDocument*, this), key, aData, aHandler,
|
||||
aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetUserData(const nsAString& aKey,
|
||||
nsIVariant** aReturn)
|
||||
nsDocument::GetUserData(const nsAString &aKey,
|
||||
nsIVariant **aResult)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsDocument::GetUserData()");
|
||||
nsCOMPtr<nsIAtom> key = do_GetAtom(aKey);
|
||||
if (!key) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return GetUserData(NS_STATIC_CAST(nsIDocument*, this), key, aResult);
|
||||
}
|
||||
|
||||
static void
|
||||
ReleaseDOMUserData(void *aObject,
|
||||
nsIAtom *aPropertyName,
|
||||
void *aPropertyValue,
|
||||
void *aData)
|
||||
{
|
||||
nsISupports *propertyValue = NS_STATIC_CAST(nsISupports*, aPropertyValue);
|
||||
NS_RELEASE(propertyValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::SetUserData(const nsISupports *aObject,
|
||||
nsIAtom *aKey,
|
||||
nsIVariant *aData,
|
||||
nsIDOMUserDataHandler *aHandler,
|
||||
nsIVariant **aResult)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsISupports> object =
|
||||
do_QueryInterface(NS_CONST_CAST(nsISupports*, aObject));
|
||||
NS_ASSERTION(object == aObject, "Use cannonical nsISupports pointer!");
|
||||
#endif
|
||||
|
||||
*aResult = nsnull;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
void *data;
|
||||
if (aData) {
|
||||
rv = mPropertyTable.SetProperty(aObject, DOM_USER_DATA, aKey, aData,
|
||||
ReleaseDOMUserData, &data);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ADDREF(aData);
|
||||
}
|
||||
else {
|
||||
data = mPropertyTable.UnsetProperty(aObject, DOM_USER_DATA, aKey);
|
||||
}
|
||||
|
||||
// Take over ownership of the old data from the property table.
|
||||
nsCOMPtr<nsIVariant> oldData = dont_AddRef(NS_STATIC_CAST(nsIVariant*,
|
||||
data));
|
||||
|
||||
if (aData && aHandler) {
|
||||
rv = mPropertyTable.SetProperty(aObject, DOM_USER_DATA_HANDLER, aKey,
|
||||
aHandler, ReleaseDOMUserData);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(aHandler);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsIDOMUserDataHandler *oldHandler =
|
||||
NS_STATIC_CAST(nsIDOMUserDataHandler*,
|
||||
mPropertyTable.UnsetProperty(aObject,
|
||||
DOM_USER_DATA_HANDLER,
|
||||
aKey));
|
||||
NS_IF_RELEASE(oldHandler);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
oldData.swap(*aResult);
|
||||
}
|
||||
else {
|
||||
// We failed to set the handler, remove the data.
|
||||
nsIVariant *variant =
|
||||
NS_STATIC_CAST(nsIVariant*,
|
||||
mPropertyTable.UnsetProperty(aObject, DOM_USER_DATA,
|
||||
aKey));
|
||||
NS_IF_RELEASE(variant);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::GetUserData(const nsISupports *aObject, nsIAtom *aKey,
|
||||
nsIVariant **aResult)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsISupports> object =
|
||||
do_QueryInterface(NS_CONST_CAST(nsISupports*, aObject));
|
||||
NS_ASSERTION(object == aObject, "Use cannonical nsISupports pointer!");
|
||||
#endif
|
||||
|
||||
*aResult = NS_STATIC_CAST(nsIVariant*,
|
||||
mPropertyTable.GetProperty(aObject, DOM_USER_DATA,
|
||||
aKey));
|
||||
|
||||
NS_IF_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct nsHandlerData
|
||||
{
|
||||
PRUint16 mOperation;
|
||||
nsCOMPtr<nsIDOMNode> mSource;
|
||||
nsCOMPtr<nsIDOMNode> mDest;
|
||||
nsDocument *mDocument;
|
||||
};
|
||||
|
||||
static void
|
||||
CallHandler(void *aObject, nsIAtom *aKey, void *aHandler, void *aData)
|
||||
{
|
||||
nsHandlerData *handlerData = NS_STATIC_CAST(nsHandlerData*, aData);
|
||||
nsCOMPtr<nsIDOMUserDataHandler> handler =
|
||||
NS_STATIC_CAST(nsIDOMUserDataHandler*, aHandler);
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
nsISupports *object = NS_STATIC_CAST(nsISupports*, aObject);
|
||||
nsresult rv = handlerData->mDocument->GetUserData(object, aKey,
|
||||
getter_AddRefs(data));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ASSERTION(data, "Handler without data?");
|
||||
|
||||
nsAutoString key;
|
||||
aKey->ToString(key);
|
||||
handler->Handle(handlerData->mOperation, key, data, handlerData->mSource,
|
||||
handlerData->mDest);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::CallUserDataHandler(PRUint16 aOperation,
|
||||
const nsISupports *aObject,
|
||||
nsIDOMNode *aSource, nsIDOMNode *aDest)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// XXX Should we guard from QI'ing nodes that are being destroyed?
|
||||
nsCOMPtr<nsISupports> object =
|
||||
do_QueryInterface(NS_CONST_CAST(nsISupports*, aObject));
|
||||
NS_ASSERTION(object == aObject, "Use cannonical nsISupports pointer!");
|
||||
#endif
|
||||
|
||||
nsHandlerData handlerData = { aOperation, aSource, aDest, this };
|
||||
|
||||
mPropertyTable.Enumerate(aObject, DOM_USER_DATA_HANDLER, CallHandler,
|
||||
&handlerData);
|
||||
}
|
||||
|
||||
struct nsCopyData
|
||||
{
|
||||
nsDocument *mSourceDocument;
|
||||
nsIDocument *mDestDocument;
|
||||
};
|
||||
|
||||
static void
|
||||
Copy(void *aObject, nsIAtom *aKey, void *aUserData, void *aData)
|
||||
{
|
||||
nsCopyData *data = NS_STATIC_CAST(nsCopyData*, aData);
|
||||
nsPropertyTable *propertyTable = data->mSourceDocument->PropertyTable();
|
||||
nsISupports *object = NS_STATIC_CAST(nsISupports*, aObject);
|
||||
nsIDOMUserDataHandler *handler =
|
||||
NS_STATIC_CAST(nsIDOMUserDataHandler*,
|
||||
propertyTable->GetProperty(object, DOM_USER_DATA_HANDLER,
|
||||
aKey));
|
||||
|
||||
nsCOMPtr<nsIVariant> result;
|
||||
data->mDestDocument->SetUserData(object, aKey,
|
||||
NS_STATIC_CAST(nsIVariant*, aUserData),
|
||||
handler, getter_AddRefs(result));
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::CopyUserData(const nsISupports *aObject, nsIDocument *aDestination)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsISupports> object =
|
||||
do_QueryInterface(NS_CONST_CAST(nsISupports*, aObject));
|
||||
NS_ASSERTION(object == aObject, "Use cannonical nsISupports pointer!");
|
||||
#endif
|
||||
|
||||
nsCopyData copyData = { this, aDestination };
|
||||
|
||||
mPropertyTable.Enumerate(aObject, DOM_USER_DATA, Copy, ©Data);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::LookupPrefix(const nsAString& aNamespaceURI,
|
||||
@ -3885,6 +4095,13 @@ nsDocument::AdoptNode(nsIDOMNode *source, nsIDOMNode **aReturn)
|
||||
{
|
||||
// Not allowing this yet, need to think about the security ramifications
|
||||
// of giving a node a brand new node info.
|
||||
|
||||
// if (NS_SUCCEEDED(rv)) {
|
||||
// nsCOMPtr<nsISupports> object = do_QueryInterface(source);
|
||||
// CallUserDataHandler(nsIDOMUserDataHandler::NODE_ADOPTED, object, source,
|
||||
// *aReturn);
|
||||
// }
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -3921,6 +4138,12 @@ nsDocument::RenameNode(nsIDOMNode *aNode,
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// if (NS_SUCCEEDED(rv)) {
|
||||
// nsCOMPtr<nsISupports> object = do_QueryInterface(aNode);
|
||||
// CallUserDataHandler(nsIDOMUserDataHandler::NODE_RENAMED, object, aNode,
|
||||
// *aReturn);
|
||||
// }
|
||||
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
||||
|
||||
@ -651,6 +651,21 @@ public:
|
||||
virtual NS_HIDDEN_(void) ForgetLink(nsIContent* aContent);
|
||||
virtual NS_HIDDEN_(void) NotifyURIVisitednessChanged(nsIURI* aURI);
|
||||
|
||||
NS_HIDDEN_(nsresult) SetUserData(const nsISupports *aObject,
|
||||
nsIAtom *aKey,
|
||||
nsIVariant *aData,
|
||||
nsIDOMUserDataHandler *aHandler,
|
||||
nsIVariant **aReturn);
|
||||
NS_HIDDEN_(nsresult) GetUserData(const nsISupports *aObject,
|
||||
nsIAtom *aKey,
|
||||
nsIVariant **aResult);
|
||||
NS_HIDDEN_(void) CallUserDataHandler(PRUint16 aOperation,
|
||||
const nsISupports *aObject,
|
||||
nsIDOMNode *aSource,
|
||||
nsIDOMNode *aDest);
|
||||
NS_HIDDEN_(void) CopyUserData(const nsISupports *aObject,
|
||||
nsIDocument *aDestination);
|
||||
|
||||
protected:
|
||||
|
||||
void DispatchContentLoadedEvents();
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
#include "nsIDOM3Node.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsDOMString.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
|
||||
class nsDocumentFragment : public nsGenericElement,
|
||||
public nsIDocumentFragment,
|
||||
@ -423,20 +424,24 @@ NS_IMETHODIMP
|
||||
nsDocumentFragment::SetUserData(const nsAString& aKey,
|
||||
nsIVariant* aData,
|
||||
nsIDOMUserDataHandler* aHandler,
|
||||
nsIVariant** aReturn)
|
||||
nsIVariant** aResult)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsDocumentFragment::SetUserData()");
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return document->SetUserData(NS_STATIC_CAST(nsIContent*, this), aKey, aData,
|
||||
aHandler, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentFragment::GetUserData(const nsAString& aKey,
|
||||
nsIVariant** aReturn)
|
||||
nsIVariant** aResult)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsDocumentFragment::GetUserData()");
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return document->GetUserData(NS_STATIC_CAST(nsIContent*, this), aKey,
|
||||
aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
@ -54,6 +54,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDOMString.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
|
||||
#include "pldhash.h"
|
||||
#include "prprf.h"
|
||||
@ -65,6 +66,16 @@ nsGenericDOMDataNode::nsGenericDOMDataNode(nsINodeInfo *aNodeInfo)
|
||||
|
||||
nsGenericDOMDataNode::~nsGenericDOMDataNode()
|
||||
{
|
||||
if (CouldHaveProperties()) {
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
if (document) {
|
||||
nsISupports *thisSupports = NS_STATIC_CAST(nsIContent*, this);
|
||||
document->CallUserDataHandler(nsIDOMUserDataHandler::NODE_DELETED,
|
||||
thisSupports, nsnull, nsnull);
|
||||
document->PropertyTable()->DeleteAllPropertiesFor(thisSupports);
|
||||
}
|
||||
}
|
||||
|
||||
if (CouldHaveEventListenerManager()) {
|
||||
PL_DHashTableOperate(&nsGenericElement::sEventListenerManagersHash,
|
||||
this, PL_DHASH_REMOVE);
|
||||
@ -283,7 +294,8 @@ nsGenericDOMDataNode::GetBaseURI(nsAString& aURI)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::CloneNode(PRBool aDeep, nsIDOMNode **aResult) const
|
||||
nsGenericDOMDataNode::CloneNode(PRBool aDeep, nsIDOMNode *aSource,
|
||||
nsIDOMNode **aResult) const
|
||||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
@ -292,7 +304,16 @@ nsGenericDOMDataNode::CloneNode(PRBool aDeep, nsIDOMNode **aResult) const
|
||||
getter_AddRefs(newContent));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(newContent, aResult);
|
||||
rv = CallQueryInterface(newContent, aResult);
|
||||
|
||||
nsIDocument *ownerDoc = GetOwnerDoc();
|
||||
if (NS_SUCCEEDED(rv) && ownerDoc && CouldHaveProperties()) {
|
||||
ownerDoc->CallUserDataHandler(nsIDOMUserDataHandler::NODE_CLONED,
|
||||
NS_STATIC_CAST(const nsIContent*, this),
|
||||
aSource, *aResult);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -656,6 +677,16 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
||||
nsIDocument *ownerDocument = GetOwnerDoc();
|
||||
if (aDocument != ownerDocument) {
|
||||
if (ownerDocument && CouldHaveProperties()) {
|
||||
nsISupports *thisSupports = NS_STATIC_CAST(nsIContent*, this);
|
||||
|
||||
// Copy UserData to the new document.
|
||||
ownerDocument->CopyUserData(thisSupports, aDocument);
|
||||
|
||||
// Remove all properties.
|
||||
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(thisSupports);
|
||||
}
|
||||
|
||||
// get a new nodeinfo
|
||||
nsNodeInfoManager *nodeInfoManager = aDocument->NodeInfoManager();
|
||||
nsCOMPtr<nsINodeInfo> newNodeInfo;
|
||||
|
||||
@ -151,9 +151,11 @@ public:
|
||||
* do the actual cloning of the node.
|
||||
*
|
||||
* @param aDeep if true all descendants will be cloned too
|
||||
* @param aSource nsIDOMNode pointer to this node
|
||||
* @param aResult the clone
|
||||
*/
|
||||
nsresult CloneNode(PRBool aDeep, nsIDOMNode **aResult) const;
|
||||
nsresult CloneNode(PRBool aDeep, nsIDOMNode *aSource,
|
||||
nsIDOMNode **aResult) const;
|
||||
|
||||
nsresult LookupPrefix(const nsAString& aNamespaceURI,
|
||||
nsAString& aPrefix);
|
||||
@ -226,6 +228,10 @@ public:
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual PRBool MayHaveFrame() const;
|
||||
virtual void SetHasProperties()
|
||||
{
|
||||
SetIsInAHash();
|
||||
}
|
||||
|
||||
/**
|
||||
* This calls Clone to do the actual cloning so that we end up with the
|
||||
@ -265,6 +271,11 @@ protected:
|
||||
virtual nsGenericDOMDataNode *Clone(nsINodeInfo *aNodeInfo,
|
||||
PRBool aCloneText) const = 0;
|
||||
|
||||
PRBool CouldHaveProperties() const
|
||||
{
|
||||
return GetIsInAHash();
|
||||
}
|
||||
|
||||
nsTextFragment mText;
|
||||
|
||||
private:
|
||||
@ -390,7 +401,7 @@ private:
|
||||
return nsGenericDOMDataNode::IsSupported(aFeature, aVersion, aReturn); \
|
||||
} \
|
||||
NS_IMETHOD CloneNode(PRBool aDeep, nsIDOMNode** aReturn) { \
|
||||
return nsGenericDOMDataNode::CloneNode(aDeep, aReturn); \
|
||||
return nsGenericDOMDataNode::CloneNode(aDeep, this, aReturn); \
|
||||
} \
|
||||
virtual nsGenericDOMDataNode *Clone(nsINodeInfo *aNodeInfo, \
|
||||
PRBool aCloneText) const;
|
||||
|
||||
@ -107,6 +107,7 @@
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsIDOMNSFeatureFactory.h"
|
||||
#include "nsIDOMDocumentType.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
|
||||
|
||||
/**
|
||||
@ -431,20 +432,28 @@ NS_IMETHODIMP
|
||||
nsNode3Tearoff::SetUserData(const nsAString& aKey,
|
||||
nsIVariant* aData,
|
||||
nsIDOMUserDataHandler* aHandler,
|
||||
nsIVariant** aReturn)
|
||||
nsIVariant** aResult)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsNode3Tearoff::SetUserData()");
|
||||
nsIDocument *document = mContent->GetOwnerDoc();
|
||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
nsresult rv = document->SetUserData(mContent, aKey, aData, aHandler,
|
||||
aResult);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mContent->SetHasProperties();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNode3Tearoff::GetUserData(const nsAString& aKey,
|
||||
nsIVariant** aReturn)
|
||||
nsIVariant** aResult)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("nsNode3Tearoff::GetUserData()");
|
||||
nsIDocument *document = mContent->GetOwnerDoc();
|
||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return document->GetUserData(mContent, aKey, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -857,7 +866,17 @@ nsGenericElement::~nsGenericElement()
|
||||
{
|
||||
NS_PRECONDITION(!IsInDoc(),
|
||||
"Please remove this from the document properly");
|
||||
|
||||
|
||||
if (HasProperties()) {
|
||||
nsIDocument *document = GetOwnerDoc();
|
||||
if (document) {
|
||||
nsISupports *thisSupports = NS_STATIC_CAST(nsIContent*, this);
|
||||
document->CallUserDataHandler(nsIDOMUserDataHandler::NODE_DELETED,
|
||||
thisSupports, nsnull, nsnull);
|
||||
document->PropertyTable()->DeleteAllPropertiesFor(thisSupports);
|
||||
}
|
||||
}
|
||||
|
||||
// pop any enclosed ranges out
|
||||
// nsRange::OwnerGone(mContent); not used for now
|
||||
|
||||
@ -1878,9 +1897,14 @@ nsGenericElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
// XXXbz sXBL/XBL2 issue!
|
||||
nsIDocument *ownerDocument = GetOwnerDoc();
|
||||
if (aDocument != ownerDocument) {
|
||||
if (ownerDocument && HasProperties()) {
|
||||
nsISupports *thisSupports = NS_STATIC_CAST(nsIContent*, this);
|
||||
|
||||
if (HasProperties()) {
|
||||
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(this);
|
||||
// Copy UserData to the new document.
|
||||
ownerDocument->CopyUserData(thisSupports, aDocument);
|
||||
|
||||
// Remove all properties.
|
||||
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(thisSupports);
|
||||
}
|
||||
|
||||
// get a new nodeinfo
|
||||
@ -4399,7 +4423,9 @@ nsGenericElement::GetProperty(nsIAtom *aPropertyName, nsresult *aStatus) const
|
||||
if (!doc)
|
||||
return nsnull;
|
||||
|
||||
return doc->PropertyTable()->GetProperty(this, aPropertyName, aStatus);
|
||||
const nsISupports *thisSupports = NS_STATIC_CAST(const nsIContent*, this);
|
||||
return doc->PropertyTable()->GetProperty(thisSupports, aPropertyName,
|
||||
aStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -4411,7 +4437,8 @@ nsGenericElement::SetProperty(nsIAtom *aPropertyName,
|
||||
if (!doc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = doc->PropertyTable()->SetProperty(this, aPropertyName,
|
||||
nsISupports *thisSupports = NS_STATIC_CAST(nsIContent*, this);
|
||||
nsresult rv = doc->PropertyTable()->SetProperty(thisSupports, aPropertyName,
|
||||
aValue, aDtor, nsnull);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
SetFlags(GENERIC_ELEMENT_HAS_PROPERTIES);
|
||||
@ -4426,7 +4453,8 @@ nsGenericElement::DeleteProperty(nsIAtom *aPropertyName)
|
||||
if (!doc)
|
||||
return nsnull;
|
||||
|
||||
return doc->PropertyTable()->DeleteProperty(this, aPropertyName);
|
||||
nsISupports *thisSupports = NS_STATIC_CAST(nsIContent*, this);
|
||||
return doc->PropertyTable()->DeleteProperty(thisSupports, aPropertyName);
|
||||
}
|
||||
|
||||
void*
|
||||
@ -4436,11 +4464,20 @@ nsGenericElement::UnsetProperty(nsIAtom *aPropertyName, nsresult *aStatus)
|
||||
if (!doc)
|
||||
return nsnull;
|
||||
|
||||
return doc->PropertyTable()->UnsetProperty(this, aPropertyName, aStatus);
|
||||
nsISupports *thisSupports = NS_STATIC_CAST(nsIContent*, this);
|
||||
return doc->PropertyTable()->UnsetProperty(thisSupports, aPropertyName,
|
||||
aStatus);
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericElement::SetHasProperties()
|
||||
{
|
||||
SetFlags(GENERIC_ELEMENT_HAS_PROPERTIES);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult) const
|
||||
nsGenericElement::CloneNode(PRBool aDeep, nsIDOMNode *aSource,
|
||||
nsIDOMNode **aResult) const
|
||||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
@ -4449,7 +4486,16 @@ nsGenericElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult) const
|
||||
getter_AddRefs(newContent));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(newContent, aResult);
|
||||
rv = CallQueryInterface(newContent, aResult);
|
||||
|
||||
nsIDocument *ownerDoc = GetOwnerDoc();
|
||||
if (NS_SUCCEEDED(rv) && ownerDoc && HasProperties()) {
|
||||
ownerDoc->CallUserDataHandler(nsIDOMUserDataHandler::NODE_CLONED,
|
||||
NS_STATIC_CAST(const nsIContent*, this),
|
||||
aSource, *aResult);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
||||
@ -433,6 +433,7 @@ public:
|
||||
nsresult *aStatus = nsnull);
|
||||
virtual void SetMayHaveFrame(PRBool aMayHaveFrame);
|
||||
virtual PRBool MayHaveFrame() const;
|
||||
void SetHasProperties();
|
||||
|
||||
/**
|
||||
* This calls Clone to do the actual cloning so that we end up with the
|
||||
@ -856,9 +857,11 @@ protected:
|
||||
*
|
||||
* @param aDeep if true all descendants will be cloned too (attributes on the
|
||||
* element are always cloned)
|
||||
* @param aSource nsIDOMNode pointer to this node
|
||||
* @param aResult the clone
|
||||
*/
|
||||
nsresult CloneNode(PRBool aDeep, nsIDOMNode **aResult) const;
|
||||
nsresult CloneNode(PRBool aDeep, nsIDOMNode *aSource,
|
||||
nsIDOMNode **aResult) const;
|
||||
|
||||
/**
|
||||
* Used for either storing flags for this element or a pointer to
|
||||
@ -990,9 +993,11 @@ public:
|
||||
|
||||
|
||||
/**
|
||||
* Macros to implement CloneNode().
|
||||
* Macros to implement CloneNode(). _elementName is the class for which to
|
||||
* implement CloneNode, _implClass is the class to use to cast to
|
||||
* nsIDOMNode*.
|
||||
*/
|
||||
#define NS_IMPL_DOM_CLONENODE(_elementName) \
|
||||
#define NS_IMPL_DOM_CLONENODE_AMBIGUOUS(_elementName, _implClass) \
|
||||
nsresult \
|
||||
_elementName::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep, \
|
||||
nsIContent **aResult) const \
|
||||
@ -1015,9 +1020,14 @@ _elementName::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep, \
|
||||
NS_IMETHODIMP \
|
||||
_elementName::CloneNode(PRBool aDeep, nsIDOMNode **aResult) \
|
||||
{ \
|
||||
return nsGenericElement::CloneNode(aDeep, aResult); \
|
||||
return nsGenericElement::CloneNode(aDeep, \
|
||||
NS_STATIC_CAST(_implClass*, this), \
|
||||
aResult); \
|
||||
}
|
||||
|
||||
#define NS_IMPL_DOM_CLONENODE(_elementName) \
|
||||
NS_IMPL_DOM_CLONENODE_AMBIGUOUS(_elementName, _elementName)
|
||||
|
||||
#define NS_IMPL_DOM_CLONENODE_WITH_INIT(_elementName) \
|
||||
nsresult \
|
||||
_elementName::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep, \
|
||||
@ -1042,7 +1052,7 @@ _elementName::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep, \
|
||||
NS_IMETHODIMP \
|
||||
_elementName::CloneNode(PRBool aDeep, nsIDOMNode **aResult) \
|
||||
{ \
|
||||
return nsGenericElement::CloneNode(aDeep, aResult); \
|
||||
return nsGenericElement::CloneNode(aDeep, this, aResult); \
|
||||
}
|
||||
|
||||
#endif /* nsGenericElement_h___ */
|
||||
|
||||
@ -50,6 +50,9 @@
|
||||
#include "nsContentErrors.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
#define CATEGORY_BIT 0x00000001U
|
||||
#define CATEGORY_MASK ~CATEGORY_BIT
|
||||
|
||||
struct PropertyListMapEntry : public PLDHashEntryHdr {
|
||||
const void *key;
|
||||
void *value;
|
||||
@ -57,14 +60,10 @@ struct PropertyListMapEntry : public PLDHashEntryHdr {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
struct nsPropertyTable::PropertyList {
|
||||
nsCOMPtr<nsIAtom> mName; // property name
|
||||
PLDHashTable mObjectValueMap; // map of object/value pairs
|
||||
NSPropertyDtorFunc mDtorFunc; // property specific value dtor function
|
||||
void* mDtorData;
|
||||
PropertyList* mNext;
|
||||
|
||||
PropertyList(nsIAtom* aName,
|
||||
class nsPropertyTable::PropertyList {
|
||||
public:
|
||||
PropertyList(PRUint32 aCategory,
|
||||
nsIAtom* aName,
|
||||
NSPropertyDtorFunc aDtorFunc,
|
||||
void* aDtorData) NS_HIDDEN;
|
||||
~PropertyList() NS_HIDDEN;
|
||||
@ -75,6 +74,37 @@ struct nsPropertyTable::PropertyList {
|
||||
|
||||
// Destroy all remaining properties (without removing them)
|
||||
NS_HIDDEN_(void) Destroy();
|
||||
|
||||
NS_HIDDEN_(PRBool) Equals(PRUint32 aCategory, nsIAtom *aPropertyName)
|
||||
{
|
||||
PRUint32 category = mBits & CATEGORY_BIT ? mBits & CATEGORY_MASK : 0;
|
||||
|
||||
return mName == aPropertyName && category == aCategory;
|
||||
}
|
||||
NS_HIDDEN_(PRBool) IsInCategory(PRUint32 aCategory)
|
||||
{
|
||||
PRUint32 category = mBits & CATEGORY_BIT ? mBits & CATEGORY_MASK : 0;
|
||||
|
||||
return category == aCategory;
|
||||
}
|
||||
NS_HIDDEN_(void*) GetDtorData()
|
||||
{
|
||||
return mBits & CATEGORY_BIT ? nsnull : NS_REINTERPRET_CAST(void*, mBits);
|
||||
}
|
||||
NS_HIDDEN_(void) SetDtorData(void *aDtorData)
|
||||
{
|
||||
NS_ASSERTION(!(mBits & CATEGORY_BIT),
|
||||
"Can't set both DtorData and category!");
|
||||
mBits = NS_REINTERPRET_CAST(PtrBits, aDtorData);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> mName; // property name
|
||||
PLDHashTable mObjectValueMap; // map of object/value pairs
|
||||
NSPropertyDtorFunc mDtorFunc; // property specific value dtor function
|
||||
PropertyList* mNext;
|
||||
|
||||
private:
|
||||
PtrBits mBits; // pointer to pass to dtor or category
|
||||
};
|
||||
|
||||
nsPropertyTable::~nsPropertyTable()
|
||||
@ -98,8 +128,27 @@ nsPropertyTable::DeleteAllPropertiesFor(const void *aObject)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPropertyTable::Enumerate(const void *aObject, PRUint32 aCategory,
|
||||
NSPropertyFunc aCallback, void *aData)
|
||||
{
|
||||
PropertyList* prop;
|
||||
for (prop = mPropertyList; prop; prop = prop->mNext) {
|
||||
if (prop->IsInCategory(aCategory)) {
|
||||
PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*,
|
||||
PL_DHashTableOperate(&prop->mObjectValueMap, aObject,
|
||||
PL_DHASH_LOOKUP));
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
aCallback(NS_CONST_CAST(void*, aObject), prop->mName, entry->value,
|
||||
aData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
nsPropertyTable::GetPropertyInternal(const void *aObject,
|
||||
PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName,
|
||||
PRBool aRemove,
|
||||
nsresult *aResult)
|
||||
@ -108,7 +157,7 @@ nsPropertyTable::GetPropertyInternal(const void *aObject,
|
||||
nsresult rv = NS_PROPTABLE_PROP_NOT_THERE;
|
||||
void *propValue = nsnull;
|
||||
|
||||
PropertyList* propertyList = GetPropertyListFor(aPropertyName);
|
||||
PropertyList* propertyList = GetPropertyListFor(aCategory, aPropertyName);
|
||||
if (propertyList) {
|
||||
PropertyListMapEntry *entry = NS_STATIC_CAST(PropertyListMapEntry*,
|
||||
PL_DHashTableOperate(&propertyList->mObjectValueMap, aObject,
|
||||
@ -130,29 +179,29 @@ nsPropertyTable::GetPropertyInternal(const void *aObject,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPropertyTable::SetProperty(const void *aObject,
|
||||
nsIAtom *aPropertyName,
|
||||
void *aPropertyValue,
|
||||
NSPropertyDtorFunc aPropDtorFunc,
|
||||
void *aPropDtorData)
|
||||
nsPropertyTable::SetPropertyInternal(const void *aObject,
|
||||
PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName,
|
||||
void *aPropertyValue,
|
||||
NSPropertyDtorFunc aPropDtorFunc,
|
||||
void *aPropDtorData,
|
||||
void **aOldValue)
|
||||
{
|
||||
NS_PRECONDITION(aPropertyName && aObject, "unexpected null param");
|
||||
|
||||
PropertyList* propertyList = GetPropertyListFor(aPropertyName);
|
||||
PropertyList* propertyList = GetPropertyListFor(aCategory, aPropertyName);
|
||||
|
||||
if (propertyList) {
|
||||
// Make sure the dtor function and data match
|
||||
if (aPropDtorFunc != propertyList->mDtorFunc ||
|
||||
aPropDtorData != propertyList->mDtorData) {
|
||||
aPropDtorData != propertyList->GetDtorData()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
} else {
|
||||
propertyList = new PropertyList(aPropertyName, aPropDtorFunc,
|
||||
propertyList = new PropertyList(aCategory, aPropertyName, aPropDtorFunc,
|
||||
aPropDtorData);
|
||||
if (!propertyList)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
if (!propertyList->mObjectValueMap.ops) {
|
||||
if (!propertyList || !propertyList->mObjectValueMap.ops) {
|
||||
delete propertyList;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -170,11 +219,17 @@ nsPropertyTable::SetProperty(const void *aObject,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
// A NULL entry->key is the sign that the entry has just been allocated
|
||||
// for us. If it's non-NULL then we have an existing entry.
|
||||
if (entry->key && propertyList->mDtorFunc) {
|
||||
propertyList->mDtorFunc(NS_CONST_CAST(void*, entry->key), aPropertyName,
|
||||
entry->value, propertyList->mDtorData);
|
||||
if (entry->key) {
|
||||
if (aOldValue)
|
||||
*aOldValue = entry->value;
|
||||
else if (propertyList->mDtorFunc)
|
||||
propertyList->mDtorFunc(NS_CONST_CAST(void*, entry->key), aPropertyName,
|
||||
entry->value, propertyList->GetDtorData());
|
||||
result = NS_PROPTABLE_PROP_OVERWRITTEN;
|
||||
}
|
||||
else if (aOldValue) {
|
||||
*aOldValue = nsnull;
|
||||
}
|
||||
entry->key = aObject;
|
||||
entry->value = aPropertyValue;
|
||||
|
||||
@ -183,11 +238,12 @@ nsPropertyTable::SetProperty(const void *aObject,
|
||||
|
||||
nsresult
|
||||
nsPropertyTable::DeleteProperty(const void *aObject,
|
||||
PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName)
|
||||
{
|
||||
NS_PRECONDITION(aPropertyName && aObject, "unexpected null param");
|
||||
|
||||
PropertyList* propertyList = GetPropertyListFor(aPropertyName);
|
||||
PropertyList* propertyList = GetPropertyListFor(aCategory, aPropertyName);
|
||||
if (propertyList) {
|
||||
if (propertyList->DeletePropertyFor(aObject))
|
||||
return NS_OK;
|
||||
@ -197,12 +253,13 @@ nsPropertyTable::DeleteProperty(const void *aObject,
|
||||
}
|
||||
|
||||
nsPropertyTable::PropertyList*
|
||||
nsPropertyTable::GetPropertyListFor(nsIAtom* aPropertyName) const
|
||||
nsPropertyTable::GetPropertyListFor(PRUint32 aCategory,
|
||||
nsIAtom* aPropertyName) const
|
||||
{
|
||||
PropertyList* result;
|
||||
|
||||
for (result = mPropertyList; result; result = result->mNext) {
|
||||
if (result->mName.get() == aPropertyName) {
|
||||
if (result->Equals(aCategory, aPropertyName)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -212,11 +269,20 @@ nsPropertyTable::GetPropertyListFor(nsIAtom* aPropertyName) const
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsPropertyTable::PropertyList::PropertyList(nsIAtom *aName,
|
||||
nsPropertyTable::PropertyList::PropertyList(PRUint32 aCategory,
|
||||
nsIAtom *aName,
|
||||
NSPropertyDtorFunc aDtorFunc,
|
||||
void *aDtorData)
|
||||
: mName(aName), mDtorFunc(aDtorFunc), mDtorData(aDtorData), mNext(nsnull)
|
||||
: mName(aName),
|
||||
mDtorFunc(aDtorFunc),
|
||||
mNext(nsnull),
|
||||
mBits(aCategory == 0 ? NS_REINTERPRET_CAST(PtrBits, aDtorData) :
|
||||
aCategory | CATEGORY_BIT)
|
||||
{
|
||||
NS_ASSERTION(!(aCategory & CATEGORY_BIT), "Don't set the reserved bit!");
|
||||
NS_ASSERTION(aCategory == 0 || !aDtorData,
|
||||
"Can't set both DtorData and category!");
|
||||
|
||||
PL_DHashTableInit(&mObjectValueMap, PL_DHashGetStubOps(), this,
|
||||
sizeof(PropertyListMapEntry), 16);
|
||||
}
|
||||
@ -236,14 +302,14 @@ DestroyPropertyEnumerator(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
||||
PropertyListMapEntry* entry = NS_STATIC_CAST(PropertyListMapEntry*, hdr);
|
||||
|
||||
propList->mDtorFunc(NS_CONST_CAST(void*, entry->key), propList->mName,
|
||||
entry->value, propList->mDtorData);
|
||||
entry->value, propList->GetDtorData());
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsPropertyTable::PropertyList::Destroy()
|
||||
{
|
||||
// Enumerate any remaining frame/value pairs and destroy the value object
|
||||
// Enumerate any remaining object/value pairs and destroy the value object
|
||||
if (mDtorFunc)
|
||||
PL_DHashTableEnumerate(&mObjectValueMap, DestroyPropertyEnumerator,
|
||||
nsnull);
|
||||
@ -259,7 +325,7 @@ nsPropertyTable::PropertyList::DeletePropertyFor(const void* aObject)
|
||||
|
||||
if (mDtorFunc)
|
||||
mDtorFunc(NS_CONST_CAST(void*, aObject), mName,
|
||||
entry->value, mDtorData);
|
||||
entry->value, GetDtorData());
|
||||
|
||||
PL_DHashTableRawRemove(&mObjectValueMap, entry);
|
||||
|
||||
|
||||
@ -58,6 +58,13 @@
|
||||
#include "nscore.h"
|
||||
|
||||
class nsIAtom;
|
||||
typedef unsigned long PtrBits;
|
||||
|
||||
typedef void
|
||||
(*NSPropertyFunc)(void *aObject,
|
||||
nsIAtom *aPropertyName,
|
||||
void *aPropertyValue,
|
||||
void *aData);
|
||||
|
||||
/**
|
||||
* Callback type for property destructors. |aObject| is the object
|
||||
@ -65,11 +72,13 @@ class nsIAtom;
|
||||
* being removed, |aPropertyValue| is the value of the property, and |aData|
|
||||
* is the opaque destructor data that was passed to SetProperty().
|
||||
**/
|
||||
typedef void
|
||||
(*NSPropertyDtorFunc)(void *aObject,
|
||||
nsIAtom *aPropertyName,
|
||||
void *aPropertyValue,
|
||||
void *aData);
|
||||
typedef NSPropertyFunc NSPropertyDtorFunc;
|
||||
|
||||
// Categories of properties
|
||||
// 0x00000000U is global.
|
||||
// 0x00000001U is reserved.
|
||||
#define DOM_USER_DATA 0x00000002U
|
||||
#define DOM_USER_DATA_HANDLER 0x00000004U
|
||||
|
||||
class nsPropertyTable
|
||||
{
|
||||
@ -81,57 +90,142 @@ class nsPropertyTable
|
||||
void* GetProperty(const void *aObject,
|
||||
nsIAtom *aPropertyName,
|
||||
nsresult *aResult = nsnull)
|
||||
{ return GetPropertyInternal(aObject, aPropertyName, PR_FALSE, aResult); }
|
||||
{
|
||||
return GetPropertyInternal(aObject, 0, aPropertyName, PR_FALSE, aResult);
|
||||
}
|
||||
|
||||
void* GetProperty(const void *aObject,
|
||||
PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName,
|
||||
nsresult *aResult = nsnull)
|
||||
{
|
||||
return GetPropertyInternal(aObject, aCategory, aPropertyName, PR_FALSE,
|
||||
aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the property |aPropertyName| to |aPropertyValue|
|
||||
* for node |aObject|. |aDtor| is a destructor for the property value
|
||||
* to be called if the property is removed. It can be null if no
|
||||
* destructor is required. |aDtorData| is an optional opaque context to
|
||||
* be passed to the property destructor. Note that the destructor is
|
||||
* global for each property name regardless of node; it is an error
|
||||
* to set a given property with a different destructor than was used before
|
||||
* (this will return NS_ERROR_INVALID_ARG).
|
||||
**/
|
||||
* Set the value of the property |aPropertyName| in the global category to
|
||||
* |aPropertyValue| for node |aObject|. |aDtor| is a destructor for the
|
||||
* property value to be called if the property is removed. It can be null
|
||||
* if no destructor is required. |aDtorData| is an optional pointer to an
|
||||
* opaque context to be passed to the property destructor. Note that the
|
||||
* destructor is global for each property name regardless of node; it is an
|
||||
* error to set a given property with a different destructor than was used
|
||||
* before (this will return NS_ERROR_INVALID_ARG). If aOldValue is non-null
|
||||
* it will contain the old value after the function returns (the destructor
|
||||
* for the old value will not be run in that case).
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) SetProperty(const void *aObject,
|
||||
nsIAtom *aPropertyName,
|
||||
void *aPropertyValue,
|
||||
NSPropertyDtorFunc aDtor,
|
||||
void *aDtorData);
|
||||
void *aDtorData,
|
||||
void **aOldValue = nsnull)
|
||||
{
|
||||
return SetPropertyInternal(aObject, 0, aPropertyName, aPropertyValue,
|
||||
aDtor, aDtorData, aOldValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the property |aPropertyName| for object |aObject|.
|
||||
* The property's destructor function will be called.
|
||||
**/
|
||||
* Set the value of the property |aPropertyName| in the category |aCategory|
|
||||
* to |aPropertyValue| for node |aObject|. |aDtor| is a destructor for the
|
||||
* property value to be called if the property is removed. It can be null
|
||||
* if no destructor is required. Note that the destructor is global for
|
||||
* each property name regardless of node; it is an error to set a given
|
||||
* property with a different destructor than was used before (this will
|
||||
* return NS_ERROR_INVALID_ARG). If aOldValue is non-null it will contain the
|
||||
* old value after the function returns (the destructor for the old value
|
||||
* will not be run in that case).
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) SetProperty(const void *aObject,
|
||||
PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName,
|
||||
void *aPropertyValue,
|
||||
NSPropertyDtorFunc aDtor,
|
||||
void **aOldValue = nsnull)
|
||||
{
|
||||
return SetPropertyInternal(aObject, aCategory, aPropertyName,
|
||||
aPropertyValue, aDtor, nsnull, aOldValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the property |aPropertyName| in the global category for object
|
||||
* |aObject|. The property's destructor function will be called.
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) DeleteProperty(const void *aObject,
|
||||
nsIAtom *aPropertyName)
|
||||
{
|
||||
return DeleteProperty(aObject, 0, aPropertyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the property |aPropertyName| in category |aCategory| for object
|
||||
* |aObject|. The property's destructor function will be called.
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) DeleteProperty(const void *aObject,
|
||||
PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName);
|
||||
|
||||
/**
|
||||
* Unset the property |aPropertyName| for object |aObject|, but do not
|
||||
* call the property's destructor function. The property value is returned.
|
||||
**/
|
||||
* Unset the property |aPropertyName| in the global category for object
|
||||
* |aObject|, but do not call the property's destructor function. The
|
||||
* property value is returned.
|
||||
*/
|
||||
void* UnsetProperty(const void *aObject,
|
||||
nsIAtom *aPropertyName,
|
||||
nsresult *aStatus = nsnull)
|
||||
{ return GetPropertyInternal(aObject, aPropertyName, PR_TRUE, aStatus); }
|
||||
{
|
||||
return GetPropertyInternal(aObject, 0, aPropertyName, PR_TRUE, aStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the property |aPropertyName| in category |aCategory| for object
|
||||
* |aObject|, but do not call the property's destructor function. The
|
||||
* property value is returned.
|
||||
*/
|
||||
void* UnsetProperty(const void *aObject,
|
||||
PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName,
|
||||
nsresult *aStatus = nsnull)
|
||||
{
|
||||
return GetPropertyInternal(aObject, aCategory, aPropertyName, PR_TRUE,
|
||||
aStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all of the properties for object |aObject|, calling the
|
||||
* destructor function for each property.
|
||||
**/
|
||||
*/
|
||||
NS_HIDDEN_(void) DeleteAllPropertiesFor(const void *aObject);
|
||||
|
||||
/**
|
||||
* Enumerate the properties in category |aCategory| for object |aObject|.
|
||||
* For every property |aCallback| will be called with as arguments |aObject|,
|
||||
* the property name, the property value and |aData|.
|
||||
*/
|
||||
NS_HIDDEN_(void) Enumerate(const void *aObject, PRUint32 aCategory,
|
||||
NSPropertyFunc aCallback, void *aData);
|
||||
|
||||
~nsPropertyTable() NS_HIDDEN;
|
||||
|
||||
struct PropertyList;
|
||||
|
||||
private:
|
||||
NS_HIDDEN_(void) DestroyPropertyList();
|
||||
NS_HIDDEN_(PropertyList*) GetPropertyListFor(nsIAtom *aPropertyName) const;
|
||||
NS_HIDDEN_(PropertyList*) GetPropertyListFor(PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName) const;
|
||||
NS_HIDDEN_(void*) GetPropertyInternal(const void *aObject,
|
||||
PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName,
|
||||
PRBool aRemove,
|
||||
nsresult *aStatus);
|
||||
NS_HIDDEN_(nsresult) SetPropertyInternal(const void *aObject,
|
||||
PRUint32 aCategory,
|
||||
nsIAtom *aPropertyName,
|
||||
void *aPropertyValue,
|
||||
NSPropertyDtorFunc aDtor,
|
||||
void *aDtorData,
|
||||
void **aOldValue);
|
||||
|
||||
PropertyList *mPropertyList;
|
||||
};
|
||||
|
||||
@ -435,7 +435,7 @@ nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||
NS_IMETHODIMP
|
||||
nsHTMLInputElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
||||
{
|
||||
return nsGenericElement::CloneNode(aDeep, aResult);
|
||||
return nsGenericElement::CloneNode(aDeep, this, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -114,7 +114,8 @@ NS_HTML_CONTENT_INTERFACE_MAP_AMBIGOUS_BEGIN(nsHTMLSharedListElement,
|
||||
NS_HTML_CONTENT_INTERFACE_MAP_END
|
||||
|
||||
|
||||
NS_IMPL_DOM_CLONENODE(nsHTMLSharedListElement)
|
||||
NS_IMPL_DOM_CLONENODE_AMBIGUOUS(nsHTMLSharedListElement,
|
||||
nsIDOMHTMLOListElement)
|
||||
|
||||
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLSharedListElement, Compact, compact)
|
||||
|
||||
@ -513,7 +513,7 @@ nsHTMLScriptElement::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||
NS_IMETHODIMP
|
||||
nsHTMLScriptElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
||||
{
|
||||
return nsGenericElement::CloneNode(aDeep, aResult);
|
||||
return nsGenericElement::CloneNode(aDeep, this, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
@ -212,7 +212,7 @@ NS_HTML_CONTENT_INTERFACE_MAP_AMBIGOUS_BEGIN(nsHTMLSharedElement,
|
||||
NS_HTML_CONTENT_INTERFACE_MAP_END
|
||||
|
||||
|
||||
NS_IMPL_DOM_CLONENODE(nsHTMLSharedElement)
|
||||
NS_IMPL_DOM_CLONENODE_AMBIGUOUS(nsHTMLSharedElement, nsIDOMHTMLEmbedElement)
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
||||
@ -329,7 +329,7 @@ nsSVGUseElement::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||
NS_IMETHODIMP
|
||||
nsSVGUseElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
||||
{
|
||||
return nsGenericElement::CloneNode(aDeep, aResult);
|
||||
return nsGenericElement::CloneNode(aDeep, this, aResult);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
@ -89,6 +89,7 @@
|
||||
#include "nsIScriptGlobalObjectOwner.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
|
||||
// XXX The XML world depends on the html atoms
|
||||
#include "nsHTMLAtoms.h"
|
||||
@ -725,7 +726,13 @@ nsXMLDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
||||
}
|
||||
}
|
||||
|
||||
return CallQueryInterface(newDoc, aReturn);
|
||||
rv = CallQueryInterface(newDoc, aReturn);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CallUserDataHandler(nsIDOMUserDataHandler::NODE_CLONED,
|
||||
NS_STATIC_CAST(nsIDocument*, this), this, *aReturn);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// nsIDOMDocument interface
|
||||
|
||||
@ -514,7 +514,7 @@ nsXULElement::Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::CloneNode(PRBool aDeep, nsIDOMNode **aResult)
|
||||
{
|
||||
return nsGenericElement::CloneNode(aDeep, aResult);
|
||||
return nsGenericElement::CloneNode(aDeep, this, aResult);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -860,9 +860,14 @@ nsXULElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
// XXXbz sXBL/XBL2 issue!
|
||||
nsIDocument *ownerDocument = GetOwnerDoc();
|
||||
if (aDocument != ownerDocument) {
|
||||
if (ownerDocument && HasProperties()) {
|
||||
nsISupports *thisSupports = NS_STATIC_CAST(nsIContent*, this);
|
||||
|
||||
if (HasProperties()) {
|
||||
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(this);
|
||||
// Copy UserData to the new document.
|
||||
ownerDocument->CopyUserData(thisSupports, aDocument);
|
||||
|
||||
// Remove all properties.
|
||||
ownerDocument->PropertyTable()->DeleteAllPropertiesFor(thisSupports);
|
||||
}
|
||||
|
||||
// get a new nodeinfo
|
||||
@ -1080,7 +1085,7 @@ nsXULElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
||||
// and cells going away.
|
||||
// First, retrieve the tree.
|
||||
// Check first whether this element IS the tree
|
||||
controlElement = do_QueryInterface((nsIDOMXULElement*)this);
|
||||
controlElement = do_QueryInterface(NS_STATIC_CAST(nsIContent*, this));
|
||||
|
||||
// If it's not, look at our parent
|
||||
if (!controlElement)
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
// Introduced in DOM Level 3:
|
||||
|
||||
[scriptable, function, uuid(5470deff-03c9-41b7-a824-e3225266b343)]
|
||||
interface nsIDOMUserDataHandler
|
||||
interface nsIDOMUserDataHandler : nsISupports
|
||||
{
|
||||
// OperationType
|
||||
const unsigned short NODE_CLONED = 1;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user