Source/WebCore/ChangeLog

 12013-02-03 Kentaro Hara <haraken@chromium.org>
 2
 3 WebKit's focus events are UIEvents (instead of FocusEvent) and thus don't expose .relatedTarget
 4 https://bugs.webkit.org/show_bug.cgi?id=76216
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Spec: http://www.w3.org/TR/DOM-Level-3-Events/#events-FocusEvent
 9
 10 This patch creates a new FocusEvent class with a relatedTarget attribute.
 11 Now when focusin or focusout events are dispatched, a FocusEvent is created with
 12 the relatedTarget attribute set accordingly.
 13
 14 Test: fast/events/related-target-focusevent.html
 15
 16 * CMakeLists.txt:
 17 * DerivedSources.cpp:
 18 * DerivedSources.make:
 19 * DerivedSources.pri:
 20 * GNUmakefile.list.am:
 21 * Target.pri:
 22 * WebCore.gypi:
 23 * WebCore.xcodeproj/project.pbxproj:
 24 * dom/DOMAllInOne.cpp:
 25 * dom/Event.cpp:
 26 (WebCore::Event::isFocusEvent):
 27 (WebCore):
 28 * dom/Event.h:
 29 (Event):
 30 * dom/EventContext.cpp:
 31 (WebCore::EventContext::handleLocalEvents):
 32 * dom/EventNames.in:
 33 * dom/FocusEvent.h: Added.
 34 (WebCore):
 35 (FocusEvent):
 36 (WebCore::FocusEvent::create):
 37 (WebCore::FocusEvent::relatedTarget):
 38 (WebCore::FocusEvent::setRelatedTarget):
 39 (WebCore::toFocusEvent):
 40 * dom/FocusEvent.idl: Added.
 41 * dom/Node.cpp:
 42 (WebCore::Node::dispatchFocusInEvent):
 43 (WebCore::Node::dispatchFocusOutEvent):
 44
1452013-02-06 Dirk Schulze <dschulze@adobe.com>
246
347 Context's currentPath should check for passed type

Source/WebCore/CMakeLists.txt

