|
Lines 45-50
a/WebCore/dom/Node.cpp_sec1
|
| 45 |
#include "DynamicNodeList.h" |
45 |
#include "DynamicNodeList.h" |
| 46 |
#include "Element.h" |
46 |
#include "Element.h" |
| 47 |
#include "Event.h" |
47 |
#include "Event.h" |
|
|
48 |
#include "EventContext.h" |
| 48 |
#include "EventException.h" |
49 |
#include "EventException.h" |
| 49 |
#include "EventHandler.h" |
50 |
#include "EventHandler.h" |
| 50 |
#include "EventListener.h" |
51 |
#include "EventListener.h" |
|
Lines 80-85
a/WebCore/dom/Node.cpp_sec2
|
| 80 |
#include "WebKitAnimationEvent.h" |
81 |
#include "WebKitAnimationEvent.h" |
| 81 |
#include "WebKitTransitionEvent.h" |
82 |
#include "WebKitTransitionEvent.h" |
| 82 |
#include "WheelEvent.h" |
83 |
#include "WheelEvent.h" |
|
|
84 |
#include "WindowEventContext.h" |
| 83 |
#include "XMLNames.h" |
85 |
#include "XMLNames.h" |
| 84 |
#include "htmlediting.h" |
86 |
#include "htmlediting.h" |
| 85 |
#include <wtf/HashSet.h> |
87 |
#include <wtf/HashSet.h> |
|
Lines 734-742
inline void Node::setStyleChange(StyleChangeType changeType)
a/WebCore/dom/Node.cpp_sec3
|
| 734 |
|
736 |
|
| 735 |
inline void Node::markAncestorsWithChildNeedsStyleRecalc() |
737 |
inline void Node::markAncestorsWithChildNeedsStyleRecalc() |
| 736 |
{ |
738 |
{ |
| 737 |
for (ContainerNode* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode()) |
739 |
for (ContainerNode* p = parentOrHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrHostNode()) |
| 738 |
p->setChildNeedsStyleRecalc(); |
740 |
p->setChildNeedsStyleRecalc(); |
| 739 |
|
741 |
|
| 740 |
if (document()->childNeedsStyleRecalc()) |
742 |
if (document()->childNeedsStyleRecalc()) |
| 741 |
document()->scheduleStyleRecalc(); |
743 |
document()->scheduleStyleRecalc(); |
| 742 |
} |
744 |
} |
|
Lines 1321-1327
void Node::createRendererIfNeeded()
a/WebCore/dom/Node.cpp_sec4
|
| 1321 |
|
1323 |
|
| 1322 |
ASSERT(!renderer()); |
1324 |
ASSERT(!renderer()); |
| 1323 |
|
1325 |
|
| 1324 |
ContainerNode* parent = parentNode(); |
1326 |
ContainerNode* parent = parentOrHostNode(); |
| 1325 |
ASSERT(parent); |
1327 |
ASSERT(parent); |
| 1326 |
|
1328 |
|
| 1327 |
RenderObject* parentRenderer = parent->renderer(); |
1329 |
RenderObject* parentRenderer = parent->renderer(); |
|
Lines 2239-2252
void Node::getSubresourceURLs(ListHashSet<KURL>& urls) const
a/WebCore/dom/Node.cpp_sec5
|
| 2239 |
addSubresourceAttributeURLs(urls); |
2241 |
addSubresourceAttributeURLs(urls); |
| 2240 |
} |
2242 |
} |
| 2241 |
|
2243 |
|
| 2242 |
ContainerNode* Node::eventParentNode() |
|
|
| 2243 |
{ |
| 2244 |
return parentNode(); |
| 2245 |
} |
| 2246 |
|
| 2247 |
Node* Node::enclosingLinkEventParentOrSelf() |
2244 |
Node* Node::enclosingLinkEventParentOrSelf() |
| 2248 |
{ |
2245 |
{ |
| 2249 |
for (Node* node = this; node; node = node->eventParentNode()) { |
2246 |
for (Node* node = this; node; node = node->parentOrHostNode()) { |
| 2250 |
// For imagemaps, the enclosing link node is the associated area element not the image itself. |
2247 |
// For imagemaps, the enclosing link node is the associated area element not the image itself. |
| 2251 |
// So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true |
2248 |
// So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true |
| 2252 |
// for them. |
2249 |
// for them. |
|
Lines 2484-2495
void Node::handleLocalEvents(Event* event)
a/WebCore/dom/Node.cpp_sec6
|
| 2484 |
fireEventListeners(event); |
2481 |
fireEventListeners(event); |
| 2485 |
} |
2482 |
} |
| 2486 |
|
2483 |
|
| 2487 |
#if ENABLE(SVG) |
2484 |
static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNode) |
| 2488 |
static inline SVGElementInstance* eventTargetAsSVGElementInstance(Node* referenceNode) |
|
|
| 2489 |
{ |
2485 |
{ |
| 2490 |
ASSERT(referenceNode); |
2486 |
ASSERT(referenceNode); |
|
|
2487 |
|
| 2488 |
#if ENABLE(SVG) |
| 2491 |
if (!referenceNode->isSVGElement()) |
2489 |
if (!referenceNode->isSVGElement()) |
| 2492 |
return 0; |
2490 |
return referenceNode; |
| 2493 |
|
2491 |
|
| 2494 |
// Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included |
2492 |
// Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included |
| 2495 |
// as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects |
2493 |
// as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects |
|
Lines 2503-2538
static inline SVGElementInstance* eventTargetAsSVGElementInstance(Node* referenc
a/WebCore/dom/Node.cpp_sec7
|
| 2503 |
if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode)) |
2501 |
if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode)) |
| 2504 |
return instance; |
2502 |
return instance; |
| 2505 |
} |
2503 |
} |
|
|
2504 |
#endif |
| 2506 |
|
2505 |
|
| 2507 |
return 0; |
2506 |
return referenceNode; |
| 2508 |
} |
2507 |
} |
| 2509 |
#endif |
|
|
| 2510 |
|
2508 |
|
| 2511 |
static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNode) |
2509 |
void Node::getEventAncestors(Vector<EventContext>& ancestors, EventTarget* originalTarget, EventDispatchBehavior behavior) |
| 2512 |
{ |
2510 |
{ |
| 2513 |
ASSERT(referenceNode); |
2511 |
if (!inDocument()) |
|
|
2512 |
return; |
| 2514 |
|
2513 |
|
| 2515 |
#if ENABLE(SVG) |
2514 |
EventTarget* target = originalTarget; |
| 2516 |
if (SVGElementInstance* instance = eventTargetAsSVGElementInstance(referenceNode)) { |
2515 |
Node* ancestor = this; |
| 2517 |
ASSERT(instance->shadowTreeElement() == referenceNode); |
2516 |
bool shouldSkipNextAncestor = false; |
| 2518 |
return instance; |
2517 |
while (true) { |
| 2519 |
} |
2518 |
if (ancestor->isShadowNode()) { |
| 2520 |
#endif |
2519 |
if (behavior == StayInsideShadowDOM) |
|
|
2520 |
return; |
| 2521 |
ancestor = ancestor->shadowParentNode(); |
| 2522 |
if (!shouldSkipNextAncestor) |
| 2523 |
target = ancestor; |
| 2524 |
} else |
| 2525 |
ancestor = ancestor->parentNode(); |
| 2521 |
|
2526 |
|
| 2522 |
return referenceNode; |
2527 |
if (!ancestor) |
| 2523 |
} |
2528 |
return; |
| 2524 |
|
2529 |
|
| 2525 |
void Node::eventAncestors(Vector<RefPtr<ContainerNode> > &ancestors) |
|
|
| 2526 |
{ |
| 2527 |
if (inDocument()) { |
| 2528 |
for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) { |
| 2529 |
#if ENABLE(SVG) |
2530 |
#if ENABLE(SVG) |
| 2530 |
// Skip <use> shadow tree elements. |
2531 |
// Skip SVGShadowTreeRootElement. |
| 2531 |
if (ancestor->isSVGElement() && ancestor->isShadowNode()) |
2532 |
shouldSkipNextAncestor = ancestor->isSVGElement() && ancestor->isShadowNode(); |
| 2532 |
continue; |
2533 |
if (shouldSkipNextAncestor) |
|
|
2534 |
continue; |
| 2533 |
#endif |
2535 |
#endif |
| 2534 |
ancestors.append(ancestor); |
2536 |
// FIXME: Unroll the extra loop inside eventTargetRespectingSVGTargetRules into this loop. |
| 2535 |
} |
2537 |
ancestors.append(EventContext(ancestor, eventTargetRespectingSVGTargetRules(ancestor), target)); |
|
|
2538 |
|
| 2536 |
} |
2539 |
} |
| 2537 |
} |
2540 |
} |
| 2538 |
|
2541 |
|
|
Lines 2547-2552
bool Node::dispatchEvent(PassRefPtr<Event> prpEvent)
a/WebCore/dom/Node.cpp_sec8
|
| 2547 |
return dispatchGenericEvent(event.release()); |
2550 |
return dispatchGenericEvent(event.release()); |
| 2548 |
} |
2551 |
} |
| 2549 |
|
2552 |
|
|
|
2553 |
static const EventContext* topEventContext(const Vector<EventContext>& ancestors) |
| 2554 |
{ |
| 2555 |
return ancestors.isEmpty() ? 0 : &(ancestors.last()); |
| 2556 |
} |
| 2557 |
|
| 2550 |
bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent) |
2558 |
bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent) |
| 2551 |
{ |
2559 |
{ |
| 2552 |
RefPtr<Event> event(prpEvent); |
2560 |
RefPtr<Event> event(prpEvent); |
|
Lines 2559-2578
bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
a/WebCore/dom/Node.cpp_sec9
|
| 2559 |
// If the node is not in a document just send the event to it. |
2567 |
// If the node is not in a document just send the event to it. |
| 2560 |
// Be sure to ref all of nodes since event handlers could result in the last reference going away. |
2568 |
// Be sure to ref all of nodes since event handlers could result in the last reference going away. |
| 2561 |
RefPtr<Node> thisNode(this); |
2569 |
RefPtr<Node> thisNode(this); |
| 2562 |
Vector<RefPtr<ContainerNode> > ancestors; |
2570 |
RefPtr<EventTarget> originalTarget = event->target(); |
| 2563 |
eventAncestors(ancestors); |
2571 |
Vector<EventContext> ancestors; |
|
|
2572 |
getEventAncestors(ancestors, originalTarget.get(), event->isMutationEvent() ? StayInsideShadowDOM : RetargetEvent); |
| 2564 |
|
2573 |
|
| 2565 |
// Set up a pointer to indicate whether / where to dispatch window events. |
2574 |
WindowEventContext windowContext(event.get(), this, topEventContext(ancestors)); |
| 2566 |
// We don't dispatch load events to the window. That quirk was originally |
|
|
| 2567 |
// added because Mozilla doesn't propagate load events to the window object. |
| 2568 |
DOMWindow* targetForWindowEvents = 0; |
| 2569 |
if (event->type() != eventNames().loadEvent) { |
| 2570 |
Node* topLevelContainer = ancestors.isEmpty() ? this : ancestors.last().get(); |
| 2571 |
if (topLevelContainer->isDocumentNode()) |
| 2572 |
targetForWindowEvents = static_cast<Document*>(topLevelContainer)->domWindow(); |
| 2573 |
} |
| 2574 |
|
2575 |
|
| 2575 |
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(document(), *event, targetForWindowEvents, this, ancestors); |
2576 |
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(document(), *event, windowContext.window(), this, ancestors); |
| 2576 |
|
2577 |
|
| 2577 |
// Give the target node a chance to do some work before DOM event handlers get a crack. |
2578 |
// Give the target node a chance to do some work before DOM event handlers get a crack. |
| 2578 |
void* data = preDispatchEventHandler(event.get()); |
2579 |
void* data = preDispatchEventHandler(event.get()); |
|
Lines 2582-2603
bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
a/WebCore/dom/Node.cpp_sec10
|
| 2582 |
// Trigger capturing event handlers, starting at the top and working our way down. |
2583 |
// Trigger capturing event handlers, starting at the top and working our way down. |
| 2583 |
event->setEventPhase(Event::CAPTURING_PHASE); |
2584 |
event->setEventPhase(Event::CAPTURING_PHASE); |
| 2584 |
|
2585 |
|
| 2585 |
if (targetForWindowEvents) { |
2586 |
if (windowContext.handleLocalEvents(event.get()) && event->propagationStopped()) |
| 2586 |
event->setCurrentTarget(targetForWindowEvents); |
2587 |
goto doneDispatching; |
| 2587 |
targetForWindowEvents->fireEventListeners(event.get()); |
2588 |
|
| 2588 |
if (event->propagationStopped()) |
|
|
| 2589 |
goto doneDispatching; |
| 2590 |
} |
| 2591 |
for (size_t i = ancestors.size(); i; --i) { |
2589 |
for (size_t i = ancestors.size(); i; --i) { |
| 2592 |
ContainerNode* ancestor = ancestors[i - 1].get(); |
2590 |
ancestors[i - 1].handleLocalEvents(event.get()); |
| 2593 |
event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor)); |
|
|
| 2594 |
ancestor->handleLocalEvents(event.get()); |
| 2595 |
if (event->propagationStopped()) |
2591 |
if (event->propagationStopped()) |
| 2596 |
goto doneDispatching; |
2592 |
goto doneDispatching; |
| 2597 |
} |
2593 |
} |
| 2598 |
|
2594 |
|
| 2599 |
event->setEventPhase(Event::AT_TARGET); |
2595 |
event->setEventPhase(Event::AT_TARGET); |
| 2600 |
|
2596 |
event->setTarget(originalTarget.get()); |
| 2601 |
event->setCurrentTarget(eventTargetRespectingSVGTargetRules(this)); |
2597 |
event->setCurrentTarget(eventTargetRespectingSVGTargetRules(this)); |
| 2602 |
handleLocalEvents(event.get()); |
2598 |
handleLocalEvents(event.get()); |
| 2603 |
if (event->propagationStopped()) |
2599 |
if (event->propagationStopped()) |
|
Lines 2609-2629
bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
a/WebCore/dom/Node.cpp_sec11
|
| 2609 |
|
2605 |
|
| 2610 |
size_t size = ancestors.size(); |
2606 |
size_t size = ancestors.size(); |
| 2611 |
for (size_t i = 0; i < size; ++i) { |
2607 |
for (size_t i = 0; i < size; ++i) { |
| 2612 |
ContainerNode* ancestor = ancestors[i].get(); |
2608 |
ancestors[i].handleLocalEvents(event.get()); |
| 2613 |
event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor)); |
|
|
| 2614 |
ancestor->handleLocalEvents(event.get()); |
| 2615 |
if (event->propagationStopped() || event->cancelBubble()) |
| 2616 |
goto doneDispatching; |
| 2617 |
} |
| 2618 |
if (targetForWindowEvents) { |
| 2619 |
event->setCurrentTarget(targetForWindowEvents); |
| 2620 |
targetForWindowEvents->fireEventListeners(event.get()); |
| 2621 |
if (event->propagationStopped() || event->cancelBubble()) |
2609 |
if (event->propagationStopped() || event->cancelBubble()) |
| 2622 |
goto doneDispatching; |
2610 |
goto doneDispatching; |
| 2623 |
} |
2611 |
} |
|
|
2612 |
windowContext.handleLocalEvents(event.get()); |
| 2624 |
} |
2613 |
} |
| 2625 |
|
2614 |
|
| 2626 |
doneDispatching: |
2615 |
doneDispatching: |
|
|
2616 |
event->setTarget(originalTarget.get()); |
| 2627 |
event->setCurrentTarget(0); |
2617 |
event->setCurrentTarget(0); |
| 2628 |
event->setEventPhase(0); |
2618 |
event->setEventPhase(0); |
| 2629 |
|
2619 |
|
|
Lines 2644-2651
doneDispatching:
a/WebCore/dom/Node.cpp_sec12
|
| 2644 |
if (event->bubbles()) { |
2634 |
if (event->bubbles()) { |
| 2645 |
size_t size = ancestors.size(); |
2635 |
size_t size = ancestors.size(); |
| 2646 |
for (size_t i = 0; i < size; ++i) { |
2636 |
for (size_t i = 0; i < size; ++i) { |
| 2647 |
ContainerNode* ancestor = ancestors[i].get(); |
2637 |
ancestors[i].node()->defaultEventHandler(event.get()); |
| 2648 |
ancestor->defaultEventHandler(event.get()); |
|
|
| 2649 |
ASSERT(!event->defaultPrevented()); |
2638 |
ASSERT(!event->defaultPrevented()); |
| 2650 |
if (event->defaultHandled()) |
2639 |
if (event->defaultHandled()) |
| 2651 |
goto doneWithDefault; |
2640 |
goto doneWithDefault; |
|
Lines 2655-2660
doneDispatching:
a/WebCore/dom/Node.cpp_sec13
|
| 2655 |
|
2644 |
|
| 2656 |
doneWithDefault: |
2645 |
doneWithDefault: |
| 2657 |
|
2646 |
|
|
|
2647 |
// Ensure that after event dispatch, the event's target object is the |
| 2648 |
// outermost shadow DOM boundary. |
| 2649 |
event->setTarget(windowContext.target()); |
| 2650 |
event->setCurrentTarget(0); |
| 2658 |
InspectorInstrumentation::didDispatchEvent(cookie); |
2651 |
InspectorInstrumentation::didDispatchEvent(cookie); |
| 2659 |
|
2652 |
|
| 2660 |
return !event->defaultPrevented(); |
2653 |
return !event->defaultPrevented(); |