2010-11-03 Dimitri Glazkov <dglazkov@chromium.org>
authordglazkov@chromium.org <dglazkov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Nov 2010 17:02:40 +0000 (17:02 +0000)
committerdglazkov@chromium.org <dglazkov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Nov 2010 17:02:40 +0000 (17:02 +0000)
        Reviewed by Darin Adler.

        Implement shadow DOM-aware event targeting and introduce EventContext to track the context of each event dispatch.
        https://bugs.webkit.org/show_bug.cgi?id=46015

        Tuned shadow-boundary-crossing.html to better reflect its point: the event should indeed fire (it used to be swallowed),
        but its target should be a non-shadow node.

        Tweaked audio-delete-while-slider-thumb-clicked.html to actually click on
        the scrubber thumb (it was off by 2 pixels).

        * fast/events/shadow-boundary-crossing.html: Modified the test.
        * media/audio-delete-while-slider-thumb-clicked.html : Ditto.
2010-11-03  Dimitri Glazkov  <dglazkov@chromium.org>

        Reviewed by Darin Adler.

        Implement shadow DOM-aware event targeting and introduce EventContext to track the context of each event dispatch.
        https://bugs.webkit.org/show_bug.cgi?id=46015

        This patch adds the notion of EventContext (and a very similar-acting WindowEventContext, specifically
        for DOMWindow), an abstraction that carries information around dispatching an event for any given Node.

        This abstraction is necessary to ensure that events, fired from shadow DOM nodes are properly retargeted to
        appear as if they are coming from their host, thus never exposing the shadow DOM nodes to the world outside.

        * Android.mk: Added EventContext, WindowEventContext files.
        * CMakeLists.txt: Ditto.
        * GNUmakefile.am: Ditto.
        * WebCore.gypi: Ditto.
        * WebCore.pro: Ditto.
        * WebCore.xcodeproj/project.pbxproj: Ditto.
        * WebCore.vcproj/WebCore.vcproj: Ditto.
        * dom/ContainerNode.cpp:
        (WebCore::notifyChildInserted): Changed to be shadow DOM-aware.
        * dom/EventContext.cpp: Added.
        * dom/EventContext.h: Added.
        * dom/Node.cpp:
        (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): Changed to be shadow DOM-aware.
        (WebCore::Node::createRendererIfNeeded): Ditto.
        (WebCore::Node::parentOrHostNode): Added new helper method.
        (WebCore::Node::enclosingLinkEventParentOrSelf): Changed to be shadow DOM-aware.
        (WebCore::eventTargetRespectingSVGTargetRules): Collapsed two helper methods into one.
        (WebCore::Node::eventAncestors): Refactored to collect a vector of EventContexts.
        (WebCore::Node::topEventContext): Added.
        (WebCore::eventHasListeners): Changed to use EventContexts.
        (WebCore::Node::dispatchGenericEvent): Ditto.
        * dom/Node.h: Removed eventParentNode that's no longer needed, added parentOrHostNode decl,
            and changed signature of eventAncestors to use EventContexts.
        * dom/Text.cpp:
        (WebCore::Text::createRenderer): Changed to be shadow DOM-aware.
        * inspector/InspectorDOMAgent.cpp:
        (WebCore::InspectorDOMAgent::getEventListenersForNode): Changed to use EventContexts.
        * page/EventHandler.cpp:
        (WebCore::EventHandler::updateMouseEventTargetNode): Removed code that's no longer necessary.
        * rendering/ShadowElement.h: Made m_shadowParent a RefPtr to avoid stale references when parent
        is deleted.
        * svg/SVGElement.cpp: Removed eventParentNode that's no longer needed.
        * svg/SVGElement.h: Ditto.
        * dom/WindowEventContext.cpp: Added.
        * dom/WindowEventContext.h: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@71244 268f45cc-cd09-0410-ab3c-d52691b4dbfc

26 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/shadow-boundary-crossing.html
LayoutTests/media/audio-delete-while-slider-thumb-clicked.html
WebCore/Android.mk
WebCore/CMakeLists.txt
WebCore/ChangeLog
WebCore/GNUmakefile.am
WebCore/WebCore.gypi
WebCore/WebCore.pro
WebCore/WebCore.vcproj/WebCore.vcproj
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/dom/ContainerNode.cpp
WebCore/dom/EventContext.cpp [new file with mode: 0644]
WebCore/dom/EventContext.h [new file with mode: 0644]
WebCore/dom/Node.cpp
WebCore/dom/Node.h
WebCore/dom/Text.cpp
WebCore/dom/WindowEventContext.cpp [new file with mode: 0644]
WebCore/dom/WindowEventContext.h [new file with mode: 0644]
WebCore/inspector/InspectorDOMAgent.cpp
WebCore/inspector/InspectorInstrumentation.cpp
WebCore/inspector/InspectorInstrumentation.h
WebCore/page/EventHandler.cpp
WebCore/rendering/ShadowElement.h
WebCore/svg/SVGElement.cpp
WebCore/svg/SVGElement.h

index 747198a..78366df 100644 (file)
@@ -1,3 +1,19 @@
+2010-11-03  Dimitri Glazkov  <dglazkov@chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Implement shadow DOM-aware event targeting and introduce EventContext to track the context of each event dispatch.
+        https://bugs.webkit.org/show_bug.cgi?id=46015
+
+        Tuned shadow-boundary-crossing.html to better reflect its point: the event should indeed fire (it used to be swallowed),
+        but its target should be a non-shadow node.
+
+        Tweaked audio-delete-while-slider-thumb-clicked.html to actually click on
+        the scrubber thumb (it was off by 2 pixels).
+
+        * fast/events/shadow-boundary-crossing.html: Modified the test.
+        * media/audio-delete-while-slider-thumb-clicked.html : Ditto.
+
 2010-11-03  Nikolas Zimmermann  <nzimmermann@rim.com>
 
         Reviewed by Andreas Kling.