@@set(WebCore_IDL_FILES
371371 dom/EventException.idl
372372 dom/Event.idl
373373 dom/EventTarget.idl
 374 dom/FocusEvent.idl
374375 dom/HashChangeEvent.idl
375376 dom/KeyboardEvent.idl
376377 dom/MessageChannel.idl

@@set(WebCore_SOURCES
11861187 dom/EventTarget.cpp
11871188 dom/ExceptionBase.cpp
11881189 dom/ExceptionCodePlaceholder.cpp
 1190 dom/FocusEvent.cpp
11891191 dom/GenericEventQueue.cpp
11901192 dom/GestureEvent.cpp
11911193 dom/IconURL.cpp

Source/WebCore/DerivedSources.cpp

136136#include "JSFileWriterSync.cpp"
137137#include "JSFloat32Array.cpp"
138138#include "JSFloat64Array.cpp"
 139#include "JSFocusEvent.cpp"
139140#include "JSGeolocation.cpp"
140141#include "JSGeoposition.cpp"
141142#include "JSHashChangeEvent.cpp"

Source/WebCore/DerivedSources.make

@@BINDING_IDLS = \
235235 $(WebCore)/dom/EventException.idl \
236236 $(WebCore)/dom/EventListener.idl \
237237 $(WebCore)/dom/EventTarget.idl \
 238 $(WebCore)/dom/FocusEvent.idl \
238239 $(WebCore)/dom/HashChangeEvent.idl \
239240 $(WebCore)/dom/KeyboardEvent.idl \
240241 $(WebCore)/dom/MessageChannel.idl \

Source/WebCore/DerivedSources.pri

@@IDL_BINDINGS += \
248248 $$PWD/dom/EventException.idl \
249249# $$PWD/dom/EventListener.idl \
250250 $$PWD/dom/EventTarget.idl \
 251 $$PWD/dom/FocusEvent.idl \
251252 $$PWD/dom/HashChangeEvent.idl \
252253 $$PWD/dom/KeyboardEvent.idl \
253254 $$PWD/dom/MouseEvent.idl \

Source/WebCore/GNUmakefile.list.am

@@webcore_built_sources += \
286286 DerivedSources/WebCore/JSFloat32Array.h \
287287 DerivedSources/WebCore/JSFloat64Array.cpp \
288288 DerivedSources/WebCore/JSFloat64Array.h \
 289 DerivedSources/WebCore/JSFocusEvent.cpp \
 290 DerivedSources/WebCore/JSFocusEvent.h \
289291 DerivedSources/WebCore/JSGamepad.cpp \
290292 DerivedSources/WebCore/JSGamepad.h \
291293 DerivedSources/WebCore/JSGamepadList.cpp \

@@dom_binding_idls += \
13831385 $(WebCore)/dom/Event.idl \
13841386 $(WebCore)/dom/EventTarget.idl \
13851387 $(WebCore)/dom/EventException.idl \
 1388 $(WebCore)/dom/FocusEvent.idl \
13861389 $(WebCore)/dom/HashChangeEvent.idl \
13871390 $(WebCore)/dom/KeyboardEvent.idl \
13881391 $(WebCore)/dom/MessageChannel.idl \

@@webcore_sources += \
28652868 Source/WebCore/dom/ExceptionCode.h \
28662869 Source/WebCore/dom/ExceptionCodePlaceholder.cpp \
28672870 Source/WebCore/dom/ExceptionCodePlaceholder.h \
 2871 Source/WebCore/dom/FocusEvent.cpp \
 2872 Source/WebCore/dom/FocusEvent.h \
28682873 Source/WebCore/dom/FragmentScriptingPermission.h \
28692874 Source/WebCore/dom/GestureEvent.cpp \
28702875 Source/WebCore/dom/GestureEvent.h \

Source/WebCore/Target.pri

@@SOURCES += \
414414 dom/EventTarget.cpp \
415415 dom/ExceptionBase.cpp \
416416 dom/ExceptionCodePlaceholder.cpp \
 417 dom/FocusEvent.cpp \
417418 dom/GenericEventQueue.cpp \
418419 dom/GestureEvent.cpp \
419420 dom/IconURL.cpp \

@@HEADERS += \
16321633 dom/EventTarget.h \
16331634 dom/ExceptionBase.h \
16341635 dom/ExceptionCode.h \
 1636 dom/FocusEvent.h \
16351637 dom/FragmentScriptingPermission.h \
16361638 dom/GestureEvent.h \
16371639 dom/IdTargetObserver.h \

Source/WebCore/WebCore.gypi

225225 'dom/EventException.idl',
226226 'dom/EventListener.idl',
227227 'dom/EventTarget.idl',
 228 'dom/FocusEvent.idl',
228229 'dom/HashChangeEvent.idl',
229230 'dom/KeyboardEvent.idl',
230231 'dom/MessageChannel.idl',

28432844 'dom/ExceptionBase.cpp',
28442845 'dom/ExceptionBase.h',
28452846 'dom/ExceptionCodePlaceholder.cpp',
 2847 'dom/FocusEvent.cpp',
 2848 'dom/FocusEvent.h',
28462849 'dom/GenericEventQueue.cpp',
28472850 'dom/GenericEventQueue.h',
28482851 'dom/GestureEvent.cpp',

63806383 '<(PRODUCT_DIR)/DerivedSources/WebCore/JSFileWriterSync.h',
63816384 '<(PRODUCT_DIR)/DerivedSources/WebCore/JSFloat32Array.cpp',
63826385 '<(PRODUCT_DIR)/DerivedSources/WebCore/JSFloat32Array.h',
 6386 '<(PRODUCT_DIR)/DerivedSources/WebCore/JSFocusEvent.cpp',
 6387 '<(PRODUCT_DIR)/DerivedSources/WebCore/JSFocusEvent.h',
63836388 '<(PRODUCT_DIR)/DerivedSources/WebCore/JSGeolocation.cpp',
63846389 '<(PRODUCT_DIR)/DerivedSources/WebCore/JSGeolocation.h',
63856390 '<(PRODUCT_DIR)/DerivedSources/WebCore/JSGeoposition.cpp',

Source/WebCore/WebCore.xcodeproj/project.pbxproj

53615361 B658FFA21522EF3A00DD5595 /* JSRadioNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = B658FFA01522EF3A00DD5595 /* JSRadioNodeList.h */; };
53625362 B658FFA51522EFAA00DD5595 /* RadioNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B658FFA31522EFAA00DD5595 /* RadioNodeList.cpp */; };
53635363 B658FFA61522EFAA00DD5595 /* RadioNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = B658FFA41522EFAA00DD5595 /* RadioNodeList.h */; };
 5364 B6D9D23514EABD260090D75E /* FocusEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = B6D9D23314EABD260090D75E /* FocusEvent.h */; };
 5365 B6D9D23614EABD260090D75E /* FocusEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6D9D23414EABD260090D75E /* FocusEvent.cpp */; };
 5366 B6D9D27B14EAC0860090D75E /* JSFocusEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = B6D9D27914EAC0860090D75E /* JSFocusEvent.h */; };
 5367 B6D9D27C14EAC0860090D75E /* JSFocusEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6D9D27A14EAC0860090D75E /* JSFocusEvent.cpp */; };
