Reviewed by Mitz.
- fix http://bugs.webkit.org/show_bug.cgi?id=11628
REGRESSION (r17597): Command-return in native text fields doesn't open a new tab or window
I couldn't think of an easy way to make a regression test for this, but maybe
I'll get an idea later about how to do it.
The main thing I did was add a concept of a DOM event having an "underlying event".
That allows the DOM activate event to contain inside it the original keyboard event
that triggered the form submission, and thus allows WebKit to see the modifier keys
from that original event. The code that uses the underlying event is in WebKit, but
the code to set it up is here in WebCore.
- also do some clean-up to related event handling code
* bindings/js/kjs_events.cpp: (KJS::DOMEvent::getValueProperty): Updated for the
name change of cancelBubble.
* dom/Event.h: Removed a useless comment. Fixed some whitespace and formatting.
Renamed getCancelBubble to cancelBubble to match the DOM -- I suspect the old
name predated the use of the m_ prefix on data members. Added the underlying event,
and a getter and setter.
* dom/Event.cpp:
(WebCore::Event::setTarget): Updated to take a PassRefPtr.
(WebCore::Event::setUnderlyingEvent): Added.
* dom/EventTargetNode.h: Added an optional underlyingEvent parameter to
dispatchUIEvent, one of the overloads of dispatchMouseEvent, and
dispatchSimulatedMouseEvent. Added a new dispatchSimulatedClick function here that
mostly replaces the click function in HTMLElement.
* dom/EventTargetNode.cpp:
(WebCore::EventTargetNode::dispatchGenericEvent): Updated for the name change
of cancelBubble.
(WebCore::EventTargetNode::dispatchUIEvent): Added an underlying event parameter,
which gets attached to the UIEvent object after it's created.
(WebCore::EventTargetNode::dispatchMouseEvent): Tweaked formatting and parameter
name for the version that creates a mouse event for a real platform mouse event.
Added an underlying event parameter to the main version, and attached it to all
three of the events that can be dispatched.
(WebCore::EventTargetNode::dispatchSimulatedMouseEvent): Added an underlying
event parameter, passed it along to dispatchMouseEvent.
(WebCore::EventTargetNode::dispatchSimulatedClick): Moved this here from HTMLElement
and renamed it from click. Added an underlyingEvent parameter, and passed that along
in all three of the calls to dispatchSimulatedMouseEvent.
* bridge/mac/FrameMac.mm: (WebCore::FrameMac::shouldClose): Updated call to
setTarget that no longer needs a get().
* ksvg2/svg/SVGElement.cpp: (WebCore::SVGElement::sendSVGLoadEventIfPossible): Ditto.
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::defaultEventHandler): Converted a call to click
to a call to dispatchSimulatedClick.
(WebCore::HTMLAnchorElement::accessKeyAction): Ditto.
* html/HTMLButtonElement.cpp:
(WebCore::HTMLButtonElement::accessKeyAction): Ditto.
* html/HTMLElement.h: Removed the parameters to click and made it non-virtual.
We could move it down to the input and button elements, now that it's just
a single function call, but it's also OK to just leave it here.
* html/HTMLElement.cpp:
(WebCore::HTMLElement::click): Removed the parameters and changed this to just
call dispatchSimulatedClick. The real work is now in dispatchSimulatedClick.
(WebCore::HTMLElement::accessKeyAction): Converted a call to click to a call to
dispatchSimulatedClick.
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::submitClick): Ditto. But unlike accessKeyAction callers,
pass the event along as the underlying event.
* html/HTMLInputElement.h:
* html/HTMLInputElement.cpp: Removed override of virtual click function. The
special cases for the file control and hidden input elements aren't needed.
(WebCore::HTMLInputElement::accessKeyAction): Converted a call to click to a call to
dispatchSimulatedClick.
(WebCore::HTMLInputElement::defaultEventHandler): Converted calls to click to calls to
dispatchSimulatedClick, passing along the event as the underlying event.
* html/HTMLLabelElement.cpp:
(WebCore::HTMLLabelElement::defaultEventHandler): Converted a call to click to a call
to dispatchSimulatedClick, passing the event along as the underlying event. Also
changed the local variable for the element to a RefPtr since the code assumes it's
still around after calling arbitrary JavaScript code.
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::accessKeyAction): Converted a call to click to a call to
dispatchSimulatedClick.
* rendering/RenderFileUploadControl.h:
* rendering/RenderFileUploadControl.cpp: (WebCore::RenderFileUploadControl::click):
Removed unneeded ignored parameter to the click function, and also made it non-virtual.
* loader/NavigationAction.h: Removed unneeded includes.
* loader/NavigationAction.cpp: Moved all the code here from NavigationActionMac.mm,
since none of it is Mac-specific any more.
* loader/mac/NavigationActionMac.mm: Removed.
* WebCore.xcodeproj/project.pbxproj: Updated for removed file.
* ksvg2/svg/SVGAElement.cpp: Removed an unnecessary include.
* loader/FrameLoader.cpp: Added a newly-needed incluude.
* loader/mac/DocumentLoaderMac.mm: Ditto.
* loader/mac/FrameLoaderMac.mm: Ditto.
* rendering/RenderWidget.cpp: Ditto.
WebKit:
Reviewed by Mitz.
- fix http://bugs.webkit.org/show_bug.cgi?id=11628
REGRESSION (r17597): Command-return in native text fields doesn't open a new tab or window
* WebCoreSupport/WebFrameLoaderClient.mm:
(findKeyStateEvent): Added. Helper that finds the mouse or keyboard event in a chain
of events and their underlying events.
(findMouseEvent): Added. Same, but specifically for mouse events.
(WebFrameLoaderClient::actionDictionary): Rewrote to use the above functions. This means we
use the modifiers from the underlying events rather than just the one from the event itself.
So if the event is a DOM activate event, we can still see the modifiers from the original
keyboard event that triggered it. Has no effect if the event is already the right type or
if there is no underlying event.
* WebView/WebFrame.mm: Added a newly-needed include.
* WebKit.xcodeproj/project.pbxproj: Xcode wants what it wants.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@17976
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2006-12-01 Darin Adler <darin@apple.com>
+
+ Reviewed by Mitz.
+
+ - fix http://bugs.webkit.org/show_bug.cgi?id=11628
+ REGRESSION (r17597): Command-return in native text fields doesn't open a new tab or window
+
+ I couldn't think of an easy way to make a regression test for this, but maybe
+ I'll get an idea later about how to do it.
+
+ The main thing I did was add a concept of a DOM event having an "underlying event".
+ That allows the DOM activate event to contain inside it the original keyboard event
+ that triggered the form submission, and thus allows WebKit to see the modifier keys
+ from that original event. The code that uses the underlying event is in WebKit, but
+ the code to set it up is here in WebCore.
+
+ - also do some clean-up to related event handling code
+
+ * bindings/js/kjs_events.cpp: (KJS::DOMEvent::getValueProperty): Updated for the
+ name change of cancelBubble.
+
+ * dom/Event.h: Removed a useless comment. Fixed some whitespace and formatting.
+ Renamed getCancelBubble to cancelBubble to match the DOM -- I suspect the old
+ name predated the use of the m_ prefix on data members. Added the underlying event,
+ and a getter and setter.
+ * dom/Event.cpp:
+ (WebCore::Event::setTarget): Updated to take a PassRefPtr.
+ (WebCore::Event::setUnderlyingEvent): Added.
+
+ * dom/EventTargetNode.h: Added an optional underlyingEvent parameter to
+ dispatchUIEvent, one of the overloads of dispatchMouseEvent, and
+ dispatchSimulatedMouseEvent. Added a new dispatchSimulatedClick function here that
+ mostly replaces the click function in HTMLElement.
+ * dom/EventTargetNode.cpp:
+ (WebCore::EventTargetNode::dispatchGenericEvent): Updated for the name change
+ of cancelBubble.
+ (WebCore::EventTargetNode::dispatchUIEvent): Added an underlying event parameter,
+ which gets attached to the UIEvent object after it's created.
+ (WebCore::EventTargetNode::dispatchMouseEvent): Tweaked formatting and parameter
+ name for the version that creates a mouse event for a real platform mouse event.
+ Added an underlying event parameter to the main version, and attached it to all
+ three of the events that can be dispatched.
+ (WebCore::EventTargetNode::dispatchSimulatedMouseEvent): Added an underlying
+ event parameter, passed it along to dispatchMouseEvent.
+ (WebCore::EventTargetNode::dispatchSimulatedClick): Moved this here from HTMLElement
+ and renamed it from click. Added an underlyingEvent parameter, and passed that along
+ in all three of the calls to dispatchSimulatedMouseEvent.
+
+ * bridge/mac/FrameMac.mm: (WebCore::FrameMac::shouldClose): Updated call to
+ setTarget that no longer needs a get().
+ * ksvg2/svg/SVGElement.cpp: (WebCore::SVGElement::sendSVGLoadEventIfPossible): Ditto.
+
+ * html/HTMLAnchorElement.cpp:
+ (WebCore::HTMLAnchorElement::defaultEventHandler): Converted a call to click
+ to a call to dispatchSimulatedClick.
+ (WebCore::HTMLAnchorElement::accessKeyAction): Ditto.
+ * html/HTMLButtonElement.cpp:
+ (WebCore::HTMLButtonElement::accessKeyAction): Ditto.
+ * html/HTMLElement.h: Removed the parameters to click and made it non-virtual.
+ We could move it down to the input and button elements, now that it's just
+ a single function call, but it's also OK to just leave it here.
+ * html/HTMLElement.cpp:
+ (WebCore::HTMLElement::click): Removed the parameters and changed this to just
+ call dispatchSimulatedClick. The real work is now in dispatchSimulatedClick.
+ (WebCore::HTMLElement::accessKeyAction): Converted a call to click to a call to
+ dispatchSimulatedClick.
+ * html/HTMLFormElement.cpp:
+ (WebCore::HTMLFormElement::submitClick): Ditto. But unlike accessKeyAction callers,
+ pass the event along as the underlying event.
+ * html/HTMLInputElement.h:
+ * html/HTMLInputElement.cpp: Removed override of virtual click function. The
+ special cases for the file control and hidden input elements aren't needed.
+ (WebCore::HTMLInputElement::accessKeyAction): Converted a call to click to a call to
+ dispatchSimulatedClick.
+ (WebCore::HTMLInputElement::defaultEventHandler): Converted calls to click to calls to
+ dispatchSimulatedClick, passing along the event as the underlying event.
+ * html/HTMLLabelElement.cpp:
+ (WebCore::HTMLLabelElement::defaultEventHandler): Converted a call to click to a call
+ to dispatchSimulatedClick, passing the event along as the underlying event. Also
+ changed the local variable for the element to a RefPtr since the code assumes it's
+ still around after calling arbitrary JavaScript code.
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::accessKeyAction): Converted a call to click to a call to
+ dispatchSimulatedClick.
+
+ * rendering/RenderFileUploadControl.h:
+ * rendering/RenderFileUploadControl.cpp: (WebCore::RenderFileUploadControl::click):
+ Removed unneeded ignored parameter to the click function, and also made it non-virtual.
+
+ * loader/NavigationAction.h: Removed unneeded includes.
+ * loader/NavigationAction.cpp: Moved all the code here from NavigationActionMac.mm,
+ since none of it is Mac-specific any more.
+ * loader/mac/NavigationActionMac.mm: Removed.
+ * WebCore.xcodeproj/project.pbxproj: Updated for removed file.
+
+ * ksvg2/svg/SVGAElement.cpp: Removed an unnecessary include.
+
+ * loader/FrameLoader.cpp: Added a newly-needed incluude.
+ * loader/mac/DocumentLoaderMac.mm: Ditto.
+ * loader/mac/FrameLoaderMac.mm: Ditto.
+ * rendering/RenderWidget.cpp: Ditto.
+
2006-12-01 John Sullivan <sullivan@apple.com>
Reviewed by Darin
93C841F809CE855C00DFF5E5 /* DOMImplementationFront.h in Headers */ = {isa = PBXBuildFile; fileRef = 93C841F709CE855C00DFF5E5 /* DOMImplementationFront.h */; };
93C841FF09CE858300DFF5E5 /* DOMImplementationFront.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93C841FE09CE858300DFF5E5 /* DOMImplementationFront.cpp */; };
93CCF0270AF6C52900018E89 /* NavigationAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 93CCF0260AF6C52900018E89 /* NavigationAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 93CCF0580AF6C9FE00018E89 /* NavigationActionMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93CCF0570AF6C9FE00018E89 /* NavigationActionMac.mm */; };
93CCF0600AF6CA7600018E89 /* NavigationAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93CCF05F0AF6CA7600018E89 /* NavigationAction.cpp */; };
93CD4FDE0995F9EA007ECC97 /* AtomicString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93CD4FD70995F9EA007ECC97 /* AtomicString.cpp */; };
93CD4FDF0995F9EA007ECC97 /* AtomicString.h in Headers */ = {isa = PBXBuildFile; fileRef = 93CD4FD80995F9EA007ECC97 /* AtomicString.h */; settings = {ATTRIBUTES = (Private, ); }; };
93CA4CA209DF93FA00DF8677 /* svg.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = svg.css; sourceTree = "<group>"; };
93CA4CA309DF93FA00DF8677 /* tokenizer.flex */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tokenizer.flex; sourceTree = "<group>"; };
93CCF0260AF6C52900018E89 /* NavigationAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationAction.h; sourceTree = "<group>"; };
- 93CCF0570AF6C9FE00018E89 /* NavigationActionMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = NavigationActionMac.mm; sourceTree = "<group>"; };
93CCF05F0AF6CA7600018E89 /* NavigationAction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NavigationAction.cpp; sourceTree = "<group>"; };
93CD4FD70995F9EA007ECC97 /* AtomicString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AtomicString.cpp; sourceTree = "<group>"; };
93CD4FD80995F9EA007ECC97 /* AtomicString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicString.h; sourceTree = "<group>"; };
6563A9A50ADF4094000ED2CD /* LoaderNSURLRequestExtras.h */,
6563A9A60ADF4094000ED2CD /* LoaderNSURLRequestExtras.m */,
656D372A0ADBA5DE00A4554D /* MainResourceLoaderMac.mm */,
- 93CCF0570AF6C9FE00018E89 /* NavigationActionMac.mm */,
656D372C0ADBA5DE00A4554D /* NetscapePlugInStreamLoaderMac.mm */,
656D37280ADBA5DE00A4554D /* ResourceLoaderMac.mm */,
656D37310ADBA5DE00A4554D /* SubresourceLoaderMac.mm */,
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
- compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
knownRegions = (
English,
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
- shouldCheckCompatibility = 1;
targets = (
93F198A508245E59001E9ABC /* WebCore */,
DD041FBE09D9DDBE0010AF2A /* Derived Sources */,
93E22A6F0AF5E94100D48324 /* PageState.cpp in Sources */,
4B2709830AF2E5E00065127F /* PasteboardMac.mm in Sources */,
650E3F6A0AF6C168001FA3AD /* ResourceRequestMac.mm in Sources */,
- 93CCF0580AF6C9FE00018E89 /* NavigationActionMac.mm in Sources */,
93CCF0600AF6CA7600018E89 /* NavigationAction.cpp in Sources */,
B2A015A80AF6CD53006BCE0E /* GraphicsContext.cpp in Sources */,
B2A015AA0AF6CD53006BCE0E /* GraphicsTypes.cpp in Sources */,
case Bubbles:
return jsBoolean(event.bubbles());
case CancelBubble:
- return jsBoolean(event.getCancelBubble());
+ return jsBoolean(event.cancelBubble());
case ReturnValue:
return jsBoolean(!event.defaultPrevented());
case Cancelable:
return true;
RefPtr<BeforeUnloadEvent> event = new BeforeUnloadEvent;
- event->setTarget(doc.get());
+ event->setTarget(doc);
doc->handleWindowEvent(event.get(), false);
if (!event->defaultPrevented() && doc)
{
}
-void Event::setTarget(Node* target)
+void Event::setTarget(PassRefPtr<Node> target)
{
m_target = target;
- if (target)
+ if (m_target)
receivedTarget();
}
{
}
+void Event::setUnderlyingEvent(PassRefPtr<Event> ue)
+{
+ // Prohibit creation of a cycle -- just do nothing in that case.
+ for (Event* e = ue.get(); e; e = e->underlyingEvent())
+ if (e == this)
+ return;
+ m_underlyingEvent = ue;
+}
+
} // namespace WebCore
BUBBLING_PHASE = 3
};
- // Reverse-engineered from Netscape
enum EventType {
MOUSEDOWN = 1,
MOUSEUP = 2,
SELECT = 16384,
CHANGE = 32768
};
-
+
Event();
- Event(const AtomicString& typeArg, bool canBubbleArg, bool cancelableArg);
+ Event(const AtomicString& type, bool canBubble, bool cancelable);
virtual ~Event();
- void initEvent(const AtomicString &eventTypeArg, bool canBubbleArg, bool cancelableArg);
+ void initEvent(const AtomicString& type, bool canBubble, bool cancelable);
const AtomicString& type() const { return m_type; }
-
+
Node* target() const { return m_target.get(); }
- void setTarget(Node*);
-
+ void setTarget(PassRefPtr<Node>);
+
Node* currentTarget() const { return m_currentTarget; }
void setCurrentTarget(Node* currentTarget) { m_currentTarget = currentTarget; }
-
+
unsigned short eventPhase() const { return m_eventPhase; }
void setEventPhase(unsigned short eventPhase) { m_eventPhase = eventPhase; }
-
+
bool bubbles() const { return m_canBubble; }
bool cancelable() const { return m_cancelable; }
DOMTimeStamp timeStamp() { return m_createTime; }
#ifdef SVG_SUPPORT
virtual bool isSVGZoomEvent() const;
#endif
-
- bool propagationStopped() const { return m_propagationStopped; }
- bool defaultPrevented() const { return m_defaultPrevented; }
- void setDefaultHandled() { m_defaultHandled = true; }
- bool defaultHandled() const { return m_defaultHandled; }
+ bool propagationStopped() const { return m_propagationStopped; }
+ bool defaultPrevented() const { return m_defaultPrevented; }
void preventDefault() { if (m_cancelable) m_defaultPrevented = true; }
void setDefaultPrevented(bool defaultPrevented) { m_defaultPrevented = defaultPrevented; }
+ bool defaultHandled() const { return m_defaultHandled; }
+ void setDefaultHandled() { m_defaultHandled = true; }
+
+ bool cancelBubble() const { return m_cancelBubble; }
void setCancelBubble(bool cancel) { m_cancelBubble = cancel; }
- bool getCancelBubble() const { return m_cancelBubble; }
+
+ Event* underlyingEvent() const { return m_underlyingEvent.get(); }
+ void setUnderlyingEvent(PassRefPtr<Event>);
virtual bool storesResultAsString() const;
virtual void storeResult(const String&);
bool m_defaultHandled;
bool m_cancelBubble;
- Node* m_currentTarget; // ref > 0 maintained externally
+ Node* m_currentTarget;
unsigned short m_eventPhase;
RefPtr<Node> m_target;
DOMTimeStamp m_createTime;
+
+ RefPtr<Event> m_underlyingEvent;
};
} // namespace WebCore
if (evt->bubbles()) {
evt->setEventPhase(Event::BUBBLING_PHASE);
- for (; it.current() && !evt->propagationStopped() && !evt->getCancelBubble(); --it) {
+ for (; it.current() && !evt->propagationStopped() && !evt->cancelBubble(); --it) {
evt->setCurrentTarget(it.current());
EventTargetNodeCast(it.current())->handleLocalEvents(evt.get(), false);
}
// because Mozilla used to never propagate load events at all
it.toFirst();
- if (evt->type() != loadEvent && it.current()->isDocumentNode() && !evt->propagationStopped() && !evt->getCancelBubble()) {
+ if (evt->type() != loadEvent && it.current()->isDocumentNode() && !evt->propagationStopped() && !evt->cancelBubble()) {
evt->setCurrentTarget(it.current());
static_cast<Document*>(it.current())->handleWindowEvent(evt.get(), false);
}
ExceptionCode ec = 0;
RefPtr<Event> evt = new Event(eventType, canBubbleArg, cancelableArg);
RefPtr<Document> doc = document();
- evt->setTarget(doc.get());
+ evt->setTarget(doc);
doc->handleWindowEvent(evt.get(), true);
doc->handleWindowEvent(evt.get(), false);
}
}
-bool EventTargetNode::dispatchUIEvent(const AtomicString &eventType, int detail)
+bool EventTargetNode::dispatchUIEvent(const AtomicString& eventType, int detail, PassRefPtr<Event> underlyingEvent)
{
assert(!eventDispatchForbidden());
assert(eventType == DOMFocusInEvent || eventType == DOMFocusOutEvent || eventType == DOMActivateEvent);
bool cancelable = eventType == DOMActivateEvent;
ExceptionCode ec = 0;
- UIEvent* evt = new UIEvent(eventType, true, cancelable, document()->defaultView(), detail);
- return dispatchEvent(evt, ec, true);
+ RefPtr<UIEvent> evt = new UIEvent(eventType, true, cancelable, document()->defaultView(), detail);
+ evt->setUnderlyingEvent(underlyingEvent);
+ return dispatchEvent(evt.release(), ec, true);
}
bool EventTargetNode::dispatchKeyEvent(const PlatformKeyboardEvent& key)
return r;
}
-bool EventTargetNode::dispatchMouseEvent(const PlatformMouseEvent& _mouse, const AtomicString& eventType,
- int detail, Node* relatedTarget)
+bool EventTargetNode::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType,
+ int detail, Node* relatedTarget)
{
assert(!eventDispatchForbidden());
IntPoint contentsPos;
if (FrameView* view = document()->view())
- contentsPos = view->windowToContents(_mouse.pos());
+ contentsPos = view->windowToContents(event.pos());
- return dispatchMouseEvent(eventType, _mouse.button(), detail,
- contentsPos.x(), contentsPos.y(), _mouse.globalX(), _mouse.globalY(),
- _mouse.ctrlKey(), _mouse.altKey(), _mouse.shiftKey(), _mouse.metaKey(),
- false, relatedTarget);
+ return dispatchMouseEvent(eventType, event.button(), detail,
+ contentsPos.x(), contentsPos.y(), event.globalX(), event.globalY(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
+ false, relatedTarget);
}
-bool EventTargetNode::dispatchSimulatedMouseEvent(const AtomicString &eventType)
+void EventTargetNode::dispatchSimulatedMouseEvent(const AtomicString& eventType,
+ PassRefPtr<Event> underlyingEvent)
{
assert(!eventDispatchForbidden());
// Like Gecko, we just pass 0 for everything when we make a fake mouse event.
// Internet Explorer instead gives the current mouse position and state.
- return dispatchMouseEvent(eventType, 0, 0, 0, 0, 0, 0, false, false, false, false, true);
+ dispatchMouseEvent(eventType, 0, 0, 0, 0, 0, 0,
+ false, false, false, false, true, 0, underlyingEvent);
+}
+
+void EventTargetNode::dispatchSimulatedClick(PassRefPtr<Event> event, bool sendMouseEvents, bool showPressedLook)
+{
+ // send mousedown and mouseup before the click, if requested
+ if (sendMouseEvents)
+ dispatchSimulatedMouseEvent(mousedownEvent, event.get());
+ setActive(true, showPressedLook);
+ if (sendMouseEvents)
+ dispatchSimulatedMouseEvent(mouseupEvent, event.get());
+ setActive(false);
+
+ // always send click
+ dispatchSimulatedMouseEvent(clickEvent, event);
}
bool EventTargetNode::dispatchMouseEvent(const AtomicString& eventType, int button, int detail,
- int pageX, int pageY, int screenX, int screenY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- bool isSimulated, Node* relatedTargetArg)
+ int pageX, int pageY, int screenX, int screenY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
+ bool isSimulated, Node* relatedTargetArg, PassRefPtr<Event> underlyingEvent)
{
assert(!eventDispatchForbidden());
if (disabled()) // Don't even send DOM events for disabled controls..
EventTargetNode *relatedTarget = (relatedTargetArg && relatedTargetArg->isEventTargetNode()) ? static_cast<EventTargetNode*>(relatedTargetArg) : 0;
RefPtr<Event> me = new MouseEvent(eventType, true, cancelable, document()->defaultView(),
- detail, screenX, screenY, pageX, pageY,
- ctrlKey, altKey, shiftKey, metaKey, button,
- relatedTarget, 0, isSimulated);
+ detail, screenX, screenY, pageX, pageY,
+ ctrlKey, altKey, shiftKey, metaKey, button,
+ relatedTarget, 0, isSimulated);
+ me->setUnderlyingEvent(underlyingEvent.get());
dispatchEvent(me, ec, true);
bool defaultHandled = me->defaultHandled();
detail, screenX, screenY, pageX, pageY,
ctrlKey, altKey, shiftKey, metaKey, button,
relatedTarget, 0, isSimulated);
+ me->setUnderlyingEvent(underlyingEvent.get());
if (defaultHandled)
me->setDefaultHandled();
dispatchEvent(me, ec, true);
// Also send a DOMActivate event, which causes things like form submissions to occur.
if (eventType == clickEvent && !defaultPrevented)
- dispatchUIEvent(DOMActivateEvent, detail);
+ dispatchUIEvent(DOMActivateEvent, detail, underlyingEvent);
return swallowEvent;
}
bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&, bool tempEvent = false);
bool dispatchSubtreeModifiedEvent(bool childrenChanged = true);
void dispatchWindowEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
- bool dispatchUIEvent(const AtomicString& eventType, int detail = 0);
+ bool dispatchUIEvent(const AtomicString& eventType, int detail = 0, PassRefPtr<Event> underlyingEvent = 0);
bool dispatchKeyEvent(const PlatformKeyboardEvent&);
void dispatchWheelEvent(PlatformWheelEvent&);
bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType,
bool dispatchMouseEvent(const AtomicString& eventType, int button, int clickCount,
int pageX, int pageY, int screenX, int screenY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- bool isSimulated = false, Node* relatedTarget = 0);
- bool dispatchSimulatedMouseEvent(const AtomicString& eventType);
+ bool isSimulated = false, Node* relatedTarget = 0, PassRefPtr<Event> underlyingEvent = 0);
+ void dispatchSimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<Event> underlyingEvent = 0);
+ void dispatchSimulatedClick(PassRefPtr<Event> underlyingEvent, bool sendMouseEvents = false, bool showPressedLook = true);
void handleLocalEvents(Event*, bool useCapture);
}
if (k->keyEvent()) {
evt->setDefaultHandled();
- click(false);
+ dispatchSimulatedClick(0);
return;
}
}
void HTMLAnchorElement::accessKeyAction(bool sendToAnyElement)
{
- // send the mouse button events iff the
- // caller specified sendToAnyElement
- click(sendToAnyElement);
+ // send the mouse button events iff the caller specified sendToAnyElement
+ dispatchSimulatedClick(0, sendToAnyElement);
}
bool HTMLAnchorElement::isURLAttribute(Attribute *attr) const
void HTMLButtonElement::accessKeyAction(bool sendToAnyElement)
{
- // send the mouse button events iff the
- // caller specified sendToAnyElement
- click(sendToAnyElement);
+ // send the mouse button events iff the caller specified sendToAnyElement
+ dispatchSimulatedClick(0, sendToAnyElement);
}
String HTMLButtonElement::accessKey() const
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "DocumentFragment.h"
+#include "Event.h"
#include "EventListener.h"
#include "EventNames.h"
#include "ExceptionCode.h"
setAttribute(contenteditableAttr, enabled.isEmpty() ? "true" : enabled);
}
-void HTMLElement::click(bool sendMouseEvents, bool showPressedLook)
+void HTMLElement::click()
{
- // send mousedown and mouseup before the click, if requested
- if (sendMouseEvents)
- dispatchSimulatedMouseEvent(mousedownEvent);
- setActive(true, showPressedLook);
- if (sendMouseEvents)
- dispatchSimulatedMouseEvent(mouseupEvent);
- setActive(false);
-
- // always send click
- dispatchSimulatedMouseEvent(clickEvent);
+ dispatchSimulatedClick(0);
}
// accessKeyAction is used by the accessibility support code
void HTMLElement::accessKeyAction(bool sendToAnyElement)
{
if (sendToAnyElement)
- click(true);
+ dispatchSimulatedClick(0, true);
}
String HTMLElement::toString() const
virtual void setContentEditable(MappedAttribute*);
virtual void setContentEditable(const String&);
- virtual void click(bool sendMouseEvents = false, bool showPressedLook = true);
+ void click();
+
virtual void accessKeyAction(bool sendToAnyElement);
virtual bool isGenericFormElement() const { return false; }
#include "HTMLFormElement.h"
#include "CString.h"
+#include "Event.h"
#include "EventNames.h"
#include "FormData.h"
#include "FormDataList.h"
HTMLInputElement *element = static_cast<HTMLInputElement *>(formElements[i]);
if (element->isSuccessfulSubmitButton() && element->renderer()) {
submitFound = true;
- element->click(false);
+ element->dispatchSimulatedClick(event);
break;
}
}
}
}
-void HTMLInputElement::click(bool sendMouseEvents, bool showPressedLook)
-{
- switch (inputType()) {
- case BUTTON:
- case CHECKBOX:
- case IMAGE:
- case ISINDEX:
- case PASSWORD:
- case RADIO:
- case RANGE:
- case RESET:
- case SEARCH:
- case SUBMIT:
- case TEXT:
- break;
- case FILE:
- if (renderer()) {
- static_cast<RenderFileUploadControl*>(renderer())->click(sendMouseEvents);
- return;
- }
- break;
- case HIDDEN:
- // a no-op for this type
- return;
- }
- HTMLGenericFormElement::click(sendMouseEvents, showPressedLook);
-}
-
void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
{
switch (inputType()) {
// focus
focus();
// send the mouse button events iff the caller specified sendToAnyElement
- click(sendToAnyElement);
+ dispatchSimulatedClick(0, sendToAnyElement);
break;
case HIDDEN:
// a no-op for this type
}
}
-void HTMLInputElement::defaultEventHandler(Event *evt)
+void HTMLInputElement::defaultEventHandler(Event* evt)
{
if (inputType() == IMAGE && evt->isMouseEvent() && evt->type() == clickEvent) {
// record the mouse position for when we get the DOMActivate event
- MouseEvent *me = static_cast<MouseEvent*>(evt);
+ MouseEvent* me = static_cast<MouseEvent*>(evt);
// FIXME: We could just call offsetX() and offsetY() on the event,
// but that's currently broken, so for now do the computation here.
if (me->isSimulated() || !renderer()) {
// DOMActivate events cause the input to be "activated" - in the case of image and submit inputs, this means
// actually submitting the form. For reset inputs, the form is reset. These events are sent when the user clicks
- // on the element, or presses enter while it is the active element. Javacsript code wishing to activate the element
+ // on the element, or presses enter while it is the active element. JavaScript code wishing to activate the element
// must dispatch a DOMActivate event - a click event will not do the job.
if (evt->type() == DOMActivateEvent && !disabled()) {
if (inputType() == IMAGE || inputType() == SUBMIT || inputType() == RESET) {
m_activeSubmit = false;
}
} else if (inputType() == FILE && renderer())
- static_cast<RenderFileUploadControl*>(renderer())->click(false);
+ static_cast<RenderFileUploadControl*>(renderer())->click();
}
// Use key press event here since sending simulated mouse events
inputElt->isFocusable()) {
inputElt->setChecked(true);
document()->setFocusedNode(inputElt);
- inputElt->click(false, false);
+ inputElt->dispatchSimulatedClick(evt, false, false);
evt->setDefaultHandled();
break;
}
}
if (clickElement) {
- click(false);
+ dispatchSimulatedClick(evt);
evt->setDefaultHandled();
} else if (clickDefaultFormButton && (inputType() != SEARCH || form())) {
if (form()) {
void setSelectionEnd(int);
void select();
void setSelectionRange(int start, int end);
-
- virtual void click(bool sendMouseEvents = false, bool showPressedLook = true);
+
virtual void accessKeyAction(bool sendToAnyElement);
virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
static bool processingClick = false;
if (evt->type() == clickEvent && !processingClick) {
- HTMLElement* element = formElement();
-
+ RefPtr<HTMLElement> element = formElement();
+
// If we can't find a control or if the control received the click
// event, then there's no need for us to do anything.
if (!element || element->contains(evt->target()))
return;
-
+
processingClick = true;
// Click the corresponding control.
- element->click(false);
-
+ element->dispatchSimulatedClick(evt);
+
// If the control can be focused via the mouse, then do that too.
if (element->isMouseFocusable())
element->focus();
-
+
processingClick = false;
}
void HTMLLabelElement::focus()
{
- if (Element *element = formElement())
+ if (Element* element = formElement())
element->focus();
}
void HTMLSelectElement::accessKeyAction(bool sendToAnyElement)
{
- // send the mouse button events iff the
- // caller specified sendToAnyElement
- click(sendToAnyElement);
+ // send the mouse button events iff the caller specified sendToAnyElement
+ dispatchSimulatedClick(0, sendToAnyElement);
}
void HTMLSelectElement::setMultiple(bool multiple)
#include "Attr.h"
#include "Document.h"
-#include "Event.h"
#include "EventNames.h"
#include "Frame.h"
#include "FrameLoader.h"
// FIXME: This malloc could be avoided by walking the tree first to check if any listeners are present: http://bugs.webkit.org/show_bug.cgi?id=10264
RefPtr<Event> event = new Event(loadEvent, false, false);
- event->setTarget(currentTarget.get());
+ event->setTarget(currentTarget);
ExceptionCode ignored = 0;
dispatchGenericEvent(event.release(), ignored, false);
currentTarget = (parent && parent->isSVGElement()) ? static_pointer_cast<SVGElement>(parent) : 0;
#include "Editor.h"
#include "EditorClient.h"
#include "Element.h"
+#include "Event.h"
#include "EventNames.h"
#include "FloatRect.h"
#include "FormState.h"
#include "config.h"
#include "NavigationAction.h"
+#include "Event.h"
+#include "FrameLoader.h"
+
namespace WebCore {
+static NavigationType navigationType(FrameLoadType frameLoadType, bool isFormSubmission, bool haveEvent)
+{
+ if (isFormSubmission)
+ return NavigationTypeFormSubmitted;
+ if (haveEvent)
+ return NavigationTypeLinkClicked;
+ if (frameLoadType == FrameLoadTypeReload)
+ return NavigationTypeReload;
+ if (isBackForwardLoadType(frameLoadType))
+ return NavigationTypeBackForward;
+ return NavigationTypeOther;
+}
+
+NavigationAction::NavigationAction()
+ : m_type(NavigationTypeOther)
+{
+}
+
+NavigationAction::NavigationAction(const KURL& URL, NavigationType type)
+ : m_URL(URL)
+ , m_type(type)
+{
+}
+
+NavigationAction::NavigationAction(const KURL& URL, FrameLoadType frameLoadType,
+ bool isFormSubmission)
+ : m_URL(URL)
+ , m_type(navigationType(frameLoadType, isFormSubmission, 0))
+{
+}
+
+NavigationAction::NavigationAction(const KURL& URL, NavigationType type, PassRefPtr<Event> event)
+ : m_URL(URL)
+ , m_type(type)
+ , m_event(event)
+{
+}
+
+NavigationAction::NavigationAction(const KURL& URL, FrameLoadType frameLoadType,
+ bool isFormSubmission, PassRefPtr<Event> event)
+ : m_URL(URL)
+ , m_type(navigationType(frameLoadType, isFormSubmission, event))
+ , m_event(event)
+{
+}
+
}
#ifndef NavigationAction_h
#define NavigationAction_h
-#include "Event.h"
#include "FrameLoaderTypes.h"
-#include "HitTestResult.h"
#include "KURL.h"
#include <wtf/Forward.h>
#import "DocumentLoader.h"
#import "Document.h"
+#import "Event.h"
#import "FrameLoader.h"
#import "FrameMac.h"
#import "PlatformString.h"
#import "DOMElementInternal.h"
#import "Document.h"
#import "DocumentLoader.h"
+#import "Event.h"
#import "FloatRect.h"
#import "FormDataStreamMac.h"
#import "FormState.h"
+++ /dev/null
-/*
- * Copyright (C) 2006 Apple Computer, 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.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "NavigationAction.h"
-
-#include "FrameLoader.h"
-
-namespace WebCore {
-
-static NavigationType navigationType(FrameLoadType frameLoadType, bool isFormSubmission, bool haveEvent)
-{
- if (isFormSubmission)
- return NavigationTypeFormSubmitted;
- if (haveEvent)
- return NavigationTypeLinkClicked;
- if (frameLoadType == FrameLoadTypeReload)
- return NavigationTypeReload;
- if (isBackForwardLoadType(frameLoadType))
- return NavigationTypeBackForward;
- return NavigationTypeOther;
-}
-
-NavigationAction::NavigationAction()
- : m_type(NavigationTypeOther)
-{
-}
-
-NavigationAction::NavigationAction(const KURL& URL, NavigationType type)
- : m_URL(URL)
- , m_type(type)
-{
-}
-
-NavigationAction::NavigationAction(const KURL& URL, FrameLoadType frameLoadType,
- bool isFormSubmission)
- : m_URL(URL)
- , m_type(navigationType(frameLoadType, isFormSubmission, 0))
-{
-}
-
-NavigationAction::NavigationAction(const KURL& URL, NavigationType type, PassRefPtr<Event> event)
- : m_URL(URL)
- , m_type(type)
- , m_event(event)
-{
-}
-
-NavigationAction::NavigationAction(const KURL& URL, FrameLoadType frameLoadType,
- bool isFormSubmission, PassRefPtr<Event> event)
- : m_URL(URL)
- , m_type(navigationType(frameLoadType, isFormSubmission, event))
- , m_event(event)
-{
-}
-
-}
repaint();
}
-void RenderFileUploadControl::click(bool sendMouseEvents)
+void RenderFileUploadControl::click()
{
m_fileChooser->openFileChooser();
}
virtual void calcMinMaxWidth();
virtual void paintObject(PaintInfo&, int tx, int ty);
- virtual void click(bool sendMouseEvents);
+ void click();
void valueChanged();
#include "AXObjectCache.h"
#include "Document.h"
#include "Element.h"
+#include "Event.h"
#include "EventNames.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+2006-12-01 Darin Adler <darin@apple.com>
+
+ Reviewed by Mitz.
+
+ - fix http://bugs.webkit.org/show_bug.cgi?id=11628
+ REGRESSION (r17597): Command-return in native text fields doesn't open a new tab or window
+
+ * WebCoreSupport/WebFrameLoaderClient.mm:
+ (findKeyStateEvent): Added. Helper that finds the mouse or keyboard event in a chain
+ of events and their underlying events.
+ (findMouseEvent): Added. Same, but specifically for mouse events.
+ (WebFrameLoaderClient::actionDictionary): Rewrote to use the above functions. This means we
+ use the modifiers from the underlying events rather than just the one from the event itself.
+ So if the event is a DOM activate event, we can still see the modifiers from the original
+ keyboard event that triggered it. Has no effect if the event is already the right type or
+ if there is no underlying event.
+
+ * WebView/WebFrame.mm: Added a newly-needed include.
+
+ * WebKit.xcodeproj/project.pbxproj: Xcode wants what it wants.
+
2006-12-01 Don Gibson <dgibson77@gmail.com>
Reviewed by Mitz.
#import <WebCore/FrameLoaderTypes.h>
#import <WebCore/FrameMac.h>
#import <WebCore/FrameTree.h>
+#import <WebCore/HitTestResult.h>
#import <WebCore/IconDatabase.h>
#import <WebCore/MouseEvent.h>
#import <WebCore/Page.h>
return [getWebView(m_webFrame.get()) _userAgent];
}
+static const UIEventWithKeyState* findKeyStateEvent(const Event* event)
+{
+ for (const Event* e = event; e; e = e->underlyingEvent())
+ if (e->isMouseEvent() || e->isKeyboardEvent())
+ return static_cast<const UIEventWithKeyState*>(e);
+ return 0;
+}
+
+static const MouseEvent* findMouseEvent(const Event* event)
+{
+ for (const Event* e = event; e; e = e->underlyingEvent())
+ if (e->isMouseEvent())
+ return static_cast<const MouseEvent*>(e);
+ return 0;
+}
+
NSDictionary *WebFrameLoaderClient::actionDictionary(const NavigationAction& action) const
{
unsigned modifierFlags = 0;
const Event* event = action.event();
- if (event && (event->isMouseEvent() || event->isKeyboardEvent())) {
- if (static_cast<const UIEventWithKeyState*>(event)->ctrlKey())
+ if (const UIEventWithKeyState* keyStateEvent = findKeyStateEvent(event)) {
+ if (keyStateEvent->ctrlKey())
modifierFlags |= NSControlKeyMask;
- if (static_cast<const UIEventWithKeyState*>(event)->altKey())
+ if (keyStateEvent->altKey())
modifierFlags |= NSAlternateKeyMask;
- if (static_cast<const UIEventWithKeyState*>(event)->shiftKey())
+ if (keyStateEvent->shiftKey())
modifierFlags |= NSShiftKeyMask;
- if (static_cast<const UIEventWithKeyState*>(event)->metaKey())
+ if (keyStateEvent->metaKey())
modifierFlags |= NSCommandKeyMask;
}
- if (event && event->isMouseEvent()) {
- IntPoint point(static_cast<const MouseEvent*>(event)->clientX(),
- static_cast<const MouseEvent*>(event)->clientY());
+ if (const MouseEvent* mouseEvent = findMouseEvent(event)) {
+ IntPoint point(mouseEvent->clientX(), mouseEvent->clientY());
WebElementDictionary *element = [[WebElementDictionary alloc]
initWithHitTestResult:core(m_webFrame.get())->eventHandler()->hitTestResultAtPoint(point, false)];
NSDictionary *result = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:action.type()], WebActionNavigationTypeKey,
element, WebActionElementKey,
- [NSNumber numberWithInt:static_cast<const MouseEvent*>(event)->button()], WebActionButtonKey,
+ [NSNumber numberWithInt:mouseEvent->button()], WebActionButtonKey,
[NSNumber numberWithInt:modifierFlags], WebActionModifierFlagsKey,
action.URL().getNSURL(), WebActionOriginalURLKey,
nil];
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 149C283208902B0F008A9EFC /* Build configuration list for PBXProject "WebKit" */;
- compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
knownRegions = (
English,
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
- shouldCheckCompatibility = 1;
targets = (
9398100A0824BF01008DF038 /* WebKit */,
);
#import "WebViewInternal.h"
#import <WebCore/Chrome.h>
#import <WebCore/Document.h>
+#import <WebCore/Event.h>
#import <WebCore/FrameLoader.h>
#import <WebCore/FrameMac.h>
#import <WebCore/FrameTree.h>