summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebCore/Android.mk2
-rw-r--r--WebCore/bindings/js/JSEventCustom.cpp4
-rw-r--r--WebCore/bindings/js/ScriptController.cpp2
-rw-r--r--WebCore/dom/Document.cpp62
-rw-r--r--WebCore/dom/Document.h22
-rw-r--r--WebCore/dom/Document.idl12
-rw-r--r--WebCore/dom/Element.h7
-rw-r--r--WebCore/dom/Element.idl12
-rw-r--r--WebCore/dom/Event.cpp10
-rw-r--r--WebCore/dom/Event.h6
-rw-r--r--WebCore/dom/EventNames.h17
-rw-r--r--WebCore/dom/Node.cpp32
-rw-r--r--WebCore/dom/Node.h7
-rw-r--r--WebCore/dom/Touch.cpp6
-rw-r--r--WebCore/dom/Touch.h64
-rw-r--r--WebCore/dom/TouchEvent.cpp16
-rw-r--r--WebCore/dom/TouchEvent.h106
-rw-r--r--WebCore/dom/TouchEvent.idl10
-rw-r--r--WebCore/dom/TouchList.cpp2
-rw-r--r--WebCore/dom/TouchList.h28
-rw-r--r--WebCore/html/HTMLAttributeNames.in2
-rw-r--r--WebCore/html/HTMLElement.cpp14
-rw-r--r--WebCore/page/ChromeClient.h4
-rw-r--r--WebCore/page/DOMWindow.h5
-rw-r--r--WebCore/page/DOMWindow.idl19
-rw-r--r--WebCore/page/EventHandler.cpp333
-rw-r--r--WebCore/page/EventHandler.h33
-rw-r--r--WebCore/platform/PlatformTouchEvent.h127
-rw-r--r--WebCore/platform/PlatformTouchPoint.h69
-rw-r--r--WebCore/platform/android/PlatformTouchEventAndroid.cpp39
-rw-r--r--WebCore/platform/android/PlatformTouchPointAndroid.cpp37
-rw-r--r--WebCore/plugins/android/PluginViewAndroid.cpp27
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp10
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.h4
-rw-r--r--WebKit/android/jni/WebViewCore.cpp59
-rw-r--r--WebKit/android/jni/WebViewCore.h7
-rw-r--r--WebKit/android/plugins/PluginWidgetAndroid.cpp19
37 files changed, 778 insertions, 457 deletions
diff --git a/WebCore/Android.mk b/WebCore/Android.mk
index 19e3fd2..7c3781a 100644
--- a/WebCore/Android.mk
+++ b/WebCore/Android.mk
@@ -402,6 +402,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/android/GeolocationServiceBridge.cpp \
platform/android/KeyEventAndroid.cpp \
platform/android/LocalizedStringsAndroid.cpp \
+ platform/android/PlatformTouchEventAndroid.cpp \
+ platform/android/PlatformTouchPointAndroid.cpp \
platform/android/PopupMenuAndroid.cpp \
platform/android/RenderThemeAndroid.cpp \
platform/android/ScreenAndroid.cpp \
diff --git a/WebCore/bindings/js/JSEventCustom.cpp b/WebCore/bindings/js/JSEventCustom.cpp
index 7b951bd..04ceec5 100644
--- a/WebCore/bindings/js/JSEventCustom.cpp
+++ b/WebCore/bindings/js/JSEventCustom.cpp
@@ -78,7 +78,7 @@
#include "SVGZoomEvent.h"
#endif
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
#include "JSTouchEvent.h"
#include "TouchEvent.h"
#endif
@@ -118,7 +118,7 @@ JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, Event* event)
#endif
else if (event->isCompositionEvent())
wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, CompositionEvent, event);
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
else if (event->isTouchEvent())
wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, TouchEvent, event);
#endif
diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp
index 89f2345..8d34f88 100644
--- a/WebCore/bindings/js/ScriptController.cpp
+++ b/WebCore/bindings/js/ScriptController.cpp
@@ -247,7 +247,7 @@ bool ScriptController::processingUserGestureEvent() const
// keyboard events
|| type == eventNames().keydownEvent || type == eventNames().keypressEvent
|| type == eventNames().keyupEvent
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
// touch events
|| type == eventNames().touchstartEvent || type == eventNames().touchmoveEvent
|| type == eventNames().touchendEvent || type == eventNames().touchcancelEvent
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index 69b326a..d031853 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -171,12 +171,10 @@
#include "SVGStyleElement.h"
#endif
-#if ENABLE(TOUCH_EVENTS) // Android
-#include "TouchEvent.h"
#if PLATFORM(ANDROID)
+// FIXME: We shouldn't be including this from WebCore!
#include "WebViewCore.h"
#endif
-#endif
#ifdef ANDROID_META_SUPPORT
#include "Settings.h"
@@ -191,6 +189,11 @@
#include "TimeCounter.h"
#endif
+#if ENABLE(TOUCH_EVENTS)
+#include "ChromeClient.h"
+#include "TouchEvent.h"
+#endif
+
#if ENABLE(WML)
#include "WMLDocument.h"
#include "WMLElement.h"
@@ -1484,17 +1487,6 @@ void Document::detach()
FrameView* view = m_frame->view();
if (view)
view->detachCustomScrollbars();
-
-#if ENABLE(TOUCH_EVENTS) // Android
- // clean up for the top document
- if (!m_frame->ownerElement()) {
- m_touchEventListeners.clear();
-#if PLATFORM(ANDROID)
- if (view)
- android::WebViewCore::getWebViewCore(view)->needTouchEvents(false);
-#endif
- }
-#endif
}
// indicate destruction mode, i.e. attached() but renderer == 0
@@ -3062,7 +3054,7 @@ PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionCode&
else if (eventType == "SVGZoomEvents")
event = SVGZoomEvent::create();
#endif
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
else if (eventType == "TouchEvent")
event = TouchEvent::create();
#endif
@@ -3102,6 +3094,14 @@ void Document::addListenerTypeIfNeeded(const AtomicString& eventType)
addListenerType(TRANSITIONEND_LISTENER);
else if (eventType == eventNames().beforeloadEvent)
addListenerType(BEFORELOAD_LISTENER);
+ else if (eventType == eventNames().touchstartEvent
+ || eventType == eventNames().touchmoveEvent
+ || eventType == eventNames().touchendEvent
+ || eventType == eventNames().touchcancelEvent) {
+ addListenerType(TOUCH_LISTENER);
+ if (Page* page = this->page())
+ page->chrome()->client()->needTouchEvents(true);
+ }
}
CSSStyleDeclaration* Document::getOverrideStyle(Element*, const String&)
@@ -4673,38 +4673,6 @@ void Document::parseDNSPrefetchControlHeader(const String& dnsPrefetchControl)
m_haveExplicitlyDisabledDNSPrefetch = true;
}
-#if ENABLE(TOUCH_EVENTS) // Android
-void Document::addTouchEventListener(Node* node)
-{
- // Note: we only keep track of touch listener in the top frame
- if (m_frame && m_frame->tree()->parent()) {
- m_frame->page()->mainFrame()->document()->addTouchEventListener(node);
- } else {
-#if PLATFORM(ANDROID)
- if (m_frame && m_frame->view() && m_touchEventListeners.isEmpty())
- android::WebViewCore::getWebViewCore(m_frame->view())->needTouchEvents(true);
-#endif
- m_touchEventListeners.add(node, 0);
- }
-}
-
-void Document::removeTouchEventListener(Node* node)
-{
- // Note: we only keep track of touch listener in the top frame
- if (m_frame && m_frame->tree()->parent()) {
- m_frame->page()->mainFrame()->document()->removeTouchEventListener(node);
- } else {
-#if PLATFORM(ANDROID)
- if (m_frame && m_frame->view() && m_touchEventListeners.size() == 1 &&
- m_touchEventListeners.contains(node))
- android::WebViewCore::getWebViewCore(m_frame->view())->needTouchEvents(false);
-#endif
- m_touchEventListeners.remove(node);
- }
-}
-
-#endif
-
void Document::reportException(const String& errorMessage, int lineNumber, const String& sourceURL)
{
if (DOMWindow* window = domWindow())
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index f2125b1..b24063a 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -252,6 +252,12 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
+#if ENABLE(TOUCH_EVENTS)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
+#endif
DocumentType* doctype() const { return m_docType.get(); }
@@ -624,7 +630,8 @@ public:
ANIMATIONSTART_LISTENER = 0x200,
ANIMATIONITERATION_LISTENER = 0x400,
TRANSITIONEND_LISTENER = 0x800,
- BEFORELOAD_LISTENER = 0x1000
+ BEFORELOAD_LISTENER = 0x1000,
+ TOUCH_LISTENER = 0x2000
};
bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); }
@@ -937,17 +944,6 @@ protected:
void clearXMLVersion() { m_xmlVersion = String(); }
-#if ENABLE(TOUCH_EVENTS) // Android
-public:
- typedef HashMap<Node*, unsigned > TouchListenerMap;
-
- void addTouchEventListener(Node*);
- void removeTouchEventListener(Node*);
- const TouchListenerMap& touchEventListeners() const { return m_touchEventListeners; }
-
-private:
- TouchListenerMap m_touchEventListeners;
-#endif // ENABLE(TOUCH_EVENTS)
private:
virtual bool isDocument() const { return true; }
@@ -1120,7 +1116,7 @@ private:
#if ENABLE(XBL)
OwnPtr<XBLBindingManager> m_bindingManager; // The access point through which documents and elements communicate with XBL.
#endif
-
+
typedef HashMap<AtomicStringImpl*, HTMLMapElement*> ImageMapsByName;
ImageMapsByName m_imageMapsByName;
diff --git a/WebCore/dom/Document.idl b/WebCore/dom/Document.idl
index e54add0..69417c8 100644
--- a/WebCore/dom/Document.idl
+++ b/WebCore/dom/Document.idl
@@ -284,12 +284,6 @@ module core {
attribute [DontEnum] EventListener onscroll;
attribute [DontEnum] EventListener onselect;
attribute [DontEnum] EventListener onsubmit;
-#if ENABLE_TOUCH_EVENTS
- attribute [DontEnum] EventListener ontouchstart;
- attribute [DontEnum] EventListener ontouchend;
- attribute [DontEnum] EventListener ontouchmove;
- attribute [DontEnum] EventListener ontouchcancel;
-#endif
// attribute [DontEnum] EventListener oncanplay;
// attribute [DontEnum] EventListener oncanplaythrough;
@@ -326,6 +320,12 @@ module core {
attribute [DontEnum] EventListener onreset;
attribute [DontEnum] EventListener onsearch;
attribute [DontEnum] EventListener onselectstart;
+#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
+ attribute [DontEnum] EventListener ontouchstart;
+ attribute [DontEnum] EventListener ontouchmove;
+ attribute [DontEnum] EventListener ontouchend;
+ attribute [DontEnum] EventListener ontouchcancel;
+#endif
#endif
#endif
};
diff --git a/WebCore/dom/Element.h b/WebCore/dom/Element.h
index 97d3eb4..ce25d70 100644
--- a/WebCore/dom/Element.h
+++ b/WebCore/dom/Element.h
@@ -88,7 +88,12 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
DEFINE_ATTRIBUTE_EVENT_LISTENER(selectstart);
-
+#if ENABLE(TOUCH_EVENTS)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
+#endif
const AtomicString& getIDAttribute() const;
bool hasAttribute(const QualifiedName&) const;
const AtomicString& getAttribute(const QualifiedName&) const;
diff --git a/WebCore/dom/Element.idl b/WebCore/dom/Element.idl
index c24ef65..4a223bb 100644
--- a/WebCore/dom/Element.idl
+++ b/WebCore/dom/Element.idl
@@ -167,12 +167,6 @@ module core {
attribute [DontEnum] EventListener onscroll;
attribute [DontEnum] EventListener onselect;
attribute [DontEnum] EventListener onsubmit;
-#if ENABLE_TOUCH_EVENTS
- attribute [DontEnum] EventListener ontouchstart;
- attribute [DontEnum] EventListener ontouchend;
- attribute [DontEnum] EventListener ontouchmove;
- attribute [DontEnum] EventListener ontouchcancel;
-#endif
// attribute [DontEnum] EventListener oncanplay;
// attribute [DontEnum] EventListener oncanplaythrough;
@@ -209,6 +203,12 @@ module core {
attribute [DontEnum] EventListener onreset;
attribute [DontEnum] EventListener onsearch;
attribute [DontEnum] EventListener onselectstart;
+#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
+ attribute [DontEnum] EventListener ontouchstart;
+ attribute [DontEnum] EventListener ontouchmove;
+ attribute [DontEnum] EventListener ontouchend;
+ attribute [DontEnum] EventListener ontouchcancel;
+#endif
#endif
#endif
};
diff --git a/WebCore/dom/Event.cpp b/WebCore/dom/Event.cpp
index eda44b0..be2b37b 100644
--- a/WebCore/dom/Event.cpp
+++ b/WebCore/dom/Event.cpp
@@ -180,20 +180,20 @@ bool Event::isStorageEvent() const
}
#endif
-#if ENABLE(TOUCH_EVENTS) // Android
-bool Event::isTouchEvent() const
+#if ENABLE(WORKERS)
+bool Event::isErrorEvent() const
{
return false;
}
#endif
-#if ENABLE(WORKERS)
-bool Event::isErrorEvent() const
+#if ENABLE(TOUCH_EVENTS)
+bool Event::isTouchEvent() const
{
return false;
}
#endif
-
+
bool Event::storesResultAsString() const
{
return false;
diff --git a/WebCore/dom/Event.h b/WebCore/dom/Event.h
index 7ec85a7..4624663 100644
--- a/WebCore/dom/Event.h
+++ b/WebCore/dom/Event.h
@@ -123,12 +123,12 @@ namespace WebCore {
#if ENABLE(DOM_STORAGE)
virtual bool isStorageEvent() const;
#endif
-#if ENABLE(TOUCH_EVENTS) // Android
- virtual bool isTouchEvent() const;
-#endif
#if ENABLE(WORKERS)
virtual bool isErrorEvent() const;
#endif
+#if ENABLE(TOUCH_EVENTS)
+ virtual bool isTouchEvent() const;
+#endif
bool propagationStopped() const { return m_propagationStopped; }
diff --git a/WebCore/dom/EventNames.h b/WebCore/dom/EventNames.h
index 63460a5..c8c3291 100644
--- a/WebCore/dom/EventNames.h
+++ b/WebCore/dom/EventNames.h
@@ -95,14 +95,6 @@ namespace WebCore {
macro(storage) \
macro(submit) \
macro(textInput) \
-/* #if ENABLE(TOUCH_EVENTS) // Android */ \
- macro(touchstart) \
- macro(touchmove) \
- macro(touchend) \
- macro(touchcancel) \
- macro(touchlongpress) \
- macro(touchdoubletap) \
-/* #endif */ \
macro(unload) \
macro(updateready) \
macro(zoom) \
@@ -154,6 +146,15 @@ namespace WebCore {
\
macro(orientationchange) \
\
+ macro(touchstart) \
+ macro(touchmove) \
+ macro(touchend) \
+ macro(touchcancel) \
+/* #if PLATFORM(ANDROID) */ \
+ macro(touchlongpress) \
+ macro(touchdoubletap) \
+/* #endif */ \
+ \
// end of DOM_EVENT_NAMES_FOR_EACH
class EventNames : public Noncopyable {
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index 4ae83de..c2d5281 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -101,6 +101,10 @@
#include "HTMLNoScriptElement.h"
#endif
+#if ENABLE(TOUCH_EVENTS)
+#include "ChromeClient.h"
+#endif
+
#define DUMP_NODE_STATISTICS 0
using namespace std;
@@ -2422,16 +2426,8 @@ bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListe
if (Document* document = this->document())
document->addListenerTypeIfNeeded(eventType);
- updateSVGElementInstancesAfterEventListenerChange(this);
-#if ENABLE(TOUCH_EVENTS) // Android
- if (this->document() &&
- (eventType == eventNames().touchstartEvent ||
- eventType == eventNames().touchendEvent ||
- eventType == eventNames().touchmoveEvent ||
- eventType == eventNames().touchcancelEvent))
- this->document()->addTouchEventListener(this);
-#endif
+ updateSVGElementInstancesAfterEventListenerChange(this);
return true;
}
@@ -2442,13 +2438,17 @@ bool Node::removeEventListener(const AtomicString& eventType, EventListener* lis
updateSVGElementInstancesAfterEventListenerChange(this);
-#if ENABLE(TOUCH_EVENTS) // Android
- if (this->document() &&
- (eventType == eventNames().touchstartEvent ||
- eventType == eventNames().touchendEvent ||
- eventType == eventNames().touchmoveEvent ||
- eventType == eventNames().touchcancelEvent))
- this->document()->removeTouchEventListener(this);
+#if ENABLE(TOUCH_EVENTS)
+ if (Document* document = this->document()) {
+ if (document->page()
+ && (eventType == eventNames().touchstartEvent
+ || eventType == eventNames().touchmoveEvent
+ || eventType == eventNames().touchendEvent
+ || eventType == eventNames().touchcancelEvent))
+ // Note the corresponding needTouchEvents(true) is called in Document::addListenerTypeIfNeeded().
+ document->page()->chrome()->client()->needTouchEvents(false);
+
+ }
#endif
return true;
}
diff --git a/WebCore/dom/Node.h b/WebCore/dom/Node.h
index 7da8634..ebf275a 100644
--- a/WebCore/dom/Node.h
+++ b/WebCore/dom/Node.h
@@ -565,13 +565,6 @@ public:
*/
virtual bool disabled() const;
-#if ENABLE(TOUCH_EVENTS) // Android
- DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
-#endif
-
using TreeShared<Node>::ref;
using TreeShared<Node>::deref;
diff --git a/WebCore/dom/Touch.cpp b/WebCore/dom/Touch.cpp
index 561a786..41d5c19 100644
--- a/WebCore/dom/Touch.cpp
+++ b/WebCore/dom/Touch.cpp
@@ -25,7 +25,7 @@
#include "config.h"
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
#include "Touch.h"
@@ -40,7 +40,7 @@ static int contentsX(Frame* frame)
FrameView* frameView = frame->view();
if (!frameView)
return 0;
- return frameView->scrollX();
+ return frameView->scrollX() / frame->pageZoomFactor();
}
static int contentsY(Frame* frame)
@@ -50,7 +50,7 @@ static int contentsY(Frame* frame)
FrameView* frameView = frame->view();
if (!frameView)
return 0;
- return frameView->scrollY();
+ return frameView->scrollY() / frame->pageZoomFactor();
}
Touch::Touch(Frame* frame, EventTarget* target, unsigned identifier,
diff --git a/WebCore/dom/Touch.h b/WebCore/dom/Touch.h
index 62822fb..cf39faf 100644
--- a/WebCore/dom/Touch.h
+++ b/WebCore/dom/Touch.h
@@ -26,7 +26,7 @@
#ifndef TOUCH_H_
#define TOUCH_H_
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
#include "EventTarget.h"
#include "Frame.h"
@@ -36,41 +36,41 @@
namespace WebCore {
- class Touch : public RefCounted<Touch> {
- public:
- static PassRefPtr<Touch> create(Frame* frame, EventTarget* target,
- unsigned identifier, int screenX, int screenY, int pageX, int pageY)
- {
- return adoptRef(new Touch(frame, target, identifier, screenX,
- screenY, pageX, pageY));
- }
+class Touch : public RefCounted<Touch> {
+public:
+ static PassRefPtr<Touch> create(Frame* frame, EventTarget* target,
+ unsigned identifier, int screenX, int screenY, int pageX, int pageY)
+ {
+ return adoptRef(new Touch(frame, target, identifier, screenX,
+ screenY, pageX, pageY));
+ }
- void updateLocation(int screenX, int screenY, int pageX, int pageY);
+ void updateLocation(int screenX, int screenY, int pageX, int pageY);
- Frame* frame() const { return m_frame.get(); }
- EventTarget* target() const { return m_target.get(); }
- unsigned identifier() const { return m_identifier; }
- int clientX() const { return m_clientX; }
- int clientY() const { return m_clientY; }
- int screenX() const { return m_screenX; }
- int screenY() const { return m_screenY; }
- int pageX() const { return m_pageX; }
- int pageY() const { return m_pageY; }
+ Frame* frame() const { return m_frame.get(); }
+ EventTarget* target() const { return m_target.get(); }
+ unsigned identifier() const { return m_identifier; }
+ int clientX() const { return m_clientX; }
+ int clientY() const { return m_clientY; }
+ int screenX() const { return m_screenX; }
+ int screenY() const { return m_screenY; }
+ int pageX() const { return m_pageX; }
+ int pageY() const { return m_pageY; }
- private:
- Touch(Frame* frame, EventTarget* target, unsigned identifier,
- int screenX, int screenY, int pageX, int pageY);
+private:
+ Touch(Frame* frame, EventTarget* target, unsigned identifier,
+ int screenX, int screenY, int pageX, int pageY);
- RefPtr<Frame> m_frame;
- RefPtr<EventTarget> m_target;
- unsigned m_identifier;
- int m_clientX;
- int m_clientY;
- int m_screenX;
- int m_screenY;
- int m_pageX;
- int m_pageY;
- };
+ RefPtr<Frame> m_frame;
+ RefPtr<EventTarget> m_target;
+ unsigned m_identifier;
+ int m_clientX;
+ int m_clientY;
+ int m_screenX;
+ int m_screenY;
+ int m_pageX;
+ int m_pageY;
+};
} // namespace WebCore
diff --git a/WebCore/dom/TouchEvent.cpp b/WebCore/dom/TouchEvent.cpp
index 7ce856f..1fbba6c 100644
--- a/WebCore/dom/TouchEvent.cpp
+++ b/WebCore/dom/TouchEvent.cpp
@@ -25,7 +25,7 @@
#include "config.h"
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
#include "TouchEvent.h"
@@ -33,20 +33,24 @@ namespace WebCore {
TouchEvent::TouchEvent(TouchList* touches, TouchList* targetTouches,
TouchList* changedTouches, const AtomicString& type,
- PassRefPtr<AbstractView> view, int screenX, int screenY, int pageX, int pageY)
+ PassRefPtr<AbstractView> view, int screenX, int screenY, int pageX, int pageY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
: MouseRelatedEvent(type, true, true, view, 0, screenX, screenY, pageX, pageY,
- false, false, false, false)
+ ctrlKey, altKey, shiftKey, metaKey)
, m_touches(touches)
, m_targetTouches(targetTouches)
, m_changedTouches(changedTouches)
+#if PLATFORM(ANDROID)
, m_longPressPrevented(false)
, m_doubleTapPrevented(false)
+#endif
{
}
void TouchEvent::initTouchEvent(TouchList* touches, TouchList* targetTouches,
TouchList* changedTouches, const AtomicString& type,
- PassRefPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY)
+ PassRefPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
{
if (dispatched())
return;
@@ -55,6 +59,10 @@ void TouchEvent::initTouchEvent(TouchList* touches, TouchList* targetTouches,
m_screenX = screenX;
m_screenY = screenY;
+ m_ctrlKey = ctrlKey;
+ m_altKey = altKey;
+ m_shiftKey = shiftKey;
+ m_metaKey = metaKey;
initCoordinates(clientX, clientY);
}
diff --git a/WebCore/dom/TouchEvent.h b/WebCore/dom/TouchEvent.h
index 6b7d384..abc1ee2 100644
--- a/WebCore/dom/TouchEvent.h
+++ b/WebCore/dom/TouchEvent.h
@@ -26,61 +26,69 @@
#ifndef TouchEvent_h
#define TouchEvent_h
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
#include "MouseRelatedEvent.h"
#include "TouchList.h"
namespace WebCore {
- class TouchEvent : public MouseRelatedEvent {
- public:
- static PassRefPtr<TouchEvent> create()
- {
- return adoptRef(new TouchEvent);
- }
- static PassRefPtr<TouchEvent> create(TouchList* touches,
- TouchList* targetTouches, TouchList* changedTouches,
- const AtomicString& type, PassRefPtr<AbstractView> view,
- int screenX, int screenY, int pageX, int pageY)
- {
- return adoptRef(new TouchEvent(touches, targetTouches, changedTouches,
- type, view, screenX, screenY, pageX, pageY));
- }
-
- void initTouchEvent(TouchList* touches, TouchList* targetTouches,
- TouchList* changedTouches, const AtomicString& type,
- PassRefPtr<AbstractView> view, int screenX, int screenY,
- int clientX, int clientY);
-
- TouchList* touches() const {return m_touches.get();}
- TouchList* targetTouches() const {return m_targetTouches.get();}
- TouchList* changedTouches() const {return m_changedTouches.get();}
-
- bool longPressPrevented() const { return m_longPressPrevented; }
- void preventLongPress() { m_longPressPrevented = true; }
- void setLongPressPrevented(bool prevented) { m_longPressPrevented = prevented; }
-
- bool doubleTapPrevented() const { return m_doubleTapPrevented; }
- void preventDoubleTap() { m_doubleTapPrevented = true; }
- void setDoubleTapPrevented(bool prevented) { m_doubleTapPrevented = prevented; }
-
- private:
- TouchEvent() {}
- TouchEvent(TouchList* touches, TouchList* targetTouches,
- TouchList* changedTouches, const AtomicString& type,
- PassRefPtr<AbstractView>, int screenX, int screenY, int pageX,
- int pageY);
-
- virtual bool isTouchEvent() const {return true;}
-
- RefPtr<TouchList> m_touches;
- RefPtr<TouchList> m_targetTouches;
- RefPtr<TouchList> m_changedTouches;
-
- bool m_longPressPrevented;
- bool m_doubleTapPrevented;
- };
+class TouchEvent : public MouseRelatedEvent {
+public:
+ static PassRefPtr<TouchEvent> create()
+ {
+ return adoptRef(new TouchEvent);
+ }
+ static PassRefPtr<TouchEvent> create(TouchList* touches,
+ TouchList* targetTouches, TouchList* changedTouches,
+ const AtomicString& type, PassRefPtr<AbstractView> view,
+ int screenX, int screenY, int pageX, int pageY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
+ {
+ return adoptRef(new TouchEvent(touches, targetTouches, changedTouches,
+ type, view, screenX, screenY, pageX, pageY,
+ ctrlKey, altKey, shiftKey, metaKey));
+ }
+
+ void initTouchEvent(TouchList* touches, TouchList* targetTouches,
+ TouchList* changedTouches, const AtomicString& type,
+ PassRefPtr<AbstractView> view, int screenX, int screenY,
+ int clientX, int clientY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
+
+ TouchList* touches() const { return m_touches.get(); }
+ TouchList* targetTouches() const { return m_targetTouches.get(); }
+ TouchList* changedTouches() const { return m_changedTouches.get(); }
+
+#if PLATFORM(ANDROID)
+ bool longPressPrevented() const { return m_longPressPrevented; }
+ void preventLongPress() { m_longPressPrevented = true; }
+ void setLongPressPrevented(bool prevented) { m_longPressPrevented = prevented; }
+
+ bool doubleTapPrevented() const { return m_doubleTapPrevented; }
+ void preventDoubleTap() { m_doubleTapPrevented = true; }
+ void setDoubleTapPrevented(bool prevented) { m_doubleTapPrevented = prevented; }
+#endif
+
+private:
+ TouchEvent() {}
+ TouchEvent(TouchList* touches, TouchList* targetTouches,
+ TouchList* changedTouches, const AtomicString& type,
+ PassRefPtr<AbstractView>, int screenX, int screenY, int pageX,
+ int pageY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
+
+ virtual bool isTouchEvent() const { return true; }
+
+ RefPtr<TouchList> m_touches;
+ RefPtr<TouchList> m_targetTouches;
+ RefPtr<TouchList> m_changedTouches;
+
+#if PLATFORM(ANDROID)
+ bool m_longPressPrevented;
+ bool m_doubleTapPrevented;
+#endif
+};
} // namespace WebCore
diff --git a/WebCore/dom/TouchEvent.idl b/WebCore/dom/TouchEvent.idl
index b7148b0..010c36f 100644
--- a/WebCore/dom/TouchEvent.idl
+++ b/WebCore/dom/TouchEvent.idl
@@ -32,6 +32,10 @@ module events {
readonly attribute TouchList touches;
readonly attribute TouchList targetTouches;
readonly attribute TouchList changedTouches;
+ readonly attribute boolean ctrlKey;
+ readonly attribute boolean shiftKey;
+ readonly attribute boolean altKey;
+ readonly attribute boolean metaKey;
void initTouchEvent(in TouchList touches,
in TouchList targetTouches,
@@ -41,6 +45,10 @@ module events {
in long screenX,
in long screenY,
in long clientX,
- in long clientY);
+ in long clientY,
+ in boolean ctrlKey,
+ in boolean altKey,
+ in boolean shiftKey,
+ in boolean metaKey);
};
}
diff --git a/WebCore/dom/TouchList.cpp b/WebCore/dom/TouchList.cpp
index 78b588e..4167e42 100644
--- a/WebCore/dom/TouchList.cpp
+++ b/WebCore/dom/TouchList.cpp
@@ -25,7 +25,7 @@
#include "config.h"
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
#include "TouchList.h"
diff --git a/WebCore/dom/TouchList.h b/WebCore/dom/TouchList.h
index fa5fc80..f5033c9 100644
--- a/WebCore/dom/TouchList.h
+++ b/WebCore/dom/TouchList.h
@@ -26,7 +26,7 @@
#ifndef TOUCHLIST_H_
#define TOUCHLIST_H_
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
@@ -34,24 +34,24 @@
namespace WebCore {
- class TouchList : public RefCounted<TouchList> {
- public:
- static PassRefPtr<TouchList> create()
- {
- return adoptRef(new TouchList);
- }
+class TouchList : public RefCounted<TouchList> {
+public:
+ static PassRefPtr<TouchList> create()
+ {
+ return adoptRef(new TouchList);
+ }
- unsigned length() const { return m_values.size(); }
+ unsigned length() const { return m_values.size(); }
- Touch* item (unsigned);
+ Touch* item(unsigned);
- void append(const PassRefPtr<Touch> touch) { m_values.append(touch); }
+ void append(const PassRefPtr<Touch> touch) { m_values.append(touch); }
- private:
- TouchList() {}
+private:
+ TouchList() {}
- Vector<RefPtr<Touch> > m_values;
- };
+ Vector<RefPtr<Touch> > m_values;
+};
} // namespace WebCore
diff --git a/WebCore/html/HTMLAttributeNames.in b/WebCore/html/HTMLAttributeNames.in
index c989dbd..967b695 100644
--- a/WebCore/html/HTMLAttributeNames.in
+++ b/WebCore/html/HTMLAttributeNames.in
@@ -199,12 +199,10 @@ onstorage
onsuspend
onsubmit
ontimeupdate
-/* #if ENABLE(TOUCH_EVENTS) // Android */
ontouchstart
ontouchmove
ontouchend
ontouchcancel
-/* #endif */
onunload
onvolumechange
onwaiting
diff --git a/WebCore/html/HTMLElement.cpp b/WebCore/html/HTMLElement.cpp
index af15f6e..a4fc52a 100644
--- a/WebCore/html/HTMLElement.cpp
+++ b/WebCore/html/HTMLElement.cpp
@@ -218,20 +218,18 @@ void HTMLElement::parseMappedAttribute(MappedAttribute *attr)
setAttributeEventListener(eventNames().webkitAnimationEndEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == onwebkittransitionendAttr) {
setAttributeEventListener(eventNames().webkitTransitionEndEvent, createAttributeEventListener(this, attr));
-#if ENABLE(TOUCH_EVENTS) // Android
+ } else if (attr->name() == oninputAttr) {
+ setAttributeEventListener(eventNames().inputEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == oninvalidAttr) {
+ setAttributeEventListener(eventNames().invalidEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ontouchstartAttr) {
setAttributeEventListener(eventNames().touchstartEvent, createAttributeEventListener(this, attr));
- } else if (attr->name() == ontouchendAttr) {
- setAttributeEventListener(eventNames().touchendEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ontouchmoveAttr) {
setAttributeEventListener(eventNames().touchmoveEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == ontouchendAttr) {
+ setAttributeEventListener(eventNames().touchendEvent, createAttributeEventListener(this, attr));
} else if (attr->name() == ontouchcancelAttr) {
setAttributeEventListener(eventNames().touchcancelEvent, createAttributeEventListener(this, attr));
-#endif
- } else if (attr->name() == oninputAttr) {
- setAttributeEventListener(eventNames().inputEvent, createAttributeEventListener(this, attr));
- } else if (attr->name() == oninvalidAttr) {
- setAttributeEventListener(eventNames().invalidEvent, createAttributeEventListener(this, attr));
}
}
diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h
index 117953c..b28473b 100644
--- a/WebCore/page/ChromeClient.h
+++ b/WebCore/page/ChromeClient.h
@@ -225,6 +225,10 @@ namespace WebCore {
virtual void willPopUpMenu(NSMenu *) { }
#endif
+#if ENABLE(TOUCH_EVENTS)
+ virtual void needTouchEvents(bool, bool force = false) = 0;
+#endif
+
protected:
virtual ~ChromeClient() { }
};
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index 5e2d990..0aee619 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -322,13 +322,12 @@ namespace WebCore {
DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd);
DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd);
-#if ENABLE(TOUCH_EVENTS) // Android
+#if ENABLE(TOUCH_EVENTS)
DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
#endif
-
void captureEvents();
void releaseEvents();
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index c4b08c6..cfc9401 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -206,12 +206,6 @@ module window {
raises(DOMException);
// Events
-#if ENABLE_TOUCH_EVENTS
- attribute EventListener ontouchstart;
- attribute EventListener ontouchend;
- attribute EventListener ontouchmove;
- attribute EventListener ontouchcancel;
-#endif
attribute EventListener onabort;
attribute EventListener onbeforeunload;
@@ -296,6 +290,12 @@ module window {
#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
attribute EventListener onorientationchange;
#endif
+#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
+ attribute [DontEnum] EventListener ontouchstart;
+ attribute [DontEnum] EventListener ontouchmove;
+ attribute [DontEnum] EventListener ontouchend;
+ attribute [DontEnum] EventListener ontouchcancel;
+#endif
// EventTarget interface
[Custom] void addEventListener(in DOMString type,
@@ -466,9 +466,6 @@ module window {
attribute WheelEventConstructor WheelEvent;
attribute MessageEventConstructor MessageEvent;
attribute EventExceptionConstructor EventException;
-#if ENABLE_TOUCH_EVENTS
- attribute TouchEventConstructor TouchEvent;
-#endif
attribute WebKitCSSKeyframeRuleConstructor WebKitCSSKeyframeRule;
attribute WebKitCSSKeyframesRuleConstructor WebKitCSSKeyframesRule;
@@ -576,6 +573,10 @@ module window {
#endif
#endif
+#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
+ attribute TouchEventConstructor TouchEvent;
+#endif
+
#endif // defined(LANGUAGE_JAVASCRIPT)
#if defined(V8_BINDING) && V8_BINDING
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 8b6b602..a7dc13a 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -56,6 +56,7 @@
#include "Page.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
+#include "PluginView.h"
#include "RenderFrameSet.h"
#include "RenderTextControlSingleLine.h"
#include "RenderView.h"
@@ -74,9 +75,9 @@
#include "SVGUseElement.h"
#endif
-#if ENABLE(TOUCH_EVENTS) // Android
-#include "TouchEvent.h"
+#if ENABLE(TOUCH_EVENTS)
#include "PlatformTouchEvent.h"
+#include "TouchEvent.h"
#endif
#if defined(ANDROID_PLUGINS)
@@ -207,8 +208,16 @@ void EventHandler::clear()
m_lastScrollbarUnderMouse = 0;
m_clickCount = 0;
m_clickNode = 0;
-#if ENABLE(TOUCH_EVENTS) // Android
- m_touch = 0;
+#if ENABLE(TOUCH_EVENTS)
+ m_touchEventTarget = 0;
+ if (Document* doc = m_frame->document()) {
+ if (Page* page = doc->page()) {
+ // We are clearing event handlers, which includes any touch
+ // event handlers so force webkit to tell the chrome client to
+ // stop forwarding the events.
+ page->chrome()->client()->needTouchEvents(false, true);
+ }
+ }
#endif
m_frameSetBeingResized = 0;
#if ENABLE(DRAG_SUPPORT)
@@ -2546,141 +2555,221 @@ bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults&
return scrollbar->mouseDown(mev.event());
}
-#if ENABLE(TOUCH_EVENTS) // Android
-int EventHandler::handleTouchEvent(const PlatformTouchEvent& e)
+// If scrollbar (under mouse) is different from last, send a mouse exited. Set
+// last to scrollbar if setLast is true; else set last to 0.
+void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setLast)
{
- // only handle the touch event in the top frame handler
- if (m_frame->tree()->parent(true))
- return m_frame->tree()->parent()->eventHandler()->handleTouchEvent(e);
-
- Document* doc = m_frame->document();
- if (!doc)
- return 0;
-
- RenderObject* docRenderer = doc->renderer();
- if (!docRenderer)
- return 0;
-
- if (doc->touchEventListeners().size() == 0)
- return 0;
+ if (m_lastScrollbarUnderMouse != scrollbar) {
+ // Send mouse exited to the old scrollbar.
+ if (m_lastScrollbarUnderMouse)
+ m_lastScrollbarUnderMouse->mouseExited();
+ m_lastScrollbarUnderMouse = setLast ? scrollbar : 0;
+ }
+}
- TouchEventType type = e.eventType();
- if (type == TouchEventStart || type == TouchEventLongPress || type == TouchEventDoubleTap) {
- Frame* frame = m_frame;
- IntPoint vPoint = frame->view()->windowToContents(e.pos());
- HitTestRequest request(HitTestRequest::ReadOnly);
- HitTestResult result(vPoint);
- frame->contentRenderer()->layer()->hitTest(request, result);
- Node* node = result.innerNode();
- if (node) {
- RenderObject* target = node->renderer();
- while (target && target->isWidget()) {
- Widget* widget = static_cast<RenderWidget*>(target)->widget();
- if (widget->isFrameView()) {
- frame = static_cast<FrameView*>(widget)->frame();
- vPoint = frame->view()->windowToContents(e.pos());
- HitTestResult ret(vPoint);
- frame->contentRenderer()->layer()->hitTest(request, ret);
- node = ret.innerNode();
- if (!node)
- break;
- else
- target = node->renderer();
- } else
- // plugin view??
- break;
- }
+#if ENABLE(TOUCH_EVENTS)
+#if PLATFORM(ANDROID)
+// TODO(benm): On Android we return an int back to Java to signify whether the default actions
+// for longpress/doubletap in the Browser should be prevented. I think that before upstreaming
+// to webkit.org we can refactor the Java side to not require this.
+int EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
+#else
+bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
+#endif
+{
+ RefPtr<TouchList> touches = TouchList::create();
+ RefPtr<TouchList> pressedTouches = TouchList::create();
+ RefPtr<TouchList> releasedTouches = TouchList::create();
+ RefPtr<TouchList> movedTouches = TouchList::create();
+ RefPtr<TouchList> targetTouches = TouchList::create();
+ RefPtr<TouchList> cancelTouches = TouchList::create();
+
+ const Vector<PlatformTouchPoint>& points = event.touchPoints();
+ AtomicString* eventName = 0;
+
+ for (int i = 0; i < points.size(); ++i) {
+ const PlatformTouchPoint& point = points[i];
+ IntPoint framePoint = documentPointForWindowPoint(m_frame, point.pos());
+ HitTestResult result = hitTestResultAtPoint(framePoint, /*allowShadowContent*/ false);
+ Node* target = result.innerNode();
+
+ // Touch events should not go to text nodes
+ if (target && target->isTextNode())
+ target = target->parentNode();
+
+ Document* doc = target->document();
+ if (!doc)
+ continue;
+ if (!doc->hasListenerType(Document::TOUCH_LISTENER))
+ continue;
+
+ int adjustedPageX = lroundf(framePoint.x() / m_frame->pageZoomFactor());
+ int adjustedPageY = lroundf(framePoint.y() / m_frame->pageZoomFactor());
+
+ if ( (event.type() == TouchStart
+#if PLATFORM(ANDROID)
+ || event.type() == TouchDoubleTap
+ || event.type() == TouchLongPress
+#endif
+ ) && !i) {
+ m_touchEventTarget = target;
+ m_firstTouchScreenPos = point.screenPos();
+ m_firstTouchPagePos = framePoint;
}
- if (!node) {
- // reset to the top document node
- node = doc;
- frame = m_frame;
- vPoint = frame->view()->windowToContents(e.pos());
- }
+ RefPtr<Touch> touch = Touch::create(m_frame, m_touchEventTarget.get(), point.id(),
+ point.screenPos().x(), point.screenPos().y(),
+ adjustedPageX, adjustedPageY);
- m_touch = Touch::create(frame, node, 0,
- e.x(), e.y(), vPoint.x(), vPoint.y());
- } else if (m_touch) {
- if ((type == TouchEventMove) && (e.x() == m_touch->screenX()) &&
- (e.y() == m_touch->screenY())) {
- // don't trigger the event if it hasn't really moved
- return 0;
+ if (point.state() == PlatformTouchPoint::TouchReleased)
+ releasedTouches->append(touch);
+ else if (point.state() == PlatformTouchPoint::TouchCancelled)
+ cancelTouches->append(touch);
+ else {
+ if (point.state() == PlatformTouchPoint::TouchPressed)
+ pressedTouches->append(touch);
+ else {
+ touches->append(touch);
+ if (m_touchEventTarget == target)
+ targetTouches->append(touch);
+ if (point.state() == PlatformTouchPoint::TouchMoved)
+ movedTouches->append(touch);
+ }
}
+ }
- IntPoint vPoint = m_touch->frame()->view()->windowToContents(e.pos());
- m_touch->updateLocation(e.x(), e.y(), vPoint.x(), vPoint.y());
- } else {
+ if (!m_touchEventTarget)
+#if PLATFORM(ANDROID)
return 0;
- }
+#else
+ return false;
+#endif
- RefPtr<TouchList> touchList = TouchList::create();
- touchList->append(m_touch);
- // For TouchEventEnd, touches and targetTouches are empty list
- RefPtr<TouchList> emptyList = TouchList::create();
- RefPtr<TouchEvent> te;
- switch(type) {
- case TouchEventStart:
- te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
- eventNames().touchstartEvent, m_touch->frame()->document()->defaultView(),
- m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
- break;
+ bool defaultPrevented = false;
+#if PLATFORM(ANDROID)
+ // TODO (benm): We should be able to remove this prior to upstreaming once Java side refactorings to make
+ // preventDeault work better are complete.
+ bool longPressPrevented = false;
+ bool doubleTapPrevented = false;
+#endif
- case TouchEventEnd:
- te = TouchEvent::create(emptyList.get(), emptyList.get(), touchList.get(),
- eventNames().touchendEvent, m_touch->frame()->document()->defaultView(),
- m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
- break;
+ if (event.type() == TouchCancel) {
+ eventName = &eventNames().touchcancelEvent;
+ RefPtr<TouchEvent> cancelEv =
+ TouchEvent::create(TouchList::create().get(), TouchList::create().get(), cancelTouches.get(),
+ *eventName, m_touchEventTarget->document()->defaultView(),
+ m_firstTouchScreenPos.x(), m_firstTouchScreenPos.y(),
+ m_firstTouchPagePos.x(), m_firstTouchPagePos.y(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+
+ ExceptionCode ec = 0;
+ m_touchEventTarget->dispatchEvent(cancelEv.get(), ec);
+ defaultPrevented |= cancelEv->defaultPrevented();
+ }
+
+ if (releasedTouches->length() > 0) {
+ eventName = &eventNames().touchendEvent;
+
+ RefPtr<TouchEvent> endEv =
+ TouchEvent::create(touches.get(), targetTouches.get(), releasedTouches.get(),
+ *eventName, m_touchEventTarget->document()->defaultView(),
+ m_firstTouchScreenPos.x(), m_firstTouchScreenPos.y(),
+ m_firstTouchPagePos.x(), m_firstTouchPagePos.y(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+
+ ExceptionCode ec = 0;
+ m_touchEventTarget->dispatchEvent(endEv.get(), ec);
+ defaultPrevented |= endEv->defaultPrevented();
+ }
+
+ if (pressedTouches->length() > 0) {
+ // Add pressed touchpoints to touches and targetTouches.
+ for (int i = 0; i < pressedTouches->length(); ++i) {
+ touches->append(pressedTouches->item(i));
+ if (m_touchEventTarget == pressedTouches->item(i)->target())
+ targetTouches->append(pressedTouches->item(i));
+ }
- case TouchEventMove:
- te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
- eventNames().touchmoveEvent, m_touch->frame()->document()->defaultView(),
- m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
- break;
+#if PLATFORM(ANDROID)
+ if (event.type() == TouchLongPress) {
+ eventName = &eventNames().touchlongpressEvent;
+ RefPtr<TouchEvent> longpressEv =
+ TouchEvent::create(touches.get(), targetTouches.get(), pressedTouches.get(),
+ *eventName, m_touchEventTarget->document()->defaultView(),
+ m_firstTouchScreenPos.x(), m_firstTouchScreenPos.y(),
+ m_firstTouchPagePos.x(), m_firstTouchPagePos.y(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+
+ ExceptionCode ec = 0;
+ m_touchEventTarget->dispatchEvent(longpressEv.get(), ec);
+ defaultPrevented |= longpressEv->defaultPrevented();
+ } else if (event.type() == TouchDoubleTap) {
+ eventName = &eventNames().touchdoubletapEvent;
+ RefPtr<TouchEvent> doubleTapEv =
+ TouchEvent::create(touches.get(), targetTouches.get(), pressedTouches.get(),
+ *eventName, m_touchEventTarget->document()->defaultView(),
+ m_firstTouchScreenPos.x(), m_firstTouchScreenPos.y(),
+ m_firstTouchPagePos.x(), m_firstTouchPagePos.y(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+
+ ExceptionCode ec = 0;
+ m_touchEventTarget->dispatchEvent(doubleTapEv.get(), ec);
+ defaultPrevented |= doubleTapEv->defaultPrevented();
+ } else {
+#endif
+ eventName = &eventNames().touchstartEvent;
+ RefPtr<TouchEvent> startEv =
+ TouchEvent::create(touches.get(), targetTouches.get(), pressedTouches.get(),
+ *eventName, m_touchEventTarget->document()->defaultView(),
+ m_firstTouchScreenPos.x(), m_firstTouchScreenPos.y(),
+ m_firstTouchPagePos.x(), m_firstTouchPagePos.y(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+ ExceptionCode ec = 0;
+ m_touchEventTarget->dispatchEvent(startEv.get(), ec);
+ defaultPrevented |= startEv->defaultPrevented();
+#if PLATFORM(ANDROID)
+ longPressPrevented |= startEv->longPressPrevented();
+ doubleTapPrevented |= startEv->doubleTapPrevented();
+ }
+#endif
+ }
- case TouchEventCancel:
- te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
- eventNames().touchcancelEvent, m_touch->frame()->document()->defaultView(),
- m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
- break;
+ if (movedTouches->length() > 0) {
+ eventName = &eventNames().touchmoveEvent;
+ RefPtr<TouchEvent> moveEv =
+ TouchEvent::create(touches.get(), targetTouches.get(), movedTouches.get(),
+ *eventName, m_touchEventTarget->document()->defaultView(),
+ m_firstTouchScreenPos.x(), m_firstTouchScreenPos.y(),
+ m_firstTouchPagePos.x(), m_firstTouchPagePos.y(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+ ExceptionCode ec = 0;
+ m_touchEventTarget->dispatchEvent(moveEv.get(), ec);
+ defaultPrevented |= moveEv->defaultPrevented();
+ }
- case TouchEventLongPress:
- te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
- eventNames().touchlongpressEvent, m_touch->frame()->document()->defaultView(),
- m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
- break;
- case TouchEventDoubleTap:
- te = TouchEvent::create(touchList.get(), touchList.get(), touchList.get(),
- eventNames().touchdoubletapEvent, m_touch->frame()->document()->defaultView(),
- m_touch->screenX(), m_touch->screenY(), m_touch->pageX(), m_touch->pageY());
- break;
+ if (event.type() == TouchEnd || event.type() == TouchCancel)
+ m_touchEventTarget = 0;
- default:
- return false;
- }
- ExceptionCode ec = 0;
- m_touch->target()->dispatchEvent(te.get(), ec);
- if (type == TouchEventEnd || type == TouchEventCancel)
- m_touch = 0;
- if (type == TouchEventLongPress || type == TouchEventDoubleTap)
+#if PLATFORM(ANDROID)
+ // TODO (benm): We should be able to remove this prior to upstreaming once Java side refactorings to make
+ // preventDefault work better are complete.
+ if (event.type() == TouchLongPress || event.type() == TouchDoubleTap)
return 0;
- return (te->defaultPrevented() ? preventTouch : 0)
- | (te->longPressPrevented() ? preventLongPress : 0)
- | (te->doubleTapPrevented() ? preventDoubleTap : 0);
-}
-#endif
-// If scrollbar (under mouse) is different from last, send a mouse exited. Set
-// last to scrollbar if setLast is true; else set last to 0.
-void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setLast)
-{
- if (m_lastScrollbarUnderMouse != scrollbar) {
- // Send mouse exited to the old scrollbar.
- if (m_lastScrollbarUnderMouse)
- m_lastScrollbarUnderMouse->mouseExited();
- m_lastScrollbarUnderMouse = setLast ? scrollbar : 0;
- }
+ return (defaultPrevented ? preventTouch : 0)
+ | (longPressPrevented ? preventLongPress : 0)
+ | (doubleTapPrevented ? preventDoubleTap : 0);
+#else
+ return defaultPrevented;
+#endif
}
+#endif
}
diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h
index 0da44f2..8ccd761 100644
--- a/WebCore/page/EventHandler.h
+++ b/WebCore/page/EventHandler.h
@@ -52,6 +52,7 @@ class KeyboardEvent;
class MouseEventWithHitTestResults;
class Node;
class PlatformKeyboardEvent;
+class PlatformTouchEvent;
class PlatformWheelEvent;
class RenderLayer;
class RenderObject;
@@ -60,11 +61,8 @@ class Scrollbar;
class String;
class SVGElementInstance;
class TextEvent;
+class TouchEvent;
class Widget;
-#if ENABLE(TOUCH_EVENTS) // Android
-class PlatformTouchEvent;
-class Touch;
-#endif
#if ENABLE(DRAG_SUPPORT)
extern const int LinkDragHysteresis;
@@ -75,13 +73,16 @@ extern const int GeneralDragHysteresis;
enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars };
-#if ENABLE(TOUCH_EVENTS) // Android
+#if PLATFORM(ANDROID)
+// TODO (benm): I think with some Java refactoring we can remove this before upstreaming to webkit.org.
+#if ENABLE(TOUCH_EVENTS)
enum TouchResultMask {
preventTouch = 1 << 0,
preventLongPress = 1 << 1,
preventDoubleTap = 1 << 2,
};
#endif
+#endif
class EventHandler : public Noncopyable {
public:
@@ -151,11 +152,6 @@ public:
bool handleMouseReleaseEvent(const PlatformMouseEvent&);
bool handleWheelEvent(PlatformWheelEvent&);
-#if ENABLE(TOUCH_EVENTS) // Android
- // See TouchResultMask for the return value options
- int handleTouchEvent(const PlatformTouchEvent&);
-#endif
-
#if ENABLE(CONTEXT_MENUS)
bool sendContextMenuEvent(const PlatformMouseEvent&);
#endif
@@ -208,6 +204,14 @@ public:
static NSEvent *currentNSEvent();
#endif
+#if ENABLE(TOUCH_EVENTS)
+#if PLATFORM(ANDROID)
+ int handleTouchEvent(const PlatformTouchEvent&);
+#else
+ bool handleTouchEvent(const PlatformTouchEvent&);
+#endif
+#endif
+
private:
#if ENABLE(DRAG_SUPPORT)
enum DragAndDropHandleType {
@@ -389,9 +393,6 @@ private:
int m_clickCount;
RefPtr<Node> m_clickNode;
-#if ENABLE(TOUCH_EVENTS) // Android
- RefPtr<Touch> m_touch;
-#endif
#if ENABLE(DRAG_SUPPORT)
RefPtr<Node> m_dragTarget;
@@ -418,6 +419,12 @@ private:
bool m_sendingEventToSubview;
int m_activationEventNumber;
#endif
+#if ENABLE(TOUCH_EVENTS)
+ RefPtr<Node> m_touchEventTarget;
+ IntPoint m_firstTouchScreenPos;
+ IntPoint m_firstTouchPagePos;
+#endif
+
};
} // namespace WebCore
diff --git a/WebCore/platform/PlatformTouchEvent.h b/WebCore/platform/PlatformTouchEvent.h
index 6c8629c..78de894 100644
--- a/WebCore/platform/PlatformTouchEvent.h
+++ b/WebCore/platform/PlatformTouchEvent.h
@@ -1,67 +1,86 @@
/*
- * Copyright 2008, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
#ifndef PlatformTouchEvent_h
#define PlatformTouchEvent_h
-#if ENABLE(TOUCH_EVENTS) // Android
+#include "PlatformTouchPoint.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(TOUCH_EVENTS)
+
+#if PLATFORM(QT)
+QT_BEGIN_NAMESPACE
+class QTouchEvent;
+QT_END_NAMESPACE
+#endif
+#if PLATFORM(ANDROID)
#include "IntPoint.h"
+#endif
namespace WebCore {
- enum TouchEventType {TouchEventStart, TouchEventMove, TouchEventEnd, TouchEventCancel, TouchEventLongPress, TouchEventDoubleTap};
-
- class PlatformTouchEvent {
- public:
- PlatformTouchEvent()
- : m_eventType(TouchEventCancel)
- {
- }
-
- PlatformTouchEvent(const IntPoint& pos, const IntPoint& globalPos, TouchEventType eventType)
- : m_position(pos)
- , m_globalPosition(globalPos)
- , m_eventType(eventType)
- {
- }
-
- const IntPoint& pos() const { return m_position; }
- int x() const { return m_position.x(); }
- int y() const { return m_position.y(); }
- int globalX() const { return m_globalPosition.x(); }
- int globalY() const { return m_globalPosition.y(); }
- TouchEventType eventType() const { return m_eventType; }
-
- private:
- IntPoint m_position;
- IntPoint m_globalPosition;
- TouchEventType m_eventType;
- };
-
-} // namespace WebCore
+enum TouchEventType {
+ TouchStart
+ , TouchMove
+ , TouchEnd
+ , TouchCancel
+#if PLATFORM(ANDROID)
+ , TouchLongPress
+ , TouchDoubleTap
+#endif
+};
+
+class PlatformTouchEvent {
+public:
+ PlatformTouchEvent()
+ : m_type(TouchStart)
+ , m_ctrlKey(false)
+ , m_altKey(false)
+ , m_shiftKey(false)
+ , m_metaKey(false)
+ {}
+#if PLATFORM(QT)
+ PlatformTouchEvent(QTouchEvent*);
+#elif PLATFORM(ANDROID)
+ PlatformTouchEvent(const IntPoint&, const IntPoint&, TouchEventType, PlatformTouchPoint::State);
+#endif
+
+ TouchEventType type() const { return m_type; }
+ const Vector<PlatformTouchPoint>& touchPoints() const { return m_touchPoints; }
+
+ bool ctrlKey() const { return m_ctrlKey; }
+ bool altKey() const { return m_altKey; }
+ bool shiftKey() const { return m_shiftKey; }
+ bool metaKey() const { return m_metaKey; }
+
+private:
+ TouchEventType m_type;
+ Vector<PlatformTouchPoint> m_touchPoints;
+ bool m_ctrlKey;
+ bool m_altKey;
+ bool m_shiftKey;
+ bool m_metaKey;
+};
+
+}
#endif // ENABLE(TOUCH_EVENTS)
diff --git a/WebCore/platform/PlatformTouchPoint.h b/WebCore/platform/PlatformTouchPoint.h
new file mode 100644
index 0000000..339fe73
--- /dev/null
+++ b/WebCore/platform/PlatformTouchPoint.h
@@ -0,0 +1,69 @@
+/*
+ Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef PlatformTouchPoint_h
+#define PlatformTouchPoint_h
+
+#include "IntPoint.h"
+#include <wtf/Platform.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(TOUCH_EVENTS)
+
+#if PLATFORM(QT)
+#include <QTouchEvent>
+#endif
+
+namespace WebCore {
+
+class PlatformTouchEvent;
+
+class PlatformTouchPoint {
+public:
+ enum State {
+ TouchReleased,
+ TouchPressed,
+ TouchMoved,
+ TouchStationary,
+ TouchCancelled
+ };
+
+#if PLATFORM(QT)
+ PlatformTouchPoint(const QTouchEvent::TouchPoint&);
+#elif PLATFORM(ANDROID)
+ PlatformTouchPoint(const IntPoint&, const IntPoint&, State);
+#endif
+
+ int id() const { return m_id; }
+ State state() const { return m_state; }
+ IntPoint screenPos() const { return m_screenPos; }
+ IntPoint pos() const { return m_pos; }
+
+private:
+ int m_id;
+ State m_state;
+ IntPoint m_screenPos;
+ IntPoint m_pos;
+};
+
+}
+
+#endif // ENABLE(TOUCH_EVENTS)
+
+#endif // PlatformTouchPoint_h
diff --git a/WebCore/platform/android/PlatformTouchEventAndroid.cpp b/WebCore/platform/android/PlatformTouchEventAndroid.cpp
new file mode 100644
index 0000000..46d5c6f
--- /dev/null
+++ b/WebCore/platform/android/PlatformTouchEventAndroid.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PlatformTouchEvent.h"
+
+#if ENABLE(TOUCH_EVENTS)
+
+namespace WebCore {
+
+PlatformTouchEvent::PlatformTouchEvent(const IntPoint& pos, const IntPoint& globalPos, TouchEventType type, PlatformTouchPoint::State state) : m_type(type) {
+ m_touchPoints.append(PlatformTouchPoint(pos, globalPos, state));
+}
+
+}
+
+#endif
diff --git a/WebCore/platform/android/PlatformTouchPointAndroid.cpp b/WebCore/platform/android/PlatformTouchPointAndroid.cpp
new file mode 100644
index 0000000..cb22f5f
--- /dev/null
+++ b/WebCore/platform/android/PlatformTouchPointAndroid.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PlatformTouchPoint.h"
+
+#if ENABLE(TOUCH_EVENTS)
+
+namespace WebCore {
+
+PlatformTouchPoint::PlatformTouchPoint(const IntPoint& pos, const IntPoint& globalPos, State state) :m_id(0), m_state(state), m_screenPos(pos), m_pos(globalPos) {}
+
+}
+
+#endif
diff --git a/WebCore/plugins/android/PluginViewAndroid.cpp b/WebCore/plugins/android/PluginViewAndroid.cpp
index e10641d..0d02941 100644
--- a/WebCore/plugins/android/PluginViewAndroid.cpp
+++ b/WebCore/plugins/android/PluginViewAndroid.cpp
@@ -52,7 +52,9 @@
#include "PlatformKeyboardEvent.h"
#include "PluginMainThreadScheduler.h"
#include "PluginPackage.h"
+#include "Touch.h"
#include "TouchEvent.h"
+#include "TouchList.h"
#include "android_graphics.h"
#include "SkCanvas.h"
#include "npruntime_impl.h"
@@ -206,11 +208,16 @@ void PluginView::handleTouchEvent(TouchEvent* event)
evt.data.touch.modifiers = 0; // todo
- // convert to coordinates that are relative to the plugin. The pageX / pageY
- // values are the only values in the event that are consistently in frame
- // coordinates despite their misleading name.
- evt.data.touch.x = event->pageX() - m_npWindow.x;
- evt.data.touch.y = event->pageY() - m_npWindow.y;
+ // In the event of a touchend (up) event, we must ask the changedTouch for the
+ // co-ordinates as there is no touch in touches anymore.
+ TouchList* touches = (evt.data.touch.action == kUp_ANPTouchAction) ?
+ event->changedTouches() : event->touches();
+
+ // Convert to coordinates that are relative to the plugin.
+ // We only support single touch points at the moment, so we want to look at index 0 only.
+ IntPoint localPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(IntPoint(touches->item(0)->pageX(), touches->item(0)->pageY())));
+ evt.data.touch.x = localPos.x();
+ evt.data.touch.y = localPos.y();
int16 ret = m_plugin->pluginFuncs()->event(m_instance, &evt);
if (ignoreRet)
@@ -243,11 +250,11 @@ void PluginView::handleMouseEvent(MouseEvent* event)
SkANP::InitEvent(&evt, kMouse_ANPEventType);
evt.data.mouse.action = isUp ? kUp_ANPMouseAction : kDown_ANPMouseAction;
- // convert to coordinates that are relative to the plugin. The pageX / pageY
- // values are the only values in the event that are consistently in frame
- // coordinates despite their misleading name.
- evt.data.mouse.x = event->pageX() - m_npWindow.x;
- evt.data.mouse.y = event->pageY() - m_npWindow.y;
+ // Convert to coordinates that are relative to the plugin.
+ IntPoint localPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation()));
+ evt.data.mouse.x = localPos.x();
+ evt.data.mouse.y = localPos.y();
+
if (isDown) {
// The plugin needs focus to receive keyboard events
if (Page* page = m_parentFrame->page())
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
index f14c2c1..ffa96f8 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp
@@ -465,4 +465,14 @@ void ChromeClientAndroid::wakeUpMainThreadWithNewQuota(long newQuota) {
m_quotaThreadCondition.signal();
}
+#if ENABLE(TOUCH_EVENTS)
+void ChromeClientAndroid::needTouchEvents(bool needTouchEvents, bool force)
+{
+ FrameView* frameView = m_webFrame->page()->mainFrame()->view();
+ android::WebViewCore* core = android::WebViewCore::getWebViewCore(frameView);
+ if (core)
+ core->needTouchEvents(needTouchEvents, force);
+}
+#endif
+
}
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
index 45dd078..b61f9fd 100644
--- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
+++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h
@@ -136,6 +136,10 @@ namespace android {
virtual void populateVisitedLinks();
+#if ENABLE(TOUCH_EVENTS)
+ virtual void needTouchEvents(bool, bool);
+#endif
+
// Methods used to request and provide Geolocation permissions.
virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*);
// Android-specific
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 8414068..15cef2b 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -266,6 +266,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m
m_screenWidth = 320;
m_scale = 1;
m_screenWidthScale = 1;
+ m_touchEventListenerCount = 0;
LOG_ASSERT(m_mainFrame, "Uh oh, somehow a frameview was made without an initial frame!");
@@ -348,6 +349,9 @@ WebViewCore* WebViewCore::getWebViewCore(const WebCore::FrameView* view)
WebViewCore* WebViewCore::getWebViewCore(const WebCore::ScrollView* view)
{
+ if (!view)
+ return 0;
+
WebFrameView* webFrameView = static_cast<WebFrameView*>(view->platformWidget());
if (!webFrameView)
return 0;
@@ -991,15 +995,28 @@ void WebViewCore::restoreScreenWidthScale(int scale)
checkException(env);
}
-void WebViewCore::needTouchEvents(bool need)
+void WebViewCore::needTouchEvents(bool need, bool force)
{
DEBUG_NAV_UI_LOGD("%s", __FUNCTION__);
LOG_ASSERT(m_javaGlue->m_obj, "A Java widget was not associated with this view bridge!");
#if ENABLE(TOUCH_EVENTS) // Android
- JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_needTouchEvents, need);
- checkException(env);
+ bool needToUpdateJava = false;
+ if (need) {
+ if (++m_touchEventListenerCount == 1)
+ needToUpdateJava = true;
+ } else {
+ if (force)
+ m_touchEventListenerCount = 0;
+ else if (--m_touchEventListenerCount == 0)
+ needToUpdateJava = true;
+ }
+
+ if (needToUpdateJava || force) {
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue->object(env).get(), m_javaGlue->m_needTouchEvents, need);
+ checkException(env);
+ }
#endif
}
@@ -1910,29 +1927,47 @@ int WebViewCore::handleTouchEvent(int action, int x, int y)
#endif
#if ENABLE(TOUCH_EVENTS) // Android
- WebCore::TouchEventType type = WebCore::TouchEventCancel;
+ WebCore::TouchEventType type = WebCore::TouchStart;
+ WebCore::PlatformTouchPoint::State touchState = WebCore::PlatformTouchPoint::TouchPressed;
switch (action) {
case 0: // MotionEvent.ACTION_DOWN
- type = WebCore::TouchEventStart;
+ type = WebCore::TouchStart;
break;
case 1: // MotionEvent.ACTION_UP
- type = WebCore::TouchEventEnd;
+ type = WebCore::TouchEnd;
+ touchState = WebCore::PlatformTouchPoint::TouchReleased;
break;
case 2: // MotionEvent.ACTION_MOVE
- type = WebCore::TouchEventMove;
+ type = WebCore::TouchMove;
+ touchState = WebCore::PlatformTouchPoint::TouchMoved;
break;
case 3: // MotionEvent.ACTION_CANCEL
- type = WebCore::TouchEventCancel;
+ type = WebCore::TouchCancel;
+ touchState = WebCore::PlatformTouchPoint::TouchCancelled;
break;
case 0x100: // WebViewCore.ACTION_LONGPRESS
- type = WebCore::TouchEventLongPress;
+ type = WebCore::TouchLongPress;
+ touchState = WebCore::PlatformTouchPoint::TouchPressed;
break;
case 0x200: // WebViewCore.ACTION_DOUBLETAP
- type = WebCore::TouchEventDoubleTap;
+ type = WebCore::TouchDoubleTap;
+ touchState = WebCore::PlatformTouchPoint::TouchPressed;
+ break;
+ default:
+ type = WebCore::TouchCancel;
+ touchState = WebCore::PlatformTouchPoint::TouchCancelled;
break;
}
+
+ // Track previous touch and if stationary set the state.
WebCore::IntPoint pt(x - m_scrollOffsetX, y - m_scrollOffsetY);
- WebCore::PlatformTouchEvent te(pt, pt, type);
+
+ if (type == WebCore::TouchMove && pt == m_lastTouchPoint)
+ touchState = WebCore::PlatformTouchPoint::TouchStationary;
+
+ m_lastTouchPoint = pt;
+
+ WebCore::PlatformTouchEvent te(pt, pt, type, touchState);
preventDefault = m_mainFrame->eventHandler()->handleTouchEvent(te);
#endif
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index 0569b4d..c662441 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -375,7 +375,7 @@ namespace android {
Node* cursorNodeIsPlugin();
// Notify the Java side whether it needs to pass down the touch events
- void needTouchEvents(bool);
+ void needTouchEvents(bool, bool);
// Notify the Java side that webkit is requesting a keyboard
void requestKeyboard(bool showKeyboard, bool isTextView);
@@ -526,6 +526,11 @@ namespace android {
bool handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* nodePtr);
WebCore::HTMLAnchorElement* retrieveAnchorElement(WebCore::Frame* frame, WebCore::Node* node);
+#if ENABLE(TOUCH_EVENTS)
+ int m_touchEventListenerCount;
+ IntPoint m_lastTouchPoint;
+#endif
+
#if DEBUG_NAV_UI
uint32_t m_now;
#endif
diff --git a/WebKit/android/plugins/PluginWidgetAndroid.cpp b/WebKit/android/plugins/PluginWidgetAndroid.cpp
index 0fcdc3b..17443b7 100644
--- a/WebKit/android/plugins/PluginWidgetAndroid.cpp
+++ b/WebKit/android/plugins/PluginWidgetAndroid.cpp
@@ -28,6 +28,7 @@
#include "Document.h"
#include "Element.h"
#include "Frame.h"
+#include "Page.h"
#include "PluginPackage.h"
#include "PluginView.h"
#include "PluginWidgetAndroid.h"
@@ -38,6 +39,10 @@
#include "WebViewCore.h"
#include "jni_utility.h"
+#if ENABLE(TOUCH_EVENTS)
+#include "ChromeClient.h"
+#endif
+
#define DEBUG_VISIBLE_RECTS 1 // temporary debug printfs and fixes
PluginWidgetAndroid::PluginWidgetAndroid(WebCore::PluginView* view)
@@ -259,12 +264,18 @@ void PluginWidgetAndroid::updateEventFlags(ANPEventFlags flags) {
}
Document* doc = m_pluginView->getParentFrame()->document();
+#if ENABLE(TOUCH_EVENTS)
if((m_eventFlags ^ flags) & kTouch_ANPEventFlag) {
- if(flags & kTouch_ANPEventFlag)
- doc->addTouchEventListener(m_pluginView->getElement());
- else
- doc->removeTouchEventListener(m_pluginView->getElement());
+ if (flags & kTouch_ANPEventFlag) {
+ if (Page* page = doc->page())
+ page->chrome()->client()->needTouchEvents(true, false);
+ doc->addListenerTypeIfNeeded(eventNames().touchstartEvent);
+ } else {
+ if (Page* page = doc->page())
+ page->chrome()->client()->needTouchEvents(false, false);
+ }
}
+#endif
m_eventFlags = flags;
}