index 623e067..e002333 100644 (file)
@@ -2,11 +2,12 @@
 <head>
     <title></title>
     <script type="text/javascript">
-        var fired = false;
+        var success;
+        var target;
 
         function selectStart(event)
         {
-            fired = true;
+            success = event.target == target;
         }
 
         function test()
@@ -15,7 +16,7 @@
                 return;
             layoutTestController.dumpAsText();
 
-            var target = document.getElementById("target");
+            target = document.getElementById("target");
             var x = target.offsetLeft + target.offsetWidth / 2;
             var y = target.offsetTop + target.offsetHeight / 2;
 
@@ -23,7 +24,7 @@
             eventSender.mouseDown();
             eventSender.mouseUp();
 
-            document.getElementById("result").innerText = fired ? "FAIL" : "PASS";
+            document.getElementById("result").innerText = !success ? "FAIL" : "PASS";
         }
 
         addEventListener("selectstart", selectStart, true);
index c5a16a8..8d25e8a 100644 (file)
 
                 var audio = document.getElementById('audio');
 
-                var middle = audio.offsetLeft + (audio.offsetWidth / 2);
-                var bottom = audio.offsetTop + audio.offsetHeight;
+                var center = audio.offsetLeft + (audio.offsetWidth / 2);
+                var middle = audio.offsetTop + (audio.offsetHeight / 2);
                 
-                var x = middle + 16 + 16 + 8;
-                var y = bottom - 8;
+                var x = center + 16 + 16 + 8;
+                var y = middle;
 
                 // drag slider, leave the mouse down
                 log("clicking in controller");
index ea0c29e..ee754ed 100644 (file)
@@ -132,6 +132,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
        dom/EntityReference.cpp \
        dom/ErrorEvent.cpp \
        dom/Event.cpp \
+       dom/EventContext.cpp \
        dom/EventNames.cpp \
        dom/EventTarget.cpp \
        dom/ExceptionBase.cpp \
@@ -192,6 +193,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
        dom/WebKitAnimationEvent.cpp \
        dom/WebKitTransitionEvent.cpp \
        dom/WheelEvent.cpp \
+       dom/WindowEventContext.cpp \
        dom/XMLDocumentParser.cpp \
        dom/XMLDocumentParserLibxml2.cpp \
        dom/XMLDocumentParserScope.cpp \
index bba7a33..79fb9a6 100644 (file)
@@ -824,6 +824,7 @@ SET(WebCore_SOURCES
     dom/EntityReference.cpp
     dom/ErrorEvent.cpp
     dom/Event.cpp
+    dom/EventContext.cpp
     dom/EventNames.cpp
     dom/EventTarget.cpp
     dom/ExceptionBase.cpp
@@ -881,6 +882,7 @@ SET(WebCore_SOURCES
     dom/WebKitAnimationEvent.cpp
     dom/WebKitTransitionEvent.cpp
     dom/WheelEvent.cpp
+    dom/WindowEventContext.cpp
     dom/XMLDocumentParser.cpp
     dom/XMLDocumentParserLibxml2.cpp
     dom/XMLDocumentParserScope.cpp
index 7b07a41..5bfabcd 100644 (file)
@@ -1,3 +1,52 @@
+2010-11-03  Dimitri Glazkov  <dglazkov@chromium.org>
+
+        Reviewed by Darin Adler.
+
+        Implement shadow DOM-aware event targeting and introduce EventContext to track the context of each event dispatch.
+        https://bugs.webkit.org/show_bug.cgi?id=46015
+
+        This patch adds the notion of EventContext (and a very similar-acting WindowEventContext, specifically
+        for DOMWindow), an abstraction that carries information around dispatching an event for any given Node.
+
+        This abstraction is necessary to ensure that events, fired from shadow DOM nodes are properly retargeted to
+        appear as if they are coming from their host, thus never exposing the shadow DOM nodes to the world outside.
+
+        * Android.mk: Added EventContext, WindowEventContext files.
+        * CMakeLists.txt: Ditto.
+        * GNUmakefile.am: Ditto.
+        * WebCore.gypi: Ditto.
+        * WebCore.pro: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * WebCore.vcproj/WebCore.vcproj: Ditto.
+        * dom/ContainerNode.cpp:
+        (WebCore::notifyChildInserted): Changed to be shadow DOM-aware.
+        * dom/EventContext.cpp: Added.
+        * dom/EventContext.h: Added.
+        * dom/Node.cpp:
+        (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): Changed to be shadow DOM-aware.
+        (WebCore::Node::createRendererIfNeeded): Ditto.
+        (WebCore::Node::parentOrHostNode): Added new helper method.
+        (WebCore::Node::enclosingLinkEventParentOrSelf): Changed to be shadow DOM-aware.
+        (WebCore::eventTargetRespectingSVGTargetRules): Collapsed two helper methods into one.
+        (WebCore::Node::eventAncestors): Refactored to collect a vector of EventContexts.
+        (WebCore::Node::topEventContext): Added.
+        (WebCore::eventHasListeners): Changed to use EventContexts.
+        (WebCore::Node::dispatchGenericEvent): Ditto.
+        * dom/Node.h: Removed eventParentNode that's no longer needed, added parentOrHostNode decl,
+            and changed signature of eventAncestors to use EventContexts.
+        * dom/Text.cpp:
+        (WebCore::Text::createRenderer): Changed to be shadow DOM-aware.
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::InspectorDOMAgent::getEventListenersForNode): Changed to use EventContexts.
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::updateMouseEventTargetNode): Removed code that's no longer necessary.
+        * rendering/ShadowElement.h: Made m_shadowParent a RefPtr to avoid stale references when parent
+        is deleted.
+        * svg/SVGElement.cpp: Removed eventParentNode that's no longer needed.
+        * svg/SVGElement.h: Ditto.
+        * dom/WindowEventContext.cpp: Added.
+        * dom/WindowEventContext.h: Added.
+
 2010-11-02  Mikhail Naganov  <mnaganov@chromium.org>
 
         Reviewed by Pavel Feldman.
