Commit f1bb004d authored by darin's avatar darin

WebCore:

        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: http://svn.webkit.org/repository/webkit/trunk@17976 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 66ae4f91
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
......@@ -1510,7 +1510,6 @@
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, ); }; };
......@@ -4498,7 +4497,6 @@
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>"; };
......@@ -7700,7 +7698,6 @@
6563A9A50ADF4094000ED2CD /* LoaderNSURLRequestExtras.h */,
6563A9A60ADF4094000ED2CD /* LoaderNSURLRequestExtras.m */,
656D372A0ADBA5DE00A4554D /* MainResourceLoaderMac.mm */,
93CCF0570AF6C9FE00018E89 /* NavigationActionMac.mm */,
656D372C0ADBA5DE00A4554D /* NetscapePlugInStreamLoaderMac.mm */,
656D37280ADBA5DE00A4554D /* ResourceLoaderMac.mm */,
656D37310ADBA5DE00A4554D /* SubresourceLoaderMac.mm */,
......@@ -10838,7 +10835,6 @@
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
knownRegions = (
English,
......@@ -10853,7 +10849,6 @@
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
shouldCheckCompatibility = 1;
targets = (
93F198A508245E59001E9ABC /* WebCore */,
DD041FBE09D9DDBE0010AF2A /* Derived Sources */,
......@@ -11993,7 +11988,6 @@
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 */,
......@@ -396,7 +396,7 @@ JSValue *DOMEvent::getValueProperty(ExecState *exec, int token) const
case Bubbles:
return jsBoolean(event.bubbles());
case CancelBubble:
return jsBoolean(event.getCancelBubble());
return jsBoolean(event.cancelBubble());
case ReturnValue:
return jsBoolean(!event.defaultPrevented());
case Cancelable:
......
......@@ -1607,7 +1607,7 @@ bool FrameMac::shouldClose()
return true;
RefPtr<BeforeUnloadEvent> event = new BeforeUnloadEvent;
event->setTarget(doc.get());
event->setTarget(doc);
doc->handleWindowEvent(event.get(), false);
if (!event->defaultPrevented() && doc)
......
......@@ -133,10 +133,10 @@ void Event::storeResult(const String&)
{
}
void Event::setTarget(Node* target)
void Event::setTarget(PassRefPtr<Node> target)
{
m_target = target;
if (target)
if (m_target)
receivedTarget();
}
......@@ -144,4 +144,13 @@ void Event::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
......@@ -48,7 +48,6 @@ namespace WebCore {
BUBBLING_PHASE = 3
};
// Reverse-engineered from Netscape
enum EventType {
MOUSEDOWN = 1,
MOUSEUP = 2,
......@@ -67,24 +66,24 @@ namespace WebCore {
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; }
......@@ -102,18 +101,21 @@ namespace WebCore {
#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&);
......@@ -132,10 +134,12 @@ namespace WebCore {
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
......
......@@ -231,7 +231,7 @@ bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> e, ExceptionCode&,
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);
}
......@@ -239,7 +239,7 @@ bool EventTargetNode::dispatchGenericEvent(PassRefPtr<Event> e, ExceptionCode&,
// 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);
}
......@@ -320,7 +320,7 @@ void EventTargetNode::dispatchWindowEvent(const AtomicString &eventType, bool ca
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);
......@@ -337,7 +337,7 @@ void EventTargetNode::dispatchWindowEvent(const AtomicString &eventType, bool ca
}
}
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);
......@@ -345,8 +345,9 @@ bool EventTargetNode::dispatchUIEvent(const AtomicString &eventType, int detail)
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)
......@@ -365,33 +366,49 @@ 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..
......@@ -415,9 +432,10 @@ bool EventTargetNode::dispatchMouseEvent(const AtomicString& eventType, int butt
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();
......@@ -433,6 +451,7 @@ bool EventTargetNode::dispatchMouseEvent(const AtomicString& eventType, int butt
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);
......@@ -442,7 +461,7 @@ bool EventTargetNode::dispatchMouseEvent(const AtomicString& eventType, int butt
// 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;
}
......
......@@ -52,7 +52,7 @@ public:
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,
......@@ -60,8 +60,9 @@ public:
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);
......
......@@ -182,7 +182,7 @@ void HTMLAnchorElement::defaultEventHandler(Event* evt)
}
if (k->keyEvent()) {
evt->setDefaultHandled();
click(false);
dispatchSimulatedClick(0);
return;
}
}
......@@ -287,9 +287,8 @@ void HTMLAnchorElement::parseMappedAttribute(MappedAttribute *attr)
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
......
......@@ -129,9 +129,8 @@ bool HTMLButtonElement::appendFormData(FormDataList& encoding, bool /*multipart*
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
......
......@@ -28,6 +28,7 @@
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "DocumentFragment.h"
#include "Event.h"
#include "EventListener.h"
#include "EventNames.h"
#include "ExceptionCode.h"
......@@ -584,18 +585,9 @@ void HTMLElement::setContentEditable(const String &enabled)
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
......@@ -608,7 +600,7 @@ void HTMLElement::click(bool sendMouseEvents, bool showPressedLook)
void HTMLElement::accessKeyAction(bool sendToAnyElement)
{
if (sendToAnyElement)
click(true);
dispatchSimulatedClick(0, true);
}
String HTMLElement::toString() const
......
......@@ -80,7 +80,8 @@ public:
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; }
......
......@@ -28,6 +28,7 @@
#include "HTMLFormElement.h"
#include "CString.h"
#include "Event.h"
#include "EventNames.h"
#include "FormData.h"
#include "FormDataList.h"
......@@ -133,7 +134,7 @@ void HTMLFormElement::submitClick(Event* event)
HTMLInputElement *element = static_cast<HTMLInputElement *>(formElements[i]);
if (element->isSuccessfulSubmitButton() && element->renderer()) {
submitFound = true;
element->click(false);
element->dispatchSimulatedClick(event);
break;
}
}
......
......@@ -628,34 +628,6 @@ void HTMLInputElement::setSelectionRange(int start, int end)
}
}
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()) {
......@@ -670,7 +642,7 @@ void HTMLInputElement::accessKeyAction(bool sendToAnyElement)
// 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
......@@ -1219,11 +1191,11 @@ void HTMLInputElement::postDispatchEventHandler(Event *evt, void* data)
}
}
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()) {
......@@ -1240,7 +1212,7 @@ void HTMLInputElement::defaultEventHandler(Event *evt)
// 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) {
......@@ -1257,7 +1229,7 @@ void HTMLInputElement::defaultEventHandler(Event *evt)
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
......@@ -1356,7 +1328,7 @@ void HTMLInputElement::defaultEventHandler(Event *evt)
inputElt->isFocusable()) {
inputElt->setChecked(true);
document()->setFocusedNode(inputElt);
inputElt->click(false, false);
inputElt->dispatchSimulatedClick(evt, false, false);
evt->setDefaultHandled();
break;
}
......@@ -1366,7 +1338,7 @@ void HTMLInputElement::defaultEventHandler(Event *evt)