void XMLTokenizer::notifyFinished(CachedResource* finishedObj) { ASSERT(m_pendingScript == finishedObj); ASSERT(m_pendingScript->accessCount() > 0); String cachedScriptUrl = m_pendingScript->url(); String scriptSource = m_pendingScript->script(); bool errorOccurred = m_pendingScript->errorOccurred(); m_pendingScript->removeClient(this); m_pendingScript = 0; RefPtr<Element> e = m_scriptElement; m_scriptElement = 0; if (errorOccurred) EventTargetNodeCast(e.get())->dispatchHTMLEvent(eventNames().errorEvent, true, false); else { m_view->frame()->loader()->executeScript(cachedScriptUrl, 1, scriptSource); EventTargetNodeCast(e.get())->dispatchHTMLEvent(eventNames().loadEvent, false, false); } m_scriptElement = 0; if (!m_requestingScript) resumeParsing(); }
// FIXME: This needs to be unified with the keyPress method on FrameMac bool FrameWin::keyPress(const PlatformKeyboardEvent& keyEvent) { bool result; // Check for cases where we are too early for events -- possible unmatched key up // from pressing return in the location bar. Document *doc = document(); if (!doc) return false; Node *node = doc->focusNode(); if (!node) { if (doc->isHTMLDocument()) node = doc->body(); else node = doc->documentElement(); if (!node) return false; } if (!keyEvent.isKeyUp()) prepareForUserAction(); result = !EventTargetNodeCast(node)->dispatchKeyEvent(keyEvent); // FIXME: FrameMac has a keyDown/keyPress hack here which we are not copying. return result; }
bool EventTarget::dispatchGenericEvent(EventTargetNode* referenceNode, PassRefPtr<Event> e, ExceptionCode&, bool tempEvent) { RefPtr<Event> evt(e); ASSERT(!eventDispatchForbidden()); ASSERT(evt->target()); ASSERT(!evt->type().isNull()); // JavaScript code could create an event with an empty name // work out what nodes to send event to DeprecatedPtrList<Node> nodeChain; if (referenceNode->inDocument()) { for (Node* n = referenceNode; n; n = n->eventParentNode()) { n->ref(); nodeChain.prepend(n); } } else { // if node is not in the document just send event to itself referenceNode->ref(); nodeChain.prepend(referenceNode); } DeprecatedPtrListIterator<Node> it(nodeChain); // Before we begin dispatching events, give the target node a chance to do some work prior // to the DOM event handlers getting a crack. void* data = preDispatchEventHandler(evt.get()); // trigger any capturing event handlers on our way down evt->setEventPhase(Event::CAPTURING_PHASE); it.toFirst(); // Handle window events for capture phase, except load events, this quirk is needed // because Mozilla used to never propagate load events to the window object if (evt->type() != eventNames().loadEvent && it.current()->isDocumentNode() && !evt->propagationStopped()) static_cast<Document*>(it.current())->handleWindowEvent(evt.get(), true); EventTargetNode* eventTargetNode = 0; for (; it.current() && it.current() != referenceNode && !evt->propagationStopped(); ++it) { eventTargetNode = EventTargetNodeCast(it.current()); evt->setCurrentTarget(eventTargetRespectingSVGTargetRules(eventTargetNode)); eventTargetNode->handleLocalEvents(evt.get(), true); } // dispatch to the actual target node it.toLast(); if (!evt->propagationStopped()) { evt->setEventPhase(Event::AT_TARGET); eventTargetNode = EventTargetNodeCast(it.current()); evt->setCurrentTarget(eventTargetRespectingSVGTargetRules(eventTargetNode)); // We do want capturing event listeners to be invoked here, even though // that violates the specification since Mozilla does it. eventTargetNode->handleLocalEvents(evt.get(), true); eventTargetNode->handleLocalEvents(evt.get(), false); } --it; // ok, now bubble up again (only non-capturing event handlers will be called) // ### recalculate the node chain here? (e.g. if target node moved in document by previous event handlers) // no. the DOM specs says: // The chain of EventTargets from the event target to the top of the tree // is determined before the initial dispatch of the event. // If modifications occur to the tree during event processing, // event flow will proceed based on the initial state of the tree. // // since the initial dispatch is before the capturing phase, // there's no need to recalculate the node chain. // (tobias) if (evt->bubbles()) { evt->setEventPhase(Event::BUBBLING_PHASE); for (; it.current() && !evt->propagationStopped() && !evt->cancelBubble(); --it) { eventTargetNode = EventTargetNodeCast(it.current()); evt->setCurrentTarget(eventTargetRespectingSVGTargetRules(eventTargetNode)); eventTargetNode->handleLocalEvents(evt.get(), false); } it.toFirst(); // Handle window events for bubbling phase, except load events, this quirk is needed // because Mozilla used to never propagate load events at all if (evt->type() != eventNames().loadEvent && it.current()->isDocumentNode() && !evt->propagationStopped() && !evt->cancelBubble()) { evt->setCurrentTarget(EventTargetNodeCast(it.current())); static_cast<Document*>(it.current())->handleWindowEvent(evt.get(), false); } } evt->setCurrentTarget(0); evt->setEventPhase(0); // I guess this is correct, the spec does not seem to say // anything about the default event handler phase. // Now call the post dispatch. postDispatchEventHandler(evt.get(), data); // now we call all default event handlers (this is not part of DOM - it is internal to WebCore) it.toLast(); if (evt->bubbles()) for (; it.current() && !evt->defaultPrevented() && !evt->defaultHandled(); --it) EventTargetNodeCast(it.current())->defaultEventHandler(evt.get()); else if (!evt->defaultPrevented() && !evt->defaultHandled()) EventTargetNodeCast(it.current())->defaultEventHandler(evt.get()); // deref all nodes in chain it.toFirst(); for (; it.current(); ++it) it.current()->deref(); // this may delete us Document::updateDocumentsRendering(); // If tempEvent is true, this means that the DOM implementation // will not be storing a reference to the event, i.e. there is no // way to retrieve it from javascript if a script does not already // have a reference to it in a variable. So there is no need for // the interpreter to keep the event in it's cache Frame* frame = referenceNode->document()->frame(); if (tempEvent && frame && frame->script()->isEnabled()) frame->script()->finishedWithEvent(evt.get()); return !evt->defaultPrevented(); // ### what if defaultPrevented was called before dispatchEvent? }