Exemple #1
0
DOMString AttrImpl::getValue()
{
    if (value.child == null) {
        return 0; // return "";
    }
    if (hasStringValue()) {
        // change value into a DOMString*
        DOMString *x = (value.str == null
            ?(value.str = new (getOwnerDocument()->getMemoryManager()) DOMString())
            :value.str
        );
        // return the DOMString it points to
        return *x;
    }
    ChildNode *firstChild = value.child;
    ChildNode *node = firstChild->nextSibling;
    if (node == null) {
        return firstChild->getNodeValue().clone();
    }
    int             length = 0;
    for (node = firstChild; node != null; node = node->nextSibling)
        length += node->getNodeValue().length();

    DOMString retString;
    retString.reserve(length);
    for (node = firstChild; node != null; node = node->nextSibling)
    {
        retString.appendData(node->getNodeValue());
    };

    return retString;
};
Exemple #2
0
	ChildNode * Composite::GetPrevChild(ChildNode const * pNode, ID idMatch)
	{
		for (ChildNode * pSrchNode = GetPrevChild(pNode); pSrchNode; pSrchNode = GetPrevChild(pSrchNode))
		{
			if (pSrchNode->GetChunk()->m_idCk == idMatch && !pSrchNode->GetChunk()->IsUnknown()) return pSrchNode;
		}
		return NULL;
	}
Exemple #3
0
	ChildNode * Composite::GetLastChild(ID idMatch) const
	{
		for (ChildNode * pSrchNode = m_pLast; pSrchNode; pSrchNode = GetPrevChild(pSrchNode))
		{
			if (pSrchNode->GetChunk()->m_idCk == idMatch && !pSrchNode->GetChunk()->IsUnknown()) return pSrchNode;
		}
		return NULL;
	}
Exemple #4
0
void
Attr::setOwnerDocument(Document * doc)
{
  Node::setOwnerDocument(doc);
  for (ChildNode * child = text;
       child != null; child = child->nextSibling) {
    child->setOwnerDocument(doc);
  }
  setId();
}
Exemple #5
0
	bool List::EnumChildren(ID idData, ID idChunk, bool (* pfnCallback) (Chunk *, void *), void * pData) const
	{
		for (ChildNode * pNode = GetFirstChild(); pNode; pNode = GetNextChild(pNode))
		{
			Composite const * pComposite = static_cast<Composite const *>(pNode->GetChunk());
			if (pComposite->m_idData == idData && !pComposite->EnumChildren(idData,idChunk,pfnCallback,pData)) return false;
		}
		
		return true;
	}
Exemple #6
0
	bool Composite::EnumChildren(ID idData, ID idChunk, bool (* pfnCallback) (Chunk *, void *), void * pData) const
	{
		if (m_idData != idData) return true;
		
		for (ChildNode * pNode = GetFirstChild(idChunk); pNode; pNode = GetNextChild(pNode,idChunk))
		{
			if (!pfnCallback(pNode->GetChunk(),pData)) return false;
		}
		
		return true;
	}
Exemple #7
0
void ParentNode::setReadOnly(bool readOnl, bool deep)
{
    NodeImpl::setReadOnly(readOnl, deep);

    if (deep)
        // Recursively set kids
        for (ChildNode *mykid = firstChild;
             mykid != null;
             mykid = mykid->nextSibling)
            if(! (mykid->isEntityReference()))
                mykid->setReadOnly(readOnl,true);
};
Exemple #8
0
void ParentNode::setReadOnly(bool readOnl, bool deep)
{
    NodeImpl::setReadOnly(readOnl, deep);

    if (deep)
        // Recursively set kids
        for (ChildNode *mykid = firstChild;
             mykid != null;
             mykid = mykid->nextSibling)
            if(! (mykid->isEntityReference()))
                mykid->setReadOnly(readOnl,true);
}   /* SPEC_CPU: removed extra ';' for C++98 standards compliance -- yag */
Exemple #9
0
void AttrImpl::setReadOnly(bool readOnl, bool deep) {
    NodeImpl::setReadOnly(readOnl, deep);

    if (deep) {
        if (hasStringValue()) {
            return;
        }
        // Recursively set kids
        for (ChildNode *mykid = value.child;
             mykid != null;
             mykid = mykid->nextSibling)
            if(! (mykid->isEntityReference()))
                mykid->setReadOnly(readOnl,true);
    }
}
Exemple #10
0
	Chunk * Composite::GetProperty(ChildNode const * pNode, ID idProp) const
	{
		// search backward for ID
		
		ChildNode * pFindNode = GetPrevChild(pNode, idProp);
		
		if (pFindNode) return pFindNode->GetChunk();
		
		// if not found, search parent backwards, for "PROP ...." then get that
		// and if not in the parent, search its parent similarly
		// provided all these parents are of type LIST ....
		
		for (Composite const * pThis = this; pThis->m_pParent && pThis->m_pParent->m_idCk == ID("LIST"); pThis = pThis->m_pParent)
		{
			if (pThis->m_pNode)
			{
				for (ChildNode * pFindProp = pThis->m_pParent->GetPrevChild(pThis->m_pNode,"PROP"); pFindProp; pFindProp = pThis->m_pParent->GetPrevChild(pFindProp,"PROP"))
				{
					Composite * pProp = static_cast<Composite *>(pFindProp->GetChunk());
					if (pProp->m_idData == m_idData)
					{
						ChildNode * pFindNode = pProp->GetLastChild(idProp);
						
						if (pFindNode) return pFindNode->GetChunk();
					}
				}
				
			}
		}
		
		return NULL;
	}