index c4f927f..d4681eb 100644 (file)
@@ -1132,8 +1132,10 @@ webcore_sources += \
        WebCore/dom/ErrorEvent.cpp \
        WebCore/dom/ErrorEvent.h \
        WebCore/dom/Event.cpp \
-       WebCore/dom/EventException.h \
        WebCore/dom/Event.h \
+       WebCore/dom/EventContext.cpp \
+       WebCore/dom/EventContext.h \
+       WebCore/dom/EventException.h \
        WebCore/dom/EventListener.h \
        WebCore/dom/EventNames.cpp \
        WebCore/dom/EventNames.h \
@@ -1261,6 +1263,8 @@ webcore_sources += \
        WebCore/dom/WebKitTransitionEvent.h \
        WebCore/dom/WheelEvent.cpp \
        WebCore/dom/WheelEvent.h \
+       WebCore/dom/WindowEventContext.cpp \
+       WebCore/dom/WindowEventContext.h \
        WebCore/dom/XMLDocumentParser.cpp \
        WebCore/dom/XMLDocumentParser.h \
        WebCore/dom/XMLDocumentParserLibxml2.cpp \
index d2c8695..f09575a 100644 (file)
             'dom/ErrorEvent.h',
             'dom/Event.cpp',
             'dom/Event.h',
+            'dom/EventContext.cpp',
+            'dom/EventContext.h',
             'dom/EventException.h',
             'dom/EventListener.h',
             'dom/EventNames.cpp',
             'dom/WebKitTransitionEvent.h',
             'dom/WheelEvent.cpp',
             'dom/WheelEvent.h',
+            'dom/WindowEventContext.cpp',
+            'dom/WindowEventContext.h',
             'dom/XMLDocumentParser.cpp',
             'dom/XMLDocumentParser.h',
             'dom/XMLDocumentParserLibxml2.cpp',
index 6f5f86a..4a7613d 100644 (file)
@@ -713,6 +713,7 @@ SOURCES += \
     dom/EntityReference.cpp \
     dom/ErrorEvent.cpp \
     dom/Event.cpp \
+    dom/EventContext.cpp \
     dom/EventNames.cpp \
     dom/EventTarget.cpp \
     dom/ExceptionBase.cpp \
@@ -773,6 +774,7 @@ SOURCES += \
     dom/WebKitAnimationEvent.cpp \
     dom/WebKitTransitionEvent.cpp \
     dom/WheelEvent.cpp \
+    dom/WindowEventContext.cpp \
     dom/XMLDocumentParser.cpp \
     dom/XMLDocumentParserQt.cpp \
     dom/default/PlatformMessagePortChannel.cpp \
index d6928d8..95fbf4d 100644 (file)
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\dom\EventContext.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug_Internal|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug_Cairo|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release_Cairo|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug_All|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\dom\EventContext.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\dom\EventException.h"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath="..\dom\WindowEventContext.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug_Internal|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug_Cairo|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release_Cairo|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug_All|Win32"\r
+                                       ExcludedFromBuild="true"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\dom\WindowEventContext.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\dom\XMLDocumentParser.cpp"\r
                                >\r
                                <FileConfiguration\r
index 3a5c495..4659d17 100644 (file)
                410B7E721045FAB000D8224F /* JSMessageEventCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 410B7E711045FAB000D8224F /* JSMessageEventCustom.cpp */; };
                411046410FA222A600BA436A /* ScriptEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 4110463F0FA222A600BA436A /* ScriptEventListener.h */; };
                411046420FA222A600BA436A /* ScriptEventListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 411046400FA222A600BA436A /* ScriptEventListener.cpp */; };
+               4123E569127B3041000FEEA7 /* WindowEventContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4123E567127B3041000FEEA7 /* WindowEventContext.h */; };
+               4123E56A127B3041000FEEA7 /* WindowEventContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4123E568127B3041000FEEA7 /* WindowEventContext.cpp */; };
                4127D5370F8AAB1D00E424F5 /* ScriptState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4127D5360F8AAB1D00E424F5 /* ScriptState.cpp */; };
