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; }
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; }