Exemple #11
0
Node *
Attr::internalRemoveChild(Node * oldChild)
  throw(DOMException)
{
  Document * owner = getOwnerDocument();
  if (isReadOnly())
    throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR);
  if (oldChild != null && oldChild->getParentNode() != this)
    throw DOMException(DOMException::NOT_FOUND_ERR);
  owner->removedChildNode(oldChild);

  ChildNode * oldInternal = dynamic_cast<ChildNode*>(oldChild);
  if (oldInternal == text) {
    text->isFirstChild(false);
    text = dynamic_cast<Text*>(text->nextSibling);
    if (text != null) {
      text->isFirstChild(true);
      text->previousSibling = oldInternal->previousSibling;
    }
  }
  else {
    ChildNode * prev = oldInternal->previousSibling;
    ChildNode * next = oldInternal->nextSibling;
    prev->nextSibling = next;
    if (next != null) {
      text->previousSibling = prev;
    }
    else {
      next->previousSibling = prev;
    }
  }
  //ChildNode * oldPreviousSibling = oldInternal->previousSibling;
  oldInternal->ownerNode = owner;
  oldInternal->isOwned(false);
  oldInternal->nextSibling = null;
  oldInternal->previousSibling = null;
  changed();
  return oldInternal;
}
Exemple #12
0
	void Composite::Serialize(Archive * pArchv)
	{
		pArchv->Transfer(m_idData);
		
		if (pArchv->m_bIsLoading)
		{
			DeleteAllChildren();
			
			while (pArchv->GetSize())
			{
				Chunk * pChunk = LoadChunk(pArchv);
				InsertChildLast(pChunk);
				pChunk->Release();
			}
		}
		else
		{
			for (ChildNode * pNode = m_pFirst; pNode; pNode = GetNextChild(pNode))
			{
				pNode->GetChunk()->Write(pArchv);
			}
		}
	}