+               4138D3351244054800323D33 /* EventContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4138D3331244054800323D33 /* EventContext.h */; };
+               4138D3361244054800323D33 /* EventContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4138D3341244054800323D33 /* EventContext.cpp */; };
                4162A450101145AE00DFF3ED /* DedicatedWorkerContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4162A44D101145AE00DFF3ED /* DedicatedWorkerContext.cpp */; };
                4162A451101145AE00DFF3ED /* DedicatedWorkerContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4162A44E101145AE00DFF3ED /* DedicatedWorkerContext.h */; };
                4162A454101145E300DFF3ED /* JSDedicatedWorkerContextCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4162A453101145E300DFF3ED /* JSDedicatedWorkerContextCustom.cpp */; };
                410B7E711045FAB000D8224F /* JSMessageEventCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSMessageEventCustom.cpp; sourceTree = "<group>"; };
                4110463F0FA222A600BA436A /* ScriptEventListener.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptEventListener.h; sourceTree = "<group>"; };
                411046400FA222A600BA436A /* ScriptEventListener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptEventListener.cpp; sourceTree = "<group>"; };
+               4123E567127B3041000FEEA7 /* WindowEventContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WindowEventContext.h; sourceTree = "<group>"; };
+               4123E568127B3041000FEEA7 /* WindowEventContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WindowEventContext.cpp; sourceTree = "<group>"; };
                4127D5360F8AAB1D00E424F5 /* ScriptState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptState.cpp; sourceTree = "<group>"; };
+               4138D3331244054800323D33 /* EventContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventContext.h; sourceTree = "<group>"; };
+               4138D3341244054800323D33 /* EventContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventContext.cpp; sourceTree = "<group>"; };
                4162A44D101145AE00DFF3ED /* DedicatedWorkerContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DedicatedWorkerContext.cpp; path = workers/DedicatedWorkerContext.cpp; sourceTree = "<group>"; };
                4162A44E101145AE00DFF3ED /* DedicatedWorkerContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DedicatedWorkerContext.h; path = workers/DedicatedWorkerContext.h; sourceTree = "<group>"; };
                4162A44F101145AE00DFF3ED /* DedicatedWorkerContext.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = DedicatedWorkerContext.idl; path = workers/DedicatedWorkerContext.idl; sourceTree = "<group>"; };
                                85031B2B0A44EFC700F992E0 /* Event.cpp */,
                                85031B2C0A44EFC700F992E0 /* Event.h */,
                                14E836D209F8512000B85AE4 /* Event.idl */,
+                               4138D3341244054800323D33 /* EventContext.cpp */,
+                               4138D3331244054800323D33 /* EventContext.h */,
                                BC60D9090D2A17CE00B9918F /* EventException.h */,
                                BC60D90A0D2A17CE00B9918F /* EventException.idl */,
                                935FBC4409BA00B900E230B1 /* EventListener.h */,
                                85031B3A0A44EFC700F992E0 /* WheelEvent.cpp */,
                                85031B3B0A44EFC700F992E0 /* WheelEvent.h */,
                                93EEC1F709C2877700C515D1 /* WheelEvent.idl */,
+                               4123E568127B3041000FEEA7 /* WindowEventContext.cpp */,
+                               4123E567127B3041000FEEA7 /* WindowEventContext.h */,
                                F523D30902DE4476018635CA /* XMLDocumentParser.cpp */,
                                F523D30A02DE4476018635CA /* XMLDocumentParser.h */,
                                54C50F7A0E801DF3009832A0 /* XMLDocumentParserLibxml2.cpp */,
                                89878560122CA064003AABDA /* ErrorCallback.h in Headers */,
                                2ECF7AE210162B5800427DE7 /* ErrorEvent.h in Headers */,
                                85031B420A44EFC700F992E0 /* Event.h in Headers */,
+                               4138D3351244054800323D33 /* EventContext.h in Headers */,
                                BC60D90C0D2A17CE00B9918F /* EventException.h in Headers */,
                                93C09A530B064DB3005ABD4D /* EventHandler.h in Headers */,
                                935FBC4509BA00B900E230B1 /* EventListener.h in Headers */,
                                85031B510A44EFC700F992E0 /* WheelEvent.h in Headers */,
                                9380F47409A11AB4001FDB34 /* Widget.h in Headers */,
                                939B02EF0EA2DBC400C54570 /* WidthIterator.h in Headers */,
+                               4123E569127B3041000FEEA7 /* WindowEventContext.h in Headers */,
                                BC8243E90D0CFD7500460C8F /* WindowFeatures.h in Headers */,
                                E1E1BF00115FF6FB006F52CA /* WindowsKeyboardCodes.h in Headers */,
                                08203AA00ED8C35300B8B61A /* WMLAccessElement.h in Headers */,
                                893C480C1248BD3A002B3D86 /* EntrySync.cpp in Sources */,
                                2ECF7AE110162B5800427DE7 /* ErrorEvent.cpp in Sources */,
                                85031B410A44EFC700F992E0 /* Event.cpp in Sources */,
+                               4138D3361244054800323D33 /* EventContext.cpp in Sources */,
                                93C09A810B064F00005ABD4D /* EventHandler.cpp in Sources */,
                                93C09A7F0B064EEF005ABD4D /* EventHandlerMac.mm in Sources */,
                                1CA19E050DC255950065A994 /* EventLoopMac.mm in Sources */,
                                9380F47309A11AB4001FDB34 /* Widget.cpp in Sources */,
                                9380F47809A11ACC001FDB34 /* WidgetMac.mm in Sources */,
                                939B02EE0EA2DBC400C54570 /* WidthIterator.cpp in Sources */,
+                               4123E56A127B3041000FEEA7 /* WindowEventContext.cpp in Sources */,
                                BC8243E80D0CFD7500460C8F /* WindowFeatures.cpp in Sources */,
                                08203A9F0ED8C35300B8B61A /* WMLAccessElement.cpp in Sources */,
                                088C97510ECB6E28000534BA /* WMLAElement.cpp in Sources */,
index fc33519..b4bdb7f 100644 (file)
@@ -1005,7 +1005,8 @@ static void notifyChildInserted(Node* child)
     RefPtr<Node> c = child;
     RefPtr<Document> document = child->document();
 
-    if (c->parentNode() && c->parentNode()->inDocument())
+    Node* parentOrHostNode = c->parentOrHostNode();
+    if (parentOrHostNode && parentOrHostNode->inDocument())
         c->insertedIntoDocument();
     else
         c->insertedIntoTree(true);