53645368 B71FE6DF11091CB300DAEF77 /* PrintContext.h in Headers */ = {isa = PBXBuildFile; fileRef = B776D43A1104525D00BEB0EC /* PrintContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
53655369 B734B181119B9911006587BD /* FontTranscoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B734B180119B9911006587BD /* FontTranscoder.cpp */; };
53665370 B734B183119B991D006587BD /* FontTranscoder.h in Headers */ = {isa = PBXBuildFile; fileRef = B734B182119B991D006587BD /* FontTranscoder.h */; };

1287012874 B658FFA01522EF3A00DD5595 /* JSRadioNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSRadioNodeList.h; sourceTree = "<group>"; };
1287112875 B658FFA31522EFAA00DD5595 /* RadioNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RadioNodeList.cpp; sourceTree = "<group>"; };
1287212876 B658FFA41522EFAA00DD5595 /* RadioNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RadioNodeList.h; sourceTree = "<group>"; };
 12877 B6D9D23314EABD260090D75E /* FocusEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FocusEvent.h; sourceTree = "<group>"; };
 12878 B6D9D23414EABD260090D75E /* FocusEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FocusEvent.cpp; sourceTree = "<group>"; };
 12879 B6D9D27214EABF030090D75E /* FocusEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = FocusEvent.idl; sourceTree = "<group>"; };
 12880 B6D9D27914EAC0860090D75E /* JSFocusEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFocusEvent.h; sourceTree = "<group>"; };
 12881 B6D9D27A14EAC0860090D75E /* JSFocusEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFocusEvent.cpp; sourceTree = "<group>"; };
1287312882 B734B180119B9911006587BD /* FontTranscoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FontTranscoder.cpp; path = transcoder/FontTranscoder.cpp; sourceTree = "<group>"; };
1287412883 B734B182119B991D006587BD /* FontTranscoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FontTranscoder.h; path = transcoder/FontTranscoder.h; sourceTree = "<group>"; };
1287512884 B776D43A1104525D00BEB0EC /* PrintContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrintContext.h; sourceTree = "<group>"; };

1955819567 BC60D9BE0D2A269A00B9918F /* JSEventException.h */,
1955919568 C6A703325C9D0B6CDCBC4D78 /* JSEventTarget.cpp */,
1956019569 5FC7DC26CFE2563200B85AE5 /* JSEventTarget.h */,
 19570 B6D9D27A14EAC0860090D75E /* JSFocusEvent.cpp */,
 19571 B6D9D27914EAC0860090D75E /* JSFocusEvent.h */,
1956119572 8482B74F1198CB6B00BFB005 /* JSHashChangeEvent.cpp */,
1956219573 8482B7501198CB6B00BFB005 /* JSHashChangeEvent.h */,
1956319574 A86629CE09DA2B47009633A5 /* JSKeyboardEvent.cpp */,

2240522416 935FBCF109BA143B00E230B1 /* ExceptionCode.h */,
2240622417 A7CACDB013CE875B00BBBE3F /* ExceptionCodePlaceholder.cpp */,
2240722418 A74BB76A13BDA86300FF7BF0 /* ExceptionCodePlaceholder.h */,
 22419 B6D9D23414EABD260090D75E /* FocusEvent.cpp */,
 22420 B6D9D23314EABD260090D75E /* FocusEvent.h */,
 22421 B6D9D27214EABF030090D75E /* FocusEvent.idl */,
