void NodeRemovedFromDocument(Node* node) { NodeList* childNodes = node->get_childNodes(); unsigned int length = childNodes->get_length(); for (unsigned int i = 0; i < length; ++i) { Node* child = childNodes->item(i); NodeRemovedFromDocument(child); } Document* ownerDocument = node->get_ownerDocument(); DocumentEvent* ownerDocumentEvent = dynamic_cast<DocumentEvent*>(ownerDocument); ASSERT(ownerDocumentEvent != nullptr); MutationEvent* event = dynamic_cast<MutationEvent*>(ownerDocumentEvent->createEvent(S("MutationEvent"))); event->initMutationEvent(S("DOMNodeRemovedFromDocument"), false, false, NULL/*relatedNode*/, nullptr, nullptr, nullptr, CHANGE_UNKNOWN); EventTarget* target = dynamic_cast<EventTarget*>(node); target->dispatchEvent(event); }
JSValue* JSMutationEvent::getValueProperty(ExecState* exec, int token) const { switch (token) { case RelatedNodeAttrNum: { MutationEvent* imp = static_cast<MutationEvent*>(impl()); return toJS(exec, WTF::getPtr(imp->relatedNode())); } case PrevValueAttrNum: { MutationEvent* imp = static_cast<MutationEvent*>(impl()); return jsString(exec, imp->prevValue()); } case NewValueAttrNum: { MutationEvent* imp = static_cast<MutationEvent*>(impl()); return jsString(exec, imp->newValue()); } case AttrNameAttrNum: { MutationEvent* imp = static_cast<MutationEvent*>(impl()); return jsString(exec, imp->attrName()); } case AttrChangeAttrNum: { MutationEvent* imp = static_cast<MutationEvent*>(impl()); return jsNumber(exec, imp->attrChange()); } case ConstructorAttrNum: return getConstructor(exec); } return 0; }
JSValue jsMutationEventRelatedNode(ExecState* exec, JSValue slotBase, const Identifier&) { JSMutationEvent* castedThis = static_cast<JSMutationEvent*>(asObject(slotBase)); UNUSED_PARAM(exec); MutationEvent* imp = static_cast<MutationEvent*>(castedThis->impl()); JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->relatedNode())); return result; }
JSValue jsMutationEventNewValue(ExecState* exec, JSValue slotBase, const Identifier&) { JSMutationEvent* castedThis = static_cast<JSMutationEvent*>(asObject(slotBase)); UNUSED_PARAM(exec); MutationEvent* imp = static_cast<MutationEvent*>(castedThis->impl()); JSValue result = jsString(exec, imp->newValue()); return result; }
JSValue jsMutationEventAttrChange(ExecState* exec, JSValue slotBase, const Identifier&) { JSMutationEvent* castedThis = static_cast<JSMutationEvent*>(asObject(slotBase)); UNUSED_PARAM(exec); MutationEvent* imp = static_cast<MutationEvent*>(castedThis->impl()); JSValue result = jsNumber(imp->attrChange()); return result; }
void CharacterData::set_data(System::StringW* data) { m_data = data; MutationEvent* evt = new MutationEvent; evt->InitEvent(WSTR("TextChanged"), true, false); dispatchEvent(evt); }
static v8::Handle<v8::Value> initMutationEventCallback(const v8::Arguments& args) { MutationEvent* imp = V8MutationEvent::toNative(args.Holder()); V8TRYCATCH_FOR_V8STRINGRESOURCE(V8StringResource<>, type, MAYBE_MISSING_PARAMETER(args, 0, DefaultIsUndefined)); V8TRYCATCH(bool, canBubble, MAYBE_MISSING_PARAMETER(args, 1, DefaultIsUndefined)->BooleanValue()); V8TRYCATCH(bool, cancelable, MAYBE_MISSING_PARAMETER(args, 2, DefaultIsUndefined)->BooleanValue()); V8TRYCATCH(Node*, relatedNode, V8Node::HasInstance(MAYBE_MISSING_PARAMETER(args, 3, DefaultIsUndefined)) ? V8Node::toNative(v8::Handle<v8::Object>::Cast(MAYBE_MISSING_PARAMETER(args, 3, DefaultIsUndefined))) : 0); V8TRYCATCH_FOR_V8STRINGRESOURCE(V8StringResource<>, prevValue, MAYBE_MISSING_PARAMETER(args, 4, DefaultIsUndefined)); V8TRYCATCH_FOR_V8STRINGRESOURCE(V8StringResource<>, newValue, MAYBE_MISSING_PARAMETER(args, 5, DefaultIsUndefined)); V8TRYCATCH_FOR_V8STRINGRESOURCE(V8StringResource<>, attrName, MAYBE_MISSING_PARAMETER(args, 6, DefaultIsUndefined)); V8TRYCATCH(int, attrChange, toUInt32(MAYBE_MISSING_PARAMETER(args, 7, DefaultIsUndefined))); imp->initMutationEvent(type, canBubble, cancelable, relatedNode, prevValue, newValue, attrName, attrChange); return v8Undefined(); }
JSValue* jsMutationEventPrototypeFunctionInitMutationEvent(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args) { if (!thisValue->isObject(&JSMutationEvent::s_info)) return throwError(exec, TypeError); JSMutationEvent* castedThisObj = static_cast<JSMutationEvent*>(thisValue); MutationEvent* imp = static_cast<MutationEvent*>(castedThisObj->impl()); const UString& type = args[0]->toString(exec); bool canBubble = args[1]->toBoolean(exec); bool cancelable = args[2]->toBoolean(exec); Node* relatedNode = toNode(args[3]); const UString& prevValue = args[4]->toString(exec); const UString& newValue = args[5]->toString(exec); const UString& attrName = args[6]->toString(exec); unsigned short attrChange = args[7]->toInt32(exec); imp->initMutationEvent(type, canBubble, cancelable, relatedNode, prevValue, newValue, attrName, attrChange); return jsUndefined(); }
void CharacterData::deleteData(long offset, long count) { // TODO, improve this ASSERT(0); #if 0 System::StringW* data = sysstring(m_data.c_str(), offset); data += m_data.c_str()+offset+count; m_data = data; MutationEvent* evt = new MutationEvent; evt->m_offset = offset; evt->m_len = count; evt->initEvent(WSTR("TextDeleted"), true, false); dispatchEvent(evt); #endif }
void CharacterData::insertData(long offset, System::StringW* arg) { ASSERT(0); #if 0 // TODO, improve this sysstring data = sysstring(m_data.c_str(), offset); data += arg; data += m_data.c_str()+offset; m_data = data; MutationEvent* evt = new MutationEvent; evt->m_offset = offset; evt->m_len = arg.length(); evt->initEvent(OLESTR("TextInserted"), true, false); dispatchEvent(evt); #endif }
EncodedJSValue JSC_HOST_CALL jsMutationEventPrototypeFunctionInitMutationEvent(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSMutationEvent::s_info)) return throwVMTypeError(exec); JSMutationEvent* castedThis = static_cast<JSMutationEvent*>(asObject(thisValue)); ASSERT_GC_OBJECT_INHERITS(castedThis, &JSMutationEvent::s_info); MutationEvent* imp = static_cast<MutationEvent*>(castedThis->impl()); const String& type(ustringToString(exec->argument(0).toString(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); bool canBubble(exec->argument(1).toBoolean(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); bool cancelable(exec->argument(2).toBoolean(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); Node* relatedNode(toNode(exec->argument(3))); if (exec->hadException()) return JSValue::encode(jsUndefined()); const String& prevValue(ustringToString(exec->argument(4).toString(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); const String& newValue(ustringToString(exec->argument(5).toString(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); const String& attrName(ustringToString(exec->argument(6).toString(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); unsigned short attrChange(exec->argument(7).toUInt32(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); imp->initMutationEvent(type, canBubble, cancelable, relatedNode, prevValue, newValue, attrName, attrChange); return JSValue::encode(jsUndefined()); }
void NodeInsertedIntoDocument(Node* node) { NodeList* childNodes = node->get_childNodes(); long length = childNodes->get_length(); for (int i = 0; i < length; ++i) { Node* child = childNodes->item(i); NodeInsertedIntoDocument(child); } Document* ownerDocument = node->get_ownerDocument(); DocumentEvent* ownerDocumentEvent = dynamic_cast<DocumentEvent*>(ownerDocument); ASSERT(ownerDocumentEvent != nullptr); MutationEvent* pEvent = dynamic_cast<MutationEvent*>(ownerDocumentEvent->createEvent(S("MutationEvent"))); pEvent->initMutationEvent(S("DOMNodeInsertedIntoDocument"), false, false, nullptr/*relatedNode*/, nullptr, nullptr, nullptr, CHANGE_UNKNOWN); EventTarget* target = dynamic_cast<EventTarget*>(node); target->dispatchEvent(pEvent); }
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; }
static v8::Handle<v8::Value> attrChangeAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { MutationEvent* imp = V8MutationEvent::toNative(info.Holder()); return v8Integer(imp->attrChange(), info.GetIsolate()); }
static v8::Handle<v8::Value> relatedNodeAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { MutationEvent* imp = V8MutationEvent::toNative(info.Holder()); return toV8Fast(imp->relatedNode(), info, imp); }
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; }
void handleEvent(Event* evt) { XMLString type = evt->type(); XMLString phase; switch (evt->eventPhase()) { case Event::CAPTURING_PHASE: phase = "CAPTURING_PHASE"; break; case Event::AT_TARGET: phase = "AT_TARGET"; break; case Event::BUBBLING_PHASE: phase = "BUBBLING_PHASE"; break; } Node* pTarget = static_cast<Node*>(evt->target()); Node* pCurrentTarget = static_cast<Node*>(evt->currentTarget()); _log.append(_name); _log.append(":"); _log.append(type); _log.append(":"); _log.append(phase); _log.append(":"); _log.append(pTarget->nodeName()); _log.append(":"); _log.append(pCurrentTarget->nodeName()); _log.append(":"); _log.append(evt->bubbles() ? "B" : "-"); _log.append(":"); _log.append(evt->cancelable() ? "C" : "-"); MutationEvent* pME = dynamic_cast<MutationEvent*>(evt); if (pME) { XMLString attrChange; switch (pME->attrChange()) { case MutationEvent::MODIFICATION: attrChange = "MODIFICATION"; break; case MutationEvent::ADDITION: attrChange = "ADDITION"; break; case MutationEvent::REMOVAL: attrChange = "REMOVAL"; break; } XMLString relatedNode; Node* pRelatedNode = pME->relatedNode(); if (pRelatedNode) relatedNode = pRelatedNode->nodeName(); _log.append(":"); _log.append(attrChange); _log.append(":"); _log.append(relatedNode); _log.append(":"); _log.append(pME->attrName()); _log.append(":"); _log.append(pME->prevValue()); _log.append(":"); _log.append(pME->newValue()); } _log.append("\n"); if (_cancel) evt->stopPropagation(); if (_readd) pCurrentTarget->addEventListener(type, this, _capture); }
void Attr::set_value(StringIn newVal) { String prevValue = nullptr; if (false) { prevValue = get_value(); } m_valueIsValid = true; // Optimize if there is one single textnode already there Text* textNode; #if 0 CComQIPtr<ILDOMText, &IID_ILDOMText> textNode; if ((m_childNodes->m_items.GetSize() == 1) && (textNode = m_childNodes->m_items[0])) { textNode->set_data(newVal); } else #endif { for (int i = m_childNodes->m_items.GetSize()-1; i >= 0; i--) { removeChild(m_childNodes->m_items[i]); } textNode = m_ownerDocument->createTextNode(newVal); appendChild(textNode); } #if 0 ASSERT(m_callbacks); (m_ownerElement->*m_callbacks->SetBaseValString)(); #endif if (m_owner) { m_owner->UpdateBaseValString(); } // m_callbacks->SetBaseValString(m_ownerElement); // m_notify->OnSetBaseValString(); /* if (m_pListener) { m_pListener->OnAttrValueChanged(m_nodeName, this); } */ if (false) { EventTarget* eventTarget = dynamic_cast<EventTarget*>(m_ownerElement); if (eventTarget) { DocumentEvent* ownerDocumentEvent = dynamic_cast<DocumentEvent*>(m_ownerDocument); if (ownerDocumentEvent) { MutationEvent* evt; evt = dynamic_cast<MutationEvent*>(ownerDocumentEvent->createEvent(WSTR("MutationEvent"))); if (evt) { // Create an attr modification event evt->initMutationEvent(WSTR("DOMAttrModified"), true, false, this, prevValue, newVal, m_nodeName, CHANGE_MODIFICATION); eventTarget->dispatchEvent(evt); } } } } }