diff --git a/WebCore/dom/EventContext.cpp b/WebCore/dom/EventContext.cpp
new file mode 100644 (file)
index 0000000..2a5c521
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+#include "config.h"
+#include "EventContext.h"
+
+#include "DOMWindow.h"
+#include "Document.h"
+#include "Event.h"
+#include "Node.h"
+
+namespace WebCore {
+
+EventContext::EventContext(PassRefPtr<Node> node, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target)
+    : m_node(node)
+    , m_currentTarget(currentTarget)
+    , m_target(target)
+{
+}
+
+void EventContext::handleLocalEvents(Event* event) const
+{
+    event->setTarget(m_target.get());
+    event->setCurrentTarget(m_currentTarget.get());
+    m_node->handleLocalEvents(event);
+}
+
+}
diff --git a/WebCore/dom/EventContext.h b/WebCore/dom/EventContext.h
new file mode 100644 (file)
index 0000000..9bab9d4
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+#ifndef EventContext_h
+#define EventContext_h
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class EventTarget;
+class Event;
+class Node;
+
+class EventContext {
+public:
+    // FIXME: Use ContainerNode instead of Node.
+    EventContext(PassRefPtr<Node>, PassRefPtr<EventTarget> currentTarget, PassRefPtr<EventTarget> target);
+
+    Node* node() const;
+    EventTarget* target() const;
+    void handleLocalEvents(Event*) const;
+
+private:
+    RefPtr<Node> m_node;
+    RefPtr<EventTarget> m_currentTarget;
+    RefPtr<EventTarget> m_target;
+};
+
+inline Node* EventContext::node() const
+{
+    return m_node.get();
+}
+
+inline EventTarget* EventContext::target() const
+{
+    return m_target.get();
+}
+
+}
+
+#endif // EventContext_h
index e45baa4..ff7856a 100644 (file)
@@ -45,6 +45,7 @@
 #include "DynamicNodeList.h"
 #include "Element.h"
 #include "Event.h"
+#include "EventContext.h"
 #include "EventException.h"
 #include "EventHandler.h"
 #include "EventListener.h"
@@ -80,6 +81,7 @@
 #include "WebKitAnimationEvent.h"
 #include "WebKitTransitionEvent.h"
 #include "WheelEvent.h"
+#include "WindowEventContext.h"
 #include "XMLNames.h"
 #include "htmlediting.h"
 #include <wtf/HashSet.h>
@@ -734,9 +736,9 @@ inline void Node::setStyleChange(StyleChangeType changeType)
 
 inline void Node::markAncestorsWithChildNeedsStyleRecalc()
 {
-    for (ContainerNode* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
+    for (ContainerNode* p = parentOrHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrHostNode())
         p->setChildNeedsStyleRecalc();
-    
+
     if (document()->childNeedsStyleRecalc())
         document()->scheduleStyleRecalc();
 }
@@ -1321,7 +1323,7 @@ void Node::createRendererIfNeeded()
 
     ASSERT(!renderer());
     
-    ContainerNode* parent = parentNode();    
+    ContainerNode* parent = parentOrHostNode();
     ASSERT(parent);
     
     RenderObject* parentRenderer = parent->renderer();
@@ -2239,14 +2241,9 @@ void Node::getSubresourceURLs(ListHashSet<KURL>& urls) const
     addSubresourceAttributeURLs(urls);
 }
 
-ContainerNode* Node::eventParentNode()
-{
-    return parentNode();
-}
-
 Node* Node::enclosingLinkEventParentOrSelf()
 {
-    for (Node* node = this; node; node = node->eventParentNode()) {
+    for (Node* node = this; node; node = node->parentOrHostNode()) {
         // For imagemaps, the enclosing link node is the associated area element not the image itself.
         // So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true
         // for them.
@@ -2484,12 +2481,13 @@ void Node::handleLocalEvents(Event* event)
     fireEventListeners(event);
 }
 
-#if ENABLE(SVG)
-static inline SVGElementInstance* eventTargetAsSVGElementInstance(Node* referenceNode)
+static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNode)
 {
     ASSERT(referenceNode);
+
+#if ENABLE(SVG)
     if (!referenceNode->isSVGElement())
-        return 0;
+        return referenceNode;
 
     // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
     // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects
@@ -2503,36 +2501,39 @@ static inline SVGElementInstance* eventTargetAsSVGElementInstance(Node* referenc
         if (SVGElementInstance* instance = static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode))
             return instance;
     }
-
-    return 0;
-}
-#endif
-
-static inline EventTarget* eventTargetRespectingSVGTargetRules(Node* referenceNode)
-{
-    ASSERT(referenceNode);
-
-#if ENABLE(SVG)
-    if (SVGElementInstance* instance = eventTargetAsSVGElementInstance(referenceNode)) {
-        ASSERT(instance->shadowTreeElement() == referenceNode);
-        return instance;
-    }
 #endif
 
     return referenceNode;
 }
 
-void Node::eventAncestors(Vector<RefPtr<ContainerNode> > &ancestors)
+void Node::getEventAncestors(Vector<EventContext>& ancestors, EventTarget* originalTarget)
 {
-    if (inDocument()) {
-        for (ContainerNode* ancestor = eventParentNode(); ancestor; ancestor = ancestor->eventParentNode()) {
+    if (!inDocument())
+        return;
+
+    EventTarget* target = originalTarget;
+    Node* ancestor = this;
+    bool shouldSkipNextAncestor = false;
+    while (true) {
+        if (ancestor->isShadowNode()) {
+            ancestor = ancestor->shadowParentNode();
+            if (!shouldSkipNextAncestor)
+                target = ancestor;
+        } else
+            ancestor = ancestor->parentNode();
+
+        if (!ancestor)
+            return;
+
 #if ENABLE(SVG)
-            // Skip <use> shadow tree elements.
-            if (ancestor->isSVGElement() && ancestor->isShadowNode())
-                continue;
+        // Skip SVGShadowTreeRootElement.
+        shouldSkipNextAncestor = ancestor->isSVGElement() && ancestor->isShadowNode();
+        if (shouldSkipNextAncestor)
+            continue;
 #endif
-            ancestors.append(ancestor);
-        }
+        // FIXME: Unroll the extra loop inside eventTargetRespectingSVGTargetRules into this loop.
+        ancestors.append(EventContext(ancestor, eventTargetRespectingSVGTargetRules(ancestor), target));
+
     }
 }
 
@@ -2547,6 +2548,11 @@ bool Node::dispatchEvent(PassRefPtr<Event> prpEvent)
     return dispatchGenericEvent(event.release());
 }
 