2240822422 A853123C11D0471B00D4D077 /* FragmentScriptingPermission.h */,
2240922423 0720B09E14D3323500642955 /* GenericEventQueue.cpp */,
2241022424 0720B09F14D3323500642955 /* GenericEventQueue.h */,

2420424218 D72F6D7A153159A3001EE44E /* FlowThreadController.h in Headers */,
2420524219 14993BE60B2F2B1C0050497F /* FocusController.h in Headers */,
2420624220 062287840B4DB322000C34DF /* FocusDirection.h in Headers */,
 24221 B6D9D23514EABD260090D75E /* FocusEvent.h in Headers */,
2420724222 B2C3DA610D006CD600EF6F26 /* Font.h in Headers */,
2420824223 BCB92D4F1293550B00C8387F /* FontBaseline.h in Headers */,
2420924224 B2C3DA630D006CD600EF6F26 /* FontCache.h in Headers */,

2470224717 893C47BC1238A0A9002B3D86 /* JSFileWriterCallback.h in Headers */,
2470324718 49EECF03105070C400099FAB /* JSFloat32Array.h in Headers */,
2470424719 6EBC5EB0138B50F200A0CF8A /* JSFloat64Array.h in Headers */,
 24720 B6D9D27B14EAC0860090D75E /* JSFocusEvent.h in Headers */,
2470524721 FDA15EAC12B03EE1003A583A /* JSGainNode.h in Headers */,
2470624722 FE80DA640E9C4703000D6F75 /* JSGeolocation.h in Headers */,
2470724723 FE80DA660E9C4703000D6F75 /* JSGeoposition.h in Headers */,

2751527531 B275357A0B053814002CE64F /* FloatSizeMac.mm in Sources */,
2751627532 D72F6D79153159A3001EE44E /* FlowThreadController.cpp in Sources */,
2751727533 14993BE50B2F2B1C0050497F /* FocusController.cpp in Sources */,
 27534 B6D9D23614EABD260090D75E /* FocusEvent.cpp in Sources */,
2751827535 B2C3DA600D006CD600EF6F26 /* Font.cpp in Sources */,
2751927536 B2C3DA620D006CD600EF6F26 /* FontCache.cpp in Sources */,
2752027537 B2AFFC7C0D00A5C10030074D /* FontCacheMac.mm in Sources */,

2801628033 893C47BB1238A0A9002B3D86 /* JSFileWriterCallback.cpp in Sources */,
2801728034 49EECF02105070C400099FAB /* JSFloat32Array.cpp in Sources */,
2801828035 6EBC5EAF138B50F200A0CF8A /* JSFloat64Array.cpp in Sources */,
 28036 B6D9D27C14EAC0860090D75E /* JSFocusEvent.cpp in Sources */,
2801928037 FDA15EAB12B03EE1003A583A /* JSGainNode.cpp in Sources */,
2802028038 FE80DA630E9C4703000D6F75 /* JSGeolocation.cpp in Sources */,
2802128039 FE80D7AB0E9C1ED2000D6F75 /* JSGeolocationCustom.cpp in Sources */,

Source/WebCore/dom/DOMAllInOne.cpp

8484#include "EventTarget.cpp"
8585#include "ExceptionBase.cpp"
8686#include "ExceptionCodePlaceholder.cpp"
 87#include "FocusEvent.cpp"
8788#include "IconURL.cpp"
8889#include "IdTargetObserver.cpp"
8990#include "IdTargetObserverRegistry.cpp"

Source/WebCore/dom/Event.cpp

@@bool Event::isMouseEvent() const
122122 return false;
123123}
124124
 125bool Event::isFocusEvent() const
 126{
 127 return false;
 128}
 129