Exemple #13
0
NodeImpl *ParentNode::removeChild(NodeImpl *oldChild)
{
    if (ownerDocument->getErrorChecking()) {
        if (isReadOnly()) {
            throw DOM_DOMException(
                                 DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR,
                                 null);
        }
        if (oldChild == null || oldChild->getParentNode() != this) {
            throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);
        }
    }
    //fix other ranges for change before deleting the node
    if (getOwnerDocument() !=  null) {
        typedef RefVectorOf<RangeImpl> RangeImpls;
        RangeImpls* ranges = this->getOwnerDocument()->getRanges();
        if (ranges != null) {
            unsigned int sz = ranges->size();
            if (sz != 0) {
                for (unsigned int i =0; i<sz; i++) {
                    if (ranges->elementAt(i) != null)
                        ranges->elementAt(i)->updateRangeForDeletedNode(oldChild);
                }
            }
        }
    }

    ChildNode * oldInternal = (ChildNode *) oldChild;

    // update cached length if we have any
    if (fCachedLength != -1) {
        fCachedLength--;
    }
    if (fCachedChildIndex != -1) {
        // if the removed node is the cached node
        // move the cache to its (soon former) previous sibling
        if (fCachedChild == oldInternal) {
            fCachedChildIndex--;
            fCachedChild = (ChildNode *)oldInternal->getPreviousSibling();
        } else {
            // otherwise just invalidate the cache
            fCachedChildIndex = -1;
        }
    }

    // Patch linked list around oldChild
    // Note: lastChild == firstChild->previousSibling
    if (oldInternal == firstChild) {
        // removing first child
        oldInternal->isFirstChild(false);
        firstChild = oldInternal->nextSibling;
        if (firstChild != null) {
            firstChild->isFirstChild(true);
            firstChild->previousSibling = oldInternal->previousSibling;
        }
    } else {
        ChildNode *prev = oldInternal->previousSibling;
        ChildNode *next = oldInternal->nextSibling;
        prev->nextSibling = next;
        if (next == null) {
            // removing last child
            firstChild->previousSibling = prev;
        } else {
            // removing some other child in the middle
            next->previousSibling = prev;
        }
    }

    // Remove oldInternal's references to tree
    oldInternal->ownerNode = ownerDocument;
    oldInternal->isOwned(false);
    oldInternal->nextSibling = null;
    oldInternal->previousSibling = null;

    changed();

    return oldInternal;
};
Exemple #14
0
NodeImpl *ParentNode::insertBefore(NodeImpl *newChild, NodeImpl *refChild) {

    bool errorChecking = ownerDocument->getErrorChecking();

    if (newChild->isDocumentFragmentImpl()) {
        // SLOW BUT SAFE: We could insert the whole subtree without
        // juggling so many next/previous pointers. (Wipe out the
        // parent's child-list, patch the parent pointers, set the
        // ends of the list.) But we know some subclasses have special-
        // case behavior they add to insertBefore(), so we don't risk it.
        // This approch also takes fewer bytecodes.

        // NOTE: If one of the children is not a legal child of this
        // node, throw HIERARCHY_REQUEST_ERR before _any_ of the children
        // have been transferred. (Alternative behaviors would be to
        // reparent up to the first failure point or reparent all those
        // which are acceptable to the target node, neither of which is
        // as robust. PR-DOM-0818 isn't entirely clear on which it
        // recommends?????

        // No need to check kids for right-document; if they weren't,
        // they wouldn't be kids of that DocFrag.
        if (errorChecking) {
            for (NodeImpl *kid = newChild->getFirstChild(); // Prescan
                 kid != null; kid = kid->getNextSibling()) {

                if (!DocumentImpl::isKidOK(this, kid)) {
                    throw DOM_DOMException(
                                       DOM_DOMException::HIERARCHY_REQUEST_ERR,
                                       null);
                }
            }
        }

        while (newChild->hasChildNodes()) {    // Move
            insertBefore(newChild->getFirstChild(),refChild);
        }
        return newChild;
    }

    // it's a no-op if refChild is the same as newChild
    if (refChild == newChild) {
        return newChild;
    }

    if (errorChecking) {
        if (isReadOnly()) {
            throw DOM_DOMException(
                                 DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR,
                                 null);
        }
        if (newChild->getOwnerDocument() != ownerDocument) {
            throw DOM_DOMException(DOM_DOMException::WRONG_DOCUMENT_ERR, null);
        }
        if (!DocumentImpl::isKidOK(this, newChild)) {
            throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,
                                   null);
        }
        // refChild must be a child of this node (or null)
        if (refChild != null && refChild->getParentNode() != this) {
            throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);
        }

        // Prevent cycles in the tree
        // newChild cannot be ancestor of this Node,
        // and actually cannot be this
        bool treeSafe = true;
        for (NodeImpl *a = this; treeSafe && a != null; a = a->getParentNode())
        {
            treeSafe = (newChild != a);
        }
        if (!treeSafe) {
            throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,
                                   null);
        }
    }

    // Convert to internal type, to avoid repeated casting
    ChildNode * newInternal = (ChildNode *)newChild;

    NodeImpl *oldparent = newInternal->getParentNode();
    if (oldparent != null) {
        oldparent->removeChild(newInternal);
    }

    // Convert to internal type, to avoid repeated casting
    ChildNode *refInternal = (ChildNode *)refChild;

    // Attach up
    newInternal->ownerNode = this;
    newInternal->isOwned(true);

    // Attach before and after
    // Note: firstChild.previousSibling == lastChild!!
    if (firstChild == null) {
        // this our first and only child
        firstChild = newInternal;
        newInternal->isFirstChild(true);
        newInternal->previousSibling = newInternal;
    }
    else {
        if (refInternal == null) {
            // this is an append
            ChildNode *lastChild = firstChild->previousSibling;
            lastChild->nextSibling = newInternal;
            newInternal->previousSibling = lastChild;
            firstChild->previousSibling = newInternal;
        }
        else {
            // this is an insert
            if (refChild == firstChild) {
                // at the head of the list
                firstChild->isFirstChild(false);
                newInternal->nextSibling = firstChild;
                newInternal->previousSibling = firstChild->previousSibling;
                firstChild->previousSibling = newInternal;
                firstChild = newInternal;
                newInternal->isFirstChild(true);
            }
            else {
                // somewhere in the middle
                ChildNode *prev = refInternal->previousSibling;
                newInternal->nextSibling = refInternal;
                prev->nextSibling = newInternal;
                refInternal->previousSibling = newInternal;
                newInternal->previousSibling = prev;
            }
        }
    }

    changed();

    // update cached length if we have any
    if (fCachedLength != -1) {
        fCachedLength++;
    }
    if (fCachedChildIndex != -1) {
        // if we happen to insert just before the cached node, update
        // the cache to the new node to match the cached index
        if (fCachedChild == refInternal) {
            fCachedChild = newInternal;
        }
        else {
            // otherwise just invalidate the cache
            fCachedChildIndex = -1;
        }
    }

    if (this->getOwnerDocument() != null) {
        typedef RefVectorOf<RangeImpl> RangeImpls;
        RangeImpls* ranges = this->getOwnerDocument()->getRanges();
        if ( ranges != null) {
            unsigned int sz = ranges->size();
            for (unsigned int i =0; i<sz; i++) {
                ranges->elementAt(i)->updateRangeForInsertedNode(newInternal);
            }
        }
    }

    return newInternal;
};
Exemple #15
0
NodeImpl *AttrImpl::removeChild(NodeImpl *oldChild) {

    DocumentImpl *ownerDocument = getOwnerDocument();
    if (ownerDocument->getErrorChecking()) {
        if (isReadOnly()) {
            throw DOM_DOMException(
                                 DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR,
                                 null);
        }
        if (oldChild == null || oldChild->getParentNode() != this) {
            throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);
        }
    }
    // fix other ranges for change before deleting the node
    if (getOwnerDocument() !=  null) {
        typedef RefVectorOf<RangeImpl> RangeImpls;
        RangeImpls* ranges = this->getOwnerDocument()->getRanges();
        if (ranges != null) {
            unsigned int sz = ranges->size();
            if (sz != 0) {
                for (unsigned int i =0; i<sz; i++) {
                    if (ranges->elementAt(i) != null)
                        ranges->elementAt(i)->updateRangeForDeletedNode(oldChild);
                }
            }
        }
    }

    ChildNode * oldInternal = (ChildNode *) oldChild;

    // Patch linked list around oldChild
    // Note: lastChild == firstChild->previousSibling
    if (oldInternal == value.child) {
        // removing first child
        oldInternal->isFirstChild(false);
        value.child = oldInternal->nextSibling; // firstChild = oldInternal->nextSibling
        ChildNode *firstChild = value.child;
        if (firstChild != null) {
            firstChild->isFirstChild(true);
            firstChild->previousSibling = oldInternal->previousSibling;
        }
    } else {
        ChildNode *prev = oldInternal->previousSibling;
        ChildNode *next = oldInternal->nextSibling;
        prev->nextSibling = next;
        if (next == null) {
            // removing last child
            ChildNode *firstChild = value.child;
            firstChild->previousSibling = prev;
        } else {
            // removing some other child in the middle
            next->previousSibling = prev;
        }
    }

    // Remove oldInternal's references to tree
    oldInternal->ownerNode = getOwnerDocument();
    oldInternal->isOwned(false);
    oldInternal->nextSibling = null;
    oldInternal->previousSibling = null;

    changed();

    return oldInternal;
};
Exemple #16
0
Node* Node::removeChild(Node *oldChild)
{
	//ASSERT(0);
#if 0
	// Do this first?
	{
		CComQIPtr<INotifySend> cp = thisNode;
		if (cp)
		{
			cp->FireOnChanged(NOTIFY_REMOVE, oldChild, DISPID_UNKNOWN);
		}
	}
#endif

	Document* ownerDocument = oldChild->get_ownerDocument();

	if (ownerDocument)
	{
		ASSERT(ownerDocument != NULL);

		DocumentEvent* ownerDocumentEvent = dynamic_cast<DocumentEvent*>(ownerDocument);
		ASSERT(ownerDocumentEvent != NULL);

		MutationEvent* evt = dynamic_cast<MutationEvent*>(ownerDocumentEvent->createEvent(S("MutationEvent")));

	// Create a DOMNodeRemoved event
		evt->initMutationEvent(S("DOMNodeRemoved"), true, false, this, nullptr, nullptr, nullptr, CHANGE_UNKNOWN);

		EventTarget* target = dynamic_cast<EventTarget*>(oldChild);
		target->dispatchEvent(evt);

		NodeRemovedFromDocument(oldChild);
	}

// Do the work
	ChildNode* previous = oldChild->get_previousSibling();

	ChildNode* next = oldChild->get_nextSibling();

	if (previous != NULL)
		previous->set_nextSibling(next);
	else
		m_firstChild = next;

	if (next != NULL)
		next->set_previousSibling(previous);
	else
		m_lastChild = previous;

	oldChild->set_previousSibling(nullptr);
	oldChild->set_nextSibling(nullptr);

	for (int i = 0; i < m_childNodes->m_items.GetSize(); ++i)
	{
		if (m_childNodes->m_items[i] == oldChild)
		{
#if 0
			ASSERT(0);
			/////////
			CComQIPtr<INotifySend, &IID_INotifySend> cp = (IUnknown*)oldChild;
			if (cp)
			{
				CComQIPtr<INotifyGet, &IID_INotifyGet> get = (IUnknown*)thisNode;
				if (get)
				{
					cp->Unadvise(get);
				}
			}
#endif
			/////////

		//	m_childNodes->m_items.erase(&m_childNodes->m_items[i]);
			m_childNodes->m_items.RemoveAt(i);
			break;
		}
	}

	oldChild->set_parentNode(NULL);

	return oldChild;
}
Exemple #17
0
Node* Node::insertNode(Node* _newChild, Node* _pBefore)
{
	ChildNode* newChild = dynamic_cast<ChildNode*>(_newChild);
	ChildNode* pBefore = dynamic_cast<ChildNode*>(_pBefore);

	Node* pPrevParent = newChild->get_parentNode();
	if (pPrevParent)
	{
		pPrevParent->removeChild(newChild);
	}

	ChildNode* pAfter;

	if (pBefore)
		pAfter = pBefore->get_previousSibling();
	else
		pAfter = m_lastChild;

	newChild->set_nextSibling(pBefore);
	newChild->set_previousSibling(pAfter);

	if (pAfter == NULL)
		m_firstChild = newChild;
	else
		pAfter->set_nextSibling(newChild);

	if (pBefore == NULL)
		m_lastChild = newChild;
	else
		pBefore->set_previousSibling(newChild);

	if (pBefore)
	{
		for (int i = 0; i < m_childNodes->m_items.GetSize(); i++)
		{
			if (m_childNodes->m_items[i] == pBefore)
			{
				m_childNodes->m_items.InsertAt(i, newChild);
			//	m_childNodes->m_items.insert(&m_childNodes->m_items[i], newChild);
				break;
			}
		}
	}
	else
	{
		m_childNodes->m_items.Add(newChild);
	}

// Set new child node's parent to this element
	newChild->set_parentNode(this);

//	TRACE("TODO\n");
#if 0
// Update computed xmlspace for inserted child(ren)
	CComQIPtr<ILDOMElement> newElement((IUnknown*)newChild);
	if (newElement)
	{
		CComBSTR xmlspace;
		newElement->getAttribute(OLESTR("xml:space"), &xmlspace);
		if (xmlspace.Length()==0)	// inherit from parent
		{
			CComQIPtr<CLDOMElementImplImpl>((IUnknown*)newChild)->m_xmlspace = m_xmlspace;
		}
		else	// explicitly set
		{
			CComQIPtr<CLDOMElementImplImpl>((IUnknown*)newChild)->m_xmlspace = cmpbstr(xmlspace, OLESTR("preserve")) == 0;
		}
	// TODO, update recursively for newChild
	}
#endif
	// SMIL Animation (TODO, not very well thought trough)
#if 0
	{
		CLDOMDocument* pDocument = static_cast<CLDOMDocument*>(static_cast<CLDOMDocumentImpl<ILDOMDocument>*>(m_ownerDocument));

		if (pDocument)
		{
			CComQIPtr<ILDOMElement> newElement = newChild;

			if (newElement)
			{
			// SMIL Animation (connect animate/set etc. elements to the elements they target)
				pDocument->BuildAnimationListForAllElements(newElement, pDocument->m_documentElement);

			// Set baseVal/animVal from attributes and parse 'style' attributes
				pDocument->UpdateAnimationElements(newElement);
			}
		}
	}
#endif

//	TRACE("TODO\n");
#if 0
	// Timing stuff (TODO)
	{
		ElementTimeImplImpl* elementTimeImpl((IUnknown*)newChild);
		if (elementTimeImpl)
		{
			elementTimeImpl->CalculateTimeBeforeParent();

			CComPtr<ILElementTimeContainer> parentTimeContainer;
			elementTimeImpl->get_parentTimeContainer(&parentTimeContainer);
			CComQIPtr<CLElementTimeContainerImplImpl> parentTimeContainerImpl((IUnknown*)parentTimeContainer);
			if (parentTimeContainerImpl)
			{
				parentTimeContainerImpl->RecalculateTime();
			}

			elementTimeImpl->CalculateTimeAfterParent();
		}
	}

	CComQIPtr<ILAnimationElement, &IID_ILAnimationElement> animation = (IUnknown*)newChild;
	if (animation)
	{
		CComQIPtr<CLAnimationElementImplImpl> pAnimation((IUnknown*)animation);

		pAnimation->SetValuesFromAttributes();
	}
#endif

	{
#if 0	// TODO
		for (int i = 0; i < m_pNodes.GetSize(); i++)
		{
			ASSERT(0);
			m_pNodes[i]->OnInsertedChild(newChild);
		}
#endif

#if 0
		if (TRUE)	// TODO, probably remove this (use above loop only)
		{
			CComQIPtr<INotifySend, &IID_INotifySend> cp = newChild;
			if (cp)
			{
				CComQIPtr<INotifyGet, &IID_INotifyGet> get = (IUnknown*)thisNode;
				if (get)
				{
					DWORD cookie;
					cp->Advise(get, &cookie);
				}

				cp->FireOnChanged(NOTIFY_ADD, newChild, DISPID_UNKNOWN);
			}
		}
#endif
	}

//	CComPtr<ILDOMDocument> ownerDocument;
//	newChild->get_ownerDocument(&ownerDocument);
//	if (ownerDocument)
	{
////////////////////////////////
// create an event notification

		DocumentEvent* ownerDocumentEvent = dynamic_cast<DocumentEvent*>(m_ownerDocument);

		if (ownerDocumentEvent == NULL)
			ownerDocumentEvent = dynamic_cast<DocumentEvent*>(this);

		if (ownerDocumentEvent)
		{
			MutationEvent* event = dynamic_cast<MutationEvent*>(ownerDocumentEvent->createEvent(S("MutationEvent")));

			EventTarget* eventTarget = dynamic_cast<EventTarget*>(newChild);

		//
			event->initMutationEvent(S("DOMNodeInserted"), true, false, this, nullptr, nullptr, nullptr, CHANGE_UNKNOWN);

			bool doDefault = eventTarget->dispatchEvent(event);

			if (IsDocumentOrPartOfDocument(this))
			{
			// Send "DOMNodeInsertedIntoDocument" to the node and it's children
				NodeInsertedIntoDocument(newChild);
			}
		}

		{
			Node* p = this;
			while (p)
			{
				if (p->m_pNode)
				{
					p->m_pNode->m_bArrangeValid = false;
				}

				p = p->get_parentNode();
			}
		}

#if 0
	//
		event->initMutationEvent(OLESTR("DOMSubtreeModified"), VARIANT_TRUE, VARIANT_FALSE, thisNode, NULL, NULL, NULL, CHANGE_UNKNOWN);
		eventTarget->dispatchEvent(event, &doDefault);
#endif
	}

	return newChild;
}