+static const EventContext* topEventContext(const Vector<EventContext>& ancestors)
+{
+    return ancestors.isEmpty() ? 0 : &(ancestors.last());
+}
+
 bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
 {
     RefPtr<Event> event(prpEvent);
@@ -2559,20 +2565,13 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
     // If the node is not in a document just send the event to it.
     // Be sure to ref all of nodes since event handlers could result in the last reference going away.
     RefPtr<Node> thisNode(this);
-    Vector<RefPtr<ContainerNode> > ancestors;
-    eventAncestors(ancestors);
+    RefPtr<EventTarget> originalTarget = event->target();
+    Vector<EventContext> ancestors;
+    getEventAncestors(ancestors, originalTarget.get());
 
-    // Set up a pointer to indicate whether / where to dispatch window events.
-    // We don't dispatch load events to the window. That quirk was originally
-    // added because Mozilla doesn't propagate load events to the window object.
-    DOMWindow* targetForWindowEvents = 0;
-    if (event->type() != eventNames().loadEvent) {
-        Node* topLevelContainer = ancestors.isEmpty() ? this : ancestors.last().get();
-        if (topLevelContainer->isDocumentNode())
-            targetForWindowEvents = static_cast<Document*>(topLevelContainer)->domWindow();
-    }
+    WindowEventContext windowContext(event.get(), this, topEventContext(ancestors));
 
-    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(document(), *event, targetForWindowEvents, this, ancestors);
+    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(document(), *event, windowContext.window(), this, ancestors);
 
     // Give the target node a chance to do some work before DOM event handlers get a crack.
     void* data = preDispatchEventHandler(event.get());
@@ -2582,22 +2581,17 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
     // Trigger capturing event handlers, starting at the top and working our way down.
     event->setEventPhase(Event::CAPTURING_PHASE);
 
-    if (targetForWindowEvents) {
-        event->setCurrentTarget(targetForWindowEvents);
-        targetForWindowEvents->fireEventListeners(event.get());
-        if (event->propagationStopped())
-            goto doneDispatching;
-    }
+    if (windowContext.handleLocalEvents(event.get()) && event->propagationStopped())
+        goto doneDispatching;
+
     for (size_t i = ancestors.size(); i; --i) {
-        ContainerNode* ancestor = ancestors[i - 1].get();
-        event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
-        ancestor->handleLocalEvents(event.get());
+        ancestors[i - 1].handleLocalEvents(event.get());
         if (event->propagationStopped())
             goto doneDispatching;
     }
 
     event->setEventPhase(Event::AT_TARGET);
-
+    event->setTarget(originalTarget.get());
     event->setCurrentTarget(eventTargetRespectingSVGTargetRules(this));
     handleLocalEvents(event.get());
     if (event->propagationStopped())
@@ -2609,21 +2603,15 @@ bool Node::dispatchGenericEvent(PassRefPtr<Event> prpEvent)
 
         size_t size = ancestors.size();
         for (size_t i = 0; i < size; ++i) {
-            ContainerNode* ancestor = ancestors[i].get();
-            event->setCurrentTarget(eventTargetRespectingSVGTargetRules(ancestor));
-            ancestor->handleLocalEvents(event.get());
-            if (event->propagationStopped() || event->cancelBubble())
-                goto doneDispatching;
-        }
-        if (targetForWindowEvents) {
-            event->setCurrentTarget(targetForWindowEvents);
-            targetForWindowEvents->fireEventListeners(event.get());
+            ancestors[i].handleLocalEvents(event.get());
             if (event->propagationStopped() || event->cancelBubble())
                 goto doneDispatching;
         }
+        windowContext.handleLocalEvents(event.get());
     }
 
 doneDispatching:
+    event->setTarget(originalTarget.get());
     event->setCurrentTarget(0);
     event->setEventPhase(0);
 
@@ -2644,8 +2632,7 @@ doneDispatching:
         if (event->bubbles()) {
             size_t size = ancestors.size();
             for (size_t i = 0; i < size; ++i) {
-                ContainerNode* ancestor = ancestors[i].get();
-                ancestor->defaultEventHandler(event.get());
+                ancestors[i].node()->defaultEventHandler(event.get());
                 ASSERT(!event->defaultPrevented());
                 if (event->defaultHandled())
                     goto doneWithDefault;
index 3c6c199..dad2585 100644 (file)
@@ -49,6 +49,7 @@ class Document;
 class DynamicNodeList;
 class Element;
 class Event;
+class EventContext;
 class EventListener;
 class FloatPoint;
 class Frame;
@@ -204,16 +205,14 @@ public:
     Node* shadowAncestorNode();
     Node* shadowTreeRootNode();
     bool isInShadowTree();
-
-    // The node's parent for the purpose of event capture and bubbling.
-    virtual ContainerNode* eventParentNode();
+    // Node's parent or shadow tree host.
+    ContainerNode* parentOrHostNode();
 
     // Returns the enclosing event parent node (or self) that, when clicked, would trigger a navigation.
     Node* enclosingLinkEventParentOrSelf();
 
     // Node ancestors when concerned about event flow.
-    // FIXME: Should be named getEventAncestors.
-    void eventAncestors(Vector<RefPtr<ContainerNode> > &ancestors);
+    void getEventAncestors(Vector<EventContext>& ancestors, EventTarget*);
 
     bool isBlockFlow() const;
     bool isBlockFlowOrBlockTable() const;
@@ -693,6 +692,13 @@ inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
         urls.add(url);
 }
 
+inline ContainerNode* Node::parentOrHostNode()
+{
+    if (ContainerNode* parent = parentNode())
+        return parent;
+    return shadowParentNode();
+}
+
 } //namespace
 
 #ifndef NDEBUG