125130bool Event::isKeyboardEvent() const
126131{
127132 return false;

Source/WebCore/dom/Event.h

@@public:
124124 // These events are general classes of events.
125125 virtual bool isUIEvent() const;
126126 virtual bool isMouseEvent() const;
 127 virtual bool isFocusEvent() const;
127128 virtual bool isKeyboardEvent() const;
128129 virtual bool isTouchEvent() const;
129130

Source/WebCore/dom/EventContext.cpp

3030#include "DOMWindow.h"
3131#include "Document.h"
3232#include "Event.h"
 33#include "FocusEvent.h"
3334#include "MouseEvent.h"
3435#include "Node.h"
3536

@@void EventContext::handleLocalEvents(Event* event) const
5152 event->setCurrentTarget(m_currentTarget.get());
5253 if (m_relatedTarget.get() && event->isMouseEvent())
5354 toMouseEvent(event)->setRelatedTarget(m_relatedTarget.get());
 55 else if (m_relatedTarget.get() && event->isFocusEvent())
 56 toFocusEvent(event)->setRelatedTarget(m_relatedTarget);
5457 m_node->handleLocalEvents(event);
5558}
5659

Source/WebCore/dom/EventNames.in

@@CloseEvent
88CompositionEvent
99CustomEvent
1010ErrorEvent
 11FocusEvent
1112HashChangeEvent
1213KeyboardEvent
1314KeyboardEvents interfaceName=KeyboardEvent

Source/WebCore/dom/FocusEvent.cpp

 1/*
 2 * Copyright (C) 2013 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "FocusEvent.h"
 28
 29#include "Event.h"
 30#include "EventNames.h"
 31
 32namespace WebCore {
 33
 34const AtomicString& FocusEvent::interfaceName() const
 35{
 36 return eventNames().interfaceForFocusEvent;
 37}
 38
 39bool FocusEvent::isFocusEvent() const
 40{
 41 return true;
 42};
 43
 44FocusEvent::FocusEvent()
 45{
 46}
 47
 48FocusEvent::FocusEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view, int detail, PassRefPtr<EventTarget> relatedTarget)
 49 : UIEvent(type, canBubble, cancelable, view, detail)
 50 , m_relatedTarget(relatedTarget)
 51{
 52}
 53
 54} // namespace WebCore

Source/WebCore/dom/FocusEvent.h

 1/*
 2 * Copyright (C) 2013 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef FocusEvent_h
 27#define FocusEvent_h
 28
 29#include "EventTarget.h"
 30#include "UIEvent.h"
 31
 32namespace WebCore {
 33
 34class FocusEvent : public UIEvent {
 35public:
 36 static PassRefPtr<FocusEvent> create()
 37 {
 38 return adoptRef(new FocusEvent);
 39 }
 40
 41 static PassRefPtr<FocusEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view, int detail, PassRefPtr<EventTarget> relatedTarget)
 42 {
 43 return adoptRef(new FocusEvent(type, canBubble, cancelable, view, detail, relatedTarget));
 44 }
 45
 46 EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
 47 void setRelatedTarget(PassRefPtr<EventTarget> relatedTarget) { m_relatedTarget = relatedTarget; }
 48
 49 virtual const AtomicString& interfaceName() const;
 50 virtual bool isFocusEvent() const;
 51
 52private:
 53 FocusEvent();
 54 FocusEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, int, PassRefPtr<EventTarget>);
 55
 56 RefPtr<EventTarget> m_relatedTarget;
 57};
 58
 59inline FocusEvent* toFocusEvent(Event* event)
 60{
 61 ASSERT(event && event->isFocusEvent());
 62 return static_cast<FocusEvent*>(event);
 63}
 64
 65} // namespace WebCore
 66
 67#endif // FocusEvent_h

Source/WebCore/dom/FocusEvent.idl

 1/*
 2 * Copyright (C) 2013 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26interface FocusEvent : UIEvent
 27{
 28 readonly attribute EventTarget relatedTarget;
 29};

Source/WebCore/dom/Node.cpp

5959#include "EventListener.h"
6060#include "EventNames.h"
6161#include "ExceptionCode.h"
 62#include "FocusEvent.h"
6263#include "Frame.h"
6364#include "FrameView.h"
6465#include "HTMLElement.h"

@@void Node::dispatchFocusInEvent(const AtomicString& eventType, PassRefPtr<Node>
23562357{
23572358 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
23582359 ASSERT(eventType == eventNames().focusinEvent || eventType == eventNames().DOMFocusInEvent);
2359  dispatchScopedEventDispatchMediator(FocusInEventDispatchMediator::create(UIEvent::create(eventType, true, false, document()->defaultView(), 0), oldFocusedNode));
 2360 dispatchScopedEventDispatchMediator(FocusInEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document()->defaultView(), 0, 0), oldFocusedNode));
23602361}
23612362
23622363void Node::dispatchFocusOutEvent(const AtomicString& eventType, PassRefPtr<Node> newFocusedNode)
23632364{
23642365 ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
23652366 ASSERT(eventType == eventNames().focusoutEvent || eventType == eventNames().DOMFocusOutEvent);
2366  dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(UIEvent::create(eventType, true, false, document()->defaultView(), 0), newFocusedNode));
 2367 dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document()->defaultView(), 0, 0), newFocusedNode));
23672368}
23682369
23692370bool Node::dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent)

LayoutTests/ChangeLog

 12013-02-03 Kentaro Hara <haraken@chromium.org>
 2
 3 WebKit's focus events are UIEvents (instead of FocusEvent) and thus don't expose .relatedTarget
 4 https://bugs.webkit.org/show_bug.cgi?id=76216
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Spec: http://www.w3.org/TR/DOM-Level-3-Events/#events-FocusEvent
 9
 10 This patch creates a new FocusEvent class with a relatedTarget attribute.
 11 Now when focusin or focusout events are dispatched, a FocusEvent is created with
 12 the relatedTarget attribute set accordingly.
 13
 14 * fast/dom/shadow/shadow-boundary-events-expected.txt:
 15 * fast/dom/shadow/shadow-boundary-events.html:
 16 * fast/events/related-target-focusevent-expected.txt: Added.
 17 * fast/events/related-target-focusevent.html: Added.
 18
1192013-02-06 Stephen Chenney <schenney@chromium.org>
220
321 [Chromium] Test expectations update for Skia change.

LayoutTests/fast/dom/shadow/shadow-boundary-events-expected.txt

@@PASS dispatchedEvent("mouseout") is ["divH(<-shadowK)(@divH)", "shadowG(<-shadow
6161
6262Move focus from a node to its sibling node. All nodes are outside of shadow boundary.
6363Moving focus from divB to divC
64 PASS dispatchedEvent("focusin") is ["divC(@divC)", "divC(@divA)"]
65 PASS dispatchedEvent("focusout") is ["divB(@divB)", "divB(@divA)"]
 64PASS dispatchedEvent("focusin") is ["divC(<-divB)(@divC)", "divC(<-divB)(@divA)"]
 65PASS dispatchedEvent("focusout") is ["divB(<-divC)(@divB)", "divB(<-divC)(@divA)"]
6666
6767Old focused node and new focused node exist in separated subtrees, crossing shadow boundaries. Making sure that an event is not dispatched beyond the lowest common boundary.
6868Moving focus from shadowD/shadowF/shadowG/divH to shadowD/shadowK/divL
69 PASS dispatchedEvent("focusin") is ["divL(@divL)", "shadowK(@shadowK)", "shadowK(@divJ)"]
70 PASS dispatchedEvent("focusout") is ["divH(@divH)", "shadowG(@shadowG)", "shadowF(@shadowF)", "shadowF(@divE)"]
 69PASS dispatchedEvent("focusin") is ["divL(<-shadowF)(@divL)", "shadowK(<-shadowF)(@shadowK)", "shadowK(<-shadowF)(@divJ)"]
 70PASS dispatchedEvent("focusout") is ["divH(<-shadowK)(@divH)", "shadowG(<-shadowK)(@shadowG)", "shadowF(<-shadowK)(@shadowF)", "shadowF(<-shadowK)(@divE)"]
7171
7272Move focus from a node to its sibling node. All nodes are outside of shadow boundary.
7373Moving focus from divB to divC

LayoutTests/fast/dom/shadow/shadow-boundary-events.html

@@function test()
180180 // Test for focusin/focusout events.
181181 moveFocus('divB', 'divC',
182182 'Move focus from a node to its sibling node. All nodes are outside of shadow boundary.');
183  shouldBe('dispatchedEvent("focusin")', '["divC(@divC)", "divC(@divA)"]');
184  shouldBe('dispatchedEvent("focusout")', '["divB(@divB)", "divB(@divA)"]');
 183 shouldBe('dispatchedEvent("focusin")', '["divC(<-divB)(@divC)", "divC(<-divB)(@divA)"]');
 184 shouldBe('dispatchedEvent("focusout")', '["divB(<-divC)(@divB)", "divB(<-divC)(@divA)"]');
185185
186186 moveFocus('shadowD/shadowF/shadowG/divH', 'shadowD/shadowK/divL',
187187 'Old focused node and new focused node exist in separated subtrees, crossing shadow boundaries. Making sure that an event is not dispatched beyond the lowest common boundary.');
188  shouldBe('dispatchedEvent("focusin")', '["divL(@divL)", "shadowK(@shadowK)", "shadowK(@divJ)"]');
189  shouldBe('dispatchedEvent("focusout")', '["divH(@divH)", "shadowG(@shadowG)", "shadowF(@shadowF)", "shadowF(@divE)"]');
 188 shouldBe('dispatchedEvent("focusin")', '["divL(<-shadowF)(@divL)", "shadowK(<-shadowF)(@shadowK)", "shadowK(<-shadowF)(@divJ)"]');
 189 shouldBe('dispatchedEvent("focusout")', '["divH(<-shadowK)(@divH)", "shadowG(<-shadowK)(@shadowG)", "shadowF(<-shadowK)(@shadowF)", "shadowF(<-shadowK)(@divE)"]');
190190
191191 // Omitted test cases where either a oldFocusedNode or newFocusedNode is an ancestor of the other.
192192 // Due to a focus transfer mechanism on shadow hosts, a focused node should be a leaf node in general.

LayoutTests/fast/events/related-target-focusevent-expected.txt

 1PASS event.relatedTarget is null
 2PASS event.relatedTarget is input2
 3PASS event.relatedTarget is input1
 4PASS event.relatedTarget is input3
 5PASS event.relatedTarget is input2
 6PASS event.relatedTarget is input4
 7PASS successfullyParsed is true
 8
 9TEST COMPLETE
 10Checks that the relatedTarget attribute for FocusEvent objects is being set correctly when focusin/focusout events are dispatched. Press tab four times to dispatch a focusin and focusout event for each of the inputs below.
 11
 12On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 13
 14
 15

LayoutTests/fast/events/related-target-focusevent.html

 1<html>
 2<head>
 3<script src="../js/resources/js-test-pre.js"></script>
 4</head>
 5<body>
 6<p id="description"></p>
 7<input id="input1" type="text"></input>
 8<input id="input2" type="text"></input>
 9<input id="input3" type="text"></input>
 10<input id="input4" type="text"></input>
 11<script>
 12jsTestIsAsync = true;
 13
 14description("Checks that the relatedTarget attribute for FocusEvent objects is being set correctly when focusin/focusout events are dispatched. <b>Press tab four times</b> to dispatch a focusin and focusout event for each of the inputs below.");
 15
 16var input1 = document.getElementById('input1');
 17var input2 = document.getElementById('input2');
 18var input3 = document.getElementById('input3');
 19
 20input1.addEventListener("focusin", function(event) { shouldBe('event.relatedTarget', 'null'); });
 21input1.addEventListener("focusout", function(event) { shouldBe('event.relatedTarget', 'input2'); });
 22input2.addEventListener("focusin", function(event) { shouldBe('event.relatedTarget', 'input1'); });
 23input2.addEventListener("focusout", function(event) { shouldBe('event.relatedTarget', 'input3'); });
 24input3.addEventListener("focusin", function(event) { shouldBe('event.relatedTarget', 'input2'); });
 25input3.addEventListener("focusout", function(event) { shouldBe('event.relatedTarget', 'input4'); finishJSTest(); });
 26
 27for (var i = 0; i < 4; i++) {
 28 eventSender.keyDown('\t');
 29}
 30</script>
 31<script src="../js/resources/js-test-post.js"></script>
 32</body>
 33</html>