index 6271f11..f9a4f04 100644 (file)
@@ -239,10 +239,11 @@ bool Text::rendererIsNeeded(RenderStyle *style)
 
 RenderObject* Text::createRenderer(RenderArena* arena, RenderStyle*)
 {
+    Node* parentOrHost = parentOrHostNode();
 #if ENABLE(SVG)
-    if (parentNode()->isSVGElement()
+    if (parentOrHost->isSVGElement()
 #if ENABLE(SVG_FOREIGN_OBJECT)
-        && !parentNode()->hasTagName(SVGNames::foreignObjectTag)
+        && !parentOrHost->hasTagName(SVGNames::foreignObjectTag)
 #endif
     )
         return new (arena) RenderSVGInlineText(this, dataImpl());
diff --git a/WebCore/dom/WindowEventContext.cpp b/WebCore/dom/WindowEventContext.cpp
new file mode 100644 (file)
index 0000000..90f4a36
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+#include "config.h"
+#include "WindowEventContext.h"
+
+#include "DOMWindow.h"
+#include "Document.h"
+#include "Event.h"
+#include "EventContext.h"
+#include "Node.h"
+
+namespace WebCore {
+
+WindowEventContext::WindowEventContext(Event* event, PassRefPtr<Node> node, const EventContext* topEventContext)
+{
+    // We don't dispatch load events to the window. That quirk was originally
+    // added because Mozilla doesn't propagate load events to the window object.
+    if (event->type() == eventNames().loadEvent)
+        return;
+
+    Node* topLevelContainer = topEventContext ? topEventContext->node() : node.get();
+    if (!topLevelContainer->isDocumentNode())
+        return;
+
+    m_window = static_cast<Document*>(topLevelContainer)->domWindow();
+    m_target = topEventContext ? topEventContext->target() : node.get();
+}
+
+bool WindowEventContext::handleLocalEvents(Event* event)
+{
+    if (!m_window)
+        return false;
+
+    event->setTarget(target());
+    event->setCurrentTarget(window());
+    m_window->fireEventListeners(event);
+    return true;
+}
+
+}
diff --git a/WebCore/dom/WindowEventContext.h b/WebCore/dom/WindowEventContext.h
new file mode 100644 (file)
index 0000000..a19e04d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ *
+ */
+
+#ifndef WindowEventContext_h
+#define WindowEventContext_h
+
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class DOMWindow;
+class EventTarget;
+class EventContext;
+class Event;
+class Node;
+
+class WindowEventContext {
+public:
+    WindowEventContext(Event*, PassRefPtr<Node>, const EventContext*);
+
+    DOMWindow* window() const;
+    EventTarget* target() const;
+    bool handleLocalEvents(Event* event);
+
+private:
+    RefPtr<DOMWindow> m_window;
+    RefPtr<EventTarget> m_target;
+};
+
+inline DOMWindow* WindowEventContext::window() const
+{
+    return m_window.get();
+}
+
+inline EventTarget* WindowEventContext::target() const
+{
+    return m_target.get();
+}
+
+}
+
+#endif // WindowEventContext_h
index cfb55fc..0168975 100644 (file)
@@ -51,6 +51,7 @@
 #include "Document.h"
 #include "DocumentType.h"
 #include "Event.h"
+#include "EventContext.h"
 #include "EventListener.h"
 #include "EventNames.h"
 #include "EventTarget.h"
@@ -607,13 +608,13 @@ void InspectorDOMAgent::getEventListenersForNode(long nodeId, long* outNodeId, R
         return;
 
     // The Node's Event Ancestors (not including self)
-    Vector<RefPtr<ContainerNode> > ancestors;
-    node->eventAncestors(ancestors);
+    Vector<EventContext> ancestors;
+    node->getEventAncestors(ancestors, node);
 
     // Nodes and their Listeners for the concerned event types (order is top to bottom)
     Vector<EventListenerInfo> eventInformation;
     for (size_t i = ancestors.size(); i; --i) {
-        ContainerNode* ancestor = ancestors[i - 1].get();
+        Node* ancestor = ancestors[i - 1].node();
         for (size_t j = 0; j < eventTypesLength; ++j) {
             AtomicString& type = eventTypes[j];
             if (ancestor->hasEventListeners(type))
index 94202c1..cf41527 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "DOMWindow.h"
 #include "Event.h"
+#include "EventContext.h"
 #include "InspectorController.h"
 #include "InspectorDOMAgent.h"
 #include "InspectorDebuggerAgent.h"
@@ -53,7 +54,7 @@ static const char* const timerFiredEventName = "timerFired";
 
 int InspectorInstrumentation::s_frontendCounter = 0;
 
-static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors)
+static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)
 {
     if (window && window->hasEventListeners(eventType))
         return true;
@@ -62,7 +63,7 @@ static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window,
         return true;
 
     for (size_t i = 0; i < ancestors.size(); i++) {
-        ContainerNode* ancestor = ancestors[i].get();
+        Node* ancestor = ancestors[i].node();
         if (ancestor->hasEventListeners(eventType))
             return true;
     }
@@ -139,7 +140,6 @@ void InspectorInstrumentation::characterDataModifiedImpl(InspectorController* in
         domAgent->characterDataModified(characterData);
 }
 
-
 void InspectorInstrumentation::willSendXMLHttpRequestImpl(InspectorController* inspectorController, const String& url)
 {
 #if ENABLE(JAVASCRIPT_DEBUGGER)
@@ -213,7 +213,7 @@ void InspectorInstrumentation::didChangeXHRReadyStateImpl(const InspectorInstrum
         timelineAgent->didChangeXHRReadyState();
 }
 
-InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InspectorController* inspectorController, const Event& event, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors)
+InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEventImpl(InspectorController* inspectorController, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)
 {
     pauseOnNativeEventIfNeeded(inspectorController, listenerEventCategoryType, event.type(), false);
 
index 1b62ecb..7f241c4 100644 (file)
@@ -40,6 +40,7 @@ namespace WebCore {
 
 class CharacterData;
 class Element;
+class EventContext;
 class InspectorController;
 class InspectorTimelineAgent;
 class KURL;
@@ -73,7 +74,7 @@ public:
     static void didCallFunction(const InspectorInstrumentationCookie&);
     static InspectorInstrumentationCookie willChangeXHRReadyState(ScriptExecutionContext*, XMLHttpRequest* request);
     static void didChangeXHRReadyState(const InspectorInstrumentationCookie&);
-    static InspectorInstrumentationCookie willDispatchEvent(Document*, const Event& event, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors);
+    static InspectorInstrumentationCookie willDispatchEvent(Document*, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors);
     static void didDispatchEvent(const InspectorInstrumentationCookie&);
     static InspectorInstrumentationCookie willDispatchEventOnWindow(Frame*, const Event& event, DOMWindow* window);
     static void didDispatchEventOnWindow(const InspectorInstrumentationCookie&);
@@ -130,7 +131,7 @@ private:
     static void didCallFunctionImpl(const InspectorInstrumentationCookie&);
     static InspectorInstrumentationCookie willChangeXHRReadyStateImpl(InspectorController*, XMLHttpRequest* request);
     static void didChangeXHRReadyStateImpl(const InspectorInstrumentationCookie&);
-    static InspectorInstrumentationCookie willDispatchEventImpl(InspectorController*, const Event& event, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors);
+    static InspectorInstrumentationCookie willDispatchEventImpl(InspectorController*, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors);
     static void didDispatchEventImpl(const InspectorInstrumentationCookie&);
     static InspectorInstrumentationCookie willDispatchEventOnWindowImpl(InspectorController*, const Event& event, DOMWindow* window);
     static void didDispatchEventOnWindowImpl(const InspectorInstrumentationCookie&);
@@ -225,7 +226,6 @@ inline void InspectorInstrumentation::characterDataModified(Document* document,
 #endif
 }
 
-
 inline void InspectorInstrumentation::willSendXMLHttpRequest(ScriptExecutionContext* context, const String& url)
 {
 #if ENABLE(INSPECTOR)
@@ -293,7 +293,7 @@ inline void InspectorInstrumentation::didChangeXHRReadyState(const InspectorInst
 #endif
 }
 
-inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const Vector<RefPtr<ContainerNode> >& ancestors)
+inline InspectorInstrumentationCookie InspectorInstrumentation::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const Vector<EventContext>& ancestors)
 {
 #if ENABLE(INSPECTOR)
     if (InspectorController* inspectorController = inspectorControllerForDocument(document))
index 2970259..71ca9c8 100644 (file)
@@ -1766,8 +1766,6 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
         // If the target node is a text node, dispatch on the parent node - rdar://4196646
         if (result && result->isTextNode())
             result = result->parentNode();
-        if (result)
-            result = result->shadowAncestorNode();
     }
     m_nodeUnderMouse = result;
 #if ENABLE(SVG)
index 04db62b..f5668ef 100644 (file)
@@ -43,13 +43,13 @@ protected:
     {
     }
 
-    HTMLElement* shadowParent() const { return m_shadowParent; }
+    HTMLElement* shadowParent() const { return m_shadowParent.get(); }
 
 private:
     virtual bool isShadowNode() const { return true; }
-    virtual ContainerNode* shadowParentNode() { return m_shadowParent; }
+    virtual ContainerNode* shadowParentNode() { return m_shadowParent.get(); }
 
-    HTMLElement* m_shadowParent;
+    RefPtr<HTMLElement> m_shadowParent;
 };
 
 class ShadowBlockElement : public ShadowElement<HTMLDivElement> {
index 6c2c4a2..3e9bda0 100644 (file)
@@ -347,13 +347,6 @@ void SVGElement::updateAnimatedSVGAttribute(const QualifiedName& name) const
     clearIsSynchronizingSVGAttributes();
 }
 
-ContainerNode* SVGElement::eventParentNode()
-{
-    if (ContainerNode* shadowParent = shadowParentNode())
-        return shadowParent;
-    return StyledElement::eventParentNode();
-}
-
 }
 
 #endif // ENABLE(SVG)
index 517515f..96e7fd7 100644 (file)
@@ -99,8 +99,6 @@ namespace WebCore {
 
         virtual bool isSupported(StringImpl* feature, StringImpl* version) const;
 
-        virtual ContainerNode* eventParentNode();
-
         virtual bool needsPendingResourceHandling() const { return true; }
         virtual void buildPendingResource() { }