summaryrefslogtreecommitdiffstats
path: root/WebCore/page
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/page')
-rw-r--r--WebCore/page/ChromeClient.h4
-rw-r--r--WebCore/page/Connection.cpp39
-rw-r--r--WebCore/page/Connection.h54
-rw-r--r--WebCore/page/Connection.idl38
-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/page/Geolocation.cpp149
-rw-r--r--WebCore/page/Geolocation.h29
-rw-r--r--WebCore/page/GeolocationController.cpp85
-rw-r--r--WebCore/page/GeolocationController.h67
-rw-r--r--WebCore/page/GeolocationControllerClient.h45
-rw-r--r--WebCore/page/GeolocationError.h60
-rw-r--r--WebCore/page/GeolocationPosition.h110
-rw-r--r--WebCore/page/Geoposition.h7
-rw-r--r--WebCore/page/Navigator.cpp12
-rw-r--r--WebCore/page/Navigator.h10
-rw-r--r--WebCore/page/Navigator.idl3
-rw-r--r--WebCore/page/Page.cpp13
-rw-r--r--WebCore/page/Page.h10
-rw-r--r--WebCore/page/win/FrameWin.cpp6
22 files changed, 957 insertions, 174 deletions
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/Connection.cpp b/WebCore/page/Connection.cpp
new file mode 100644
index 0000000..ffbb838
--- /dev/null
+++ b/WebCore/page/Connection.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 "Connection.h"
+
+#include "NetworkStateNotifier.h"
+
+namespace WebCore {
+
+Connection::ConnectionType Connection::type() const
+{
+ return networkStateNotifier().type();
+}
+
+}; \ No newline at end of file
diff --git a/WebCore/page/Connection.h b/WebCore/page/Connection.h
new file mode 100644
index 0000000..837a36f
--- /dev/null
+++ b/WebCore/page/Connection.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef Connection_h
+#define Connection_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class Connection : public RefCounted<Connection> {
+public:
+ enum ConnectionType {
+ Unknown = 0,
+ Ethernet = 1,
+ WiFi = 2,
+ Cell_2G = 3,
+ Cell_3G = 4,
+ };
+
+ static PassRefPtr<Connection> create() { return adoptRef(new Connection()); }
+
+ ConnectionType type() const;
+
+private:
+ Connection() { }
+};
+
+} // namespace WebCore
+
+#endif // Connection_h
diff --git a/WebCore/page/Connection.idl b/WebCore/page/Connection.idl
new file mode 100644
index 0000000..b4cfbd1
--- /dev/null
+++ b/WebCore/page/Connection.idl
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+ module core {
+
+ interface Connection {
+ readonly attribute unsigned short type;
+
+ const unsigned short UNKNOWN = 0;
+ const unsigned short ETHERNET = 1;
+ const unsigned short WIFI = 2;
+ const unsigned short CELL_2G = 3;
+ const unsigned short CELL_3G = 4;
+ };
+
+}
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/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index 5fbad47..f0578a8 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -39,10 +39,45 @@
#include "SQLValue.h"
#include <wtf/CurrentTime.h>
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+#include "Coordinates.h"
+#include "GeolocationController.h"
+#include "GeolocationError.h"
+#include "GeolocationPosition.h"
+#include "Geoposition.h"
+#include "PositionError.h"
+#endif
+
namespace WebCore {
static const char permissionDeniedErrorMessage[] = "User denied Geolocation";
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+
+static PassRefPtr<Geoposition> createGeoposition(GeolocationPosition* position)
+{
+ RefPtr<Coordinates> coordinates = Coordinates::create(position->latitude(), position->longitude(), position->canProvideAltitude(), position->altitude(),
+ position->accuracy(), position->canProvideAltitudeAccuracy(), position->altitudeAccuracy(),
+ position->canProvideHeading(), position->heading(), position->canProvideSpeed(), position->speed());
+ return Geoposition::create(coordinates.release(), position->timestamp());
+}
+
+static PassRefPtr<PositionError> createPositionError(GeolocationError* error)
+{
+ PositionError::ErrorCode code = PositionError::POSITION_UNAVAILABLE;
+ switch (error->code()) {
+ case GeolocationError::PermissionDenied:
+ code = PositionError::PERMISSION_DENIED;
+ break;
+ case GeolocationError::PositionUnavailable:
+ code = PositionError::POSITION_UNAVAILABLE;
+ break;
+ }
+
+ return PositionError::create(code, error->message());
+}
+#endif
+
Geolocation::GeoNotifier::GeoNotifier(Geolocation* geolocation, PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
: m_geolocation(geolocation)
, m_successCallback(successCallback)
@@ -305,7 +340,9 @@ String* CachedPositionManager::s_databaseFile = 0;
Geolocation::Geolocation(Frame* frame)
: EventListener(GeolocationEventListenerType)
, m_frame(frame)
+#if !ENABLE(CLIENT_BASED_GEOLOCATION)
, m_service(GeolocationService::create(this))
+#endif
, m_allowGeolocation(Unknown)
, m_shouldClearCache(false)
, m_cachedPositionManager(new CachedPositionManager)
@@ -327,7 +364,7 @@ Geolocation::~Geolocation()
void Geolocation::disconnectFrame()
{
- m_service->stopUpdating();
+ stopUpdating();
if (m_frame && m_frame->document())
m_frame->document()->setUsingGeolocation(false);
m_frame = 0;
@@ -335,6 +372,24 @@ void Geolocation::disconnectFrame()
delete m_cachedPositionManager;
}
+Geoposition* Geolocation::lastPosition()
+{
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ if (!m_frame)
+ return 0;
+
+ Page* page = m_frame->page();
+ if (!page)
+ return 0;
+
+ m_lastPosition = createGeoposition(page->geolocationController()->lastPosition());
+#else
+ m_lastPosition = m_service->lastPosition();
+#endif
+
+ return m_lastPosition.get();
+}
+
void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
{
RefPtr<GeoNotifier> notifier = startRequest(successCallback, errorCallback, options);
@@ -391,7 +446,7 @@ void Geolocation::fatalErrorOccurred(Geolocation::GeoNotifier* notifier)
m_watchers.remove(notifier);
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
}
void Geolocation::requestTimedOut(GeoNotifier* notifier)
@@ -400,7 +455,7 @@ void Geolocation::requestTimedOut(GeoNotifier* notifier)
m_oneShots.remove(notifier);
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
}
void Geolocation::requestReturnedCachedPosition(GeoNotifier* notifier)
@@ -408,11 +463,11 @@ void Geolocation::requestReturnedCachedPosition(GeoNotifier* notifier)
// If this is a one-shot request, stop it.
m_oneShots.remove(notifier);
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
// Otherwise, if the watch still exists, start the service to get updates.
if (m_watchers.contains(notifier)) {
- if (notifier->hasZeroTimeout() || m_service->startUpdating(notifier->m_options.get()))
+ if (notifier->hasZeroTimeout() || startUpdating(notifier->m_options.get()))
notifier->startTimerIfNeeded();
else
notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, "Failed to start Geolocation service"));
@@ -436,7 +491,7 @@ void Geolocation::clearWatch(int watchId)
m_watchers.remove(watchId);
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
}
void Geolocation::suspend()
@@ -497,7 +552,6 @@ void Geolocation::sendPosition(Vector<RefPtr<GeoNotifier> >& notifiers, Geoposit
RefPtr<GeoNotifier> notifier = *it;
ASSERT(notifier->m_successCallback);
- notifier->m_timer.stop();
notifier->m_successCallback->handleEvent(position);
}
}
@@ -554,7 +608,7 @@ void Geolocation::handleError(PositionError* error)
sendError(watchersCopy, error);
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
}
void Geolocation::requestPermission()
@@ -575,12 +629,11 @@ void Geolocation::requestPermission()
page->chrome()->requestGeolocationPermissionForFrame(m_frame, this);
}
-void Geolocation::geolocationServicePositionChanged(GeolocationService* service)
+void Geolocation::positionChanged(PassRefPtr<Geoposition> newPosition)
{
- ASSERT_UNUSED(service, service == m_service);
- ASSERT(m_service->lastPosition());
+ m_currentPosition = newPosition;
- m_cachedPositionManager->setCachedPosition(m_service->lastPosition());
+ m_cachedPositionManager->setCachedPosition(m_currentPosition.get());
// Stop all currently running timers.
stopTimers();
@@ -599,7 +652,7 @@ void Geolocation::geolocationServicePositionChanged(GeolocationService* service)
void Geolocation::makeSuccessCallbacks()
{
- ASSERT(m_service->lastPosition());
+ ASSERT(m_currentPosition);
ASSERT(isAllowed());
Vector<RefPtr<GeoNotifier> > oneShotsCopy;
@@ -613,23 +666,85 @@ void Geolocation::makeSuccessCallbacks()
// further callbacks to these notifiers.
m_oneShots.clear();
- sendPosition(oneShotsCopy, m_service->lastPosition());
- sendPosition(watchersCopy, m_service->lastPosition());
+ sendPosition(oneShotsCopy, m_currentPosition.get());
+ sendPosition(watchersCopy, m_currentPosition.get());
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
+}
+
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+
+void Geolocation::setPosition(GeolocationPosition* position)
+{
+ positionChanged(createGeoposition(position));
+}
+
+void Geolocation::setError(GeolocationError* error)
+{
+ RefPtr<PositionError> positionError = createPositionError(error);
+ handleError(positionError.get());
+}
+
+#else
+
+void Geolocation::geolocationServicePositionChanged(GeolocationService* service)
+{
+ ASSERT_UNUSED(service, service == m_service);
+ ASSERT(m_service->lastPosition());
+
+ positionChanged(m_service->lastPosition());
}
void Geolocation::geolocationServiceErrorOccurred(GeolocationService* service)
{
ASSERT(service->lastError());
-
+
// Note that we do not stop timers here. For one-shots, the request is
// cleared in handleError. For watchers, the spec requires that the timer is
// not cleared.
handleError(service->lastError());
}
+#endif
+
+bool Geolocation::startUpdating(PositionOptions* options)
+{
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ // FIXME: Pass options to client.
+ UNUSED_PARAM(options);
+
+ if (!m_frame)
+ return false;
+
+ Page* page = m_frame->page();
+ if (!page)
+ return false;
+
+ page->geolocationController()->addObserver(this);
+ return true;
+#else
+ return m_service->startUpdating(options);
+#endif
+}
+
+void Geolocation::stopUpdating()
+{
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ if (!m_frame)
+ return;
+
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
+ page->geolocationController()->removeObserver(this);
+#else
+ m_service->stopUpdating();
+#endif
+
+}
+
bool Geolocation::operator==(const EventListener& listener)
{
if (listener.type() != GeolocationEventListenerType)
diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h
index fd9d560..5b5feb5 100644
--- a/WebCore/page/Geolocation.h
+++ b/WebCore/page/Geolocation.h
@@ -48,8 +48,16 @@ namespace WebCore {
class Frame;
class CachedPositionManager;
-
-class Geolocation : public GeolocationServiceClient, public EventListener {
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+class GeolocationPosition;
+class GeolocationError;
+#endif
+
+class Geolocation : public EventListener
+#if !ENABLE(CLIENT_BASED_GEOLOCATION)
+ , public GeolocationServiceClient
+#endif
+{
public:
static PassRefPtr<Geolocation> create(Frame* frame) { return adoptRef(new Geolocation(frame)); }
@@ -57,7 +65,7 @@ public:
void disconnectFrame();
- Geoposition* lastPosition() const { return m_service->lastPosition(); }
+ Geoposition* lastPosition();
void getCurrentPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
int watchPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
@@ -73,6 +81,11 @@ public:
void setShouldClearCache(bool shouldClearCache) { m_shouldClearCache = shouldClearCache; }
bool shouldClearCache() const { return m_shouldClearCache; }
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ void setPostion(GeolocationPosition*);
+ void setError(GeolocationError*);
+#endif
+
static void setDatabasePath(String);
private:
@@ -126,14 +139,20 @@ private:
void stopTimersForWatchers();
void stopTimers();
+ void positionChanged(PassRefPtr<Geoposition>);
void makeSuccessCallbacks();
void handleError(PositionError*);
void requestPermission();
+ bool startUpdating(PositionOptions*);
+ void stopUpdating();
+
+#if !ENABLE(CLIENT_BASED_GEOLOCATION)
// GeolocationServiceClient
virtual void geolocationServicePositionChanged(GeolocationService*);
virtual void geolocationServiceErrorOccurred(GeolocationService*);
+#endif
PassRefPtr<GeoNotifier> startRequest(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
@@ -151,7 +170,11 @@ private:
GeoNotifierSet m_oneShots;
Watchers m_watchers;
Frame* m_frame;
+#if !ENABLE(CLIENT_BASED_GEOLOCATION)
OwnPtr<GeolocationService> m_service;
+#endif
+ RefPtr<Geoposition> m_lastPosition;
+ RefPtr<Geoposition> m_currentPosition;
enum {
Unknown,
diff --git a/WebCore/page/GeolocationController.cpp b/WebCore/page/GeolocationController.cpp
new file mode 100644
index 0000000..44eba6e
--- /dev/null
+++ b/WebCore/page/GeolocationController.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GeolocationController.h"
+
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+
+#include "GeolocationControllerClient.h"
+
+namespace WebCore {
+
+GeolocationController::GeolocationController(Page* page, GeolocationControllerClient* client)
+ : m_page(page)
+ , m_client(client)
+{
+}
+
+GeolocationController::~GeolocationController()
+{
+}
+
+void GeolocationController::addObserver(Geolocation* observer)
+{
+ ASSERT(!m_observers.contains(observer));
+
+ bool wasEmpty = m_observers.isEmpty();
+ m_observers.add(observer);
+ if (wasEmpty)
+ m_client->startUpdating();
+}
+
+void GeolocationController::removeObserver(Geolocation* observer)
+{
+ ASSERT(m_observers.contains(observer));
+
+ m_observers.remove(observer);
+ if (m_observers.isEmpty())
+ m_client->stopUpdating();
+}
+
+void GeolocationController::positionChanged(GeolocationPosition* position)
+{
+ HashSet<RefPtr<Geolocation> >::const_iterator end = m_observers.end();
+ for (HashSet<RefPtr<Geolocation> >::const_iterator it = m_observers.begin(); it != end; ++it)
+ (*it)->setPosition(position);
+}
+
+void GeolocationController::errorOccurred(GeolocationError* error)
+{
+ HashSet<RefPtr<Geolocation> >::const_iterator end = m_observers.end();
+ for (HashSet<RefPtr<Geolocation> >::const_iterator it = m_observers.begin(); it != end; ++it)
+ (*it)->setError(error);
+}
+
+GeolocationPosition* GeolocationController::lastPosition()
+{
+ return m_client->lastPosition();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(CLIENT_BASED_GEOLOCATION)
diff --git a/WebCore/page/GeolocationController.h b/WebCore/page/GeolocationController.h
new file mode 100644
index 0000000..80f9ca8
--- /dev/null
+++ b/WebCore/page/GeolocationController.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GeolocationController_h
+#define GeolocationController_h
+
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+
+#include "Geolocation.h"
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class GeolocationControllerClient;
+class GeolocationError;
+class GeolocationPosition;
+class Page;
+
+class GeolocationController : public Noncopyable {
+public:
+ GeolocationController(Page*, GeolocationControllerClient*);
+ ~GeolocationController();
+
+ void addObserver(Geolocation*);
+ void removeObserver(Geolocation*);
+
+ void positionChanged(GeolocationPosition*);
+ void errorOccurred(GeolocationError*);
+
+ GeolocationPosition* lastPosition();
+
+private:
+ Page* m_page;
+ GeolocationControllerClient* m_client;
+
+ HashSet<RefPtr<Geolocation> > m_observers;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(CLIENT_BASED_GEOLOCATION)
+
+#endif // GeolocationController_h
diff --git a/WebCore/page/GeolocationControllerClient.h b/WebCore/page/GeolocationControllerClient.h
new file mode 100644
index 0000000..830c64b
--- /dev/null
+++ b/WebCore/page/GeolocationControllerClient.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GeolocationControllerClient_h
+#define GeolocationControllerClient_h
+
+namespace WebCore {
+
+class GeolocationPosition;
+
+class GeolocationControllerClient {
+public:
+ virtual void startUpdating() = 0;
+ virtual void stopUpdating() = 0;
+ virtual GeolocationPosition* lastPosition() = 0;
+
+protected:
+ virtual ~GeolocationControllerClient() { }
+};
+
+} // namespace WebCore
+
+#endif // GeolocationControllerClient_h
diff --git a/WebCore/page/GeolocationError.h b/WebCore/page/GeolocationError.h
new file mode 100644
index 0000000..9761ca6
--- /dev/null
+++ b/WebCore/page/GeolocationError.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GeolocationError_h
+#define GeolocationError_h
+
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+
+#include "PlatformString.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class GeolocationError : public RefCounted<GeolocationError> {
+public:
+ enum ErrorCode {
+ PermissionDenied,
+ PositionUnavailable
+ };
+
+ static PassRefPtr<GeolocationError> create(ErrorCode code, const String& message) { return adoptRef(new GeolocationError(code, message)); }
+
+ ErrorCode code() const { return m_code; }
+ const String& message() const { return m_message; }
+
+private:
+ GeolocationError(ErrorCode code, const String& message);
+
+ ErrorCode m_code;
+ String m_message;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(CLIENT_BASED_GEOLOCATION)
+
+#endif // GeolocationError_h
diff --git a/WebCore/page/GeolocationPosition.h b/WebCore/page/GeolocationPosition.h
new file mode 100644
index 0000000..c31e9c4
--- /dev/null
+++ b/WebCore/page/GeolocationPosition.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GeolocationPosition_h
+#define GeolocationPosition_h
+
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class GeolocationPosition : public RefCounted<GeolocationPosition> {
+public:
+ static PassRefPtr<GeolocationPosition> create(double timestamp, double latitude, double longitude, double accuracy) { return adoptRef(new GeolocationPosition(timestamp, latitude, longitude, accuracy)); }
+
+ static PassRefPtr<GeolocationPosition> create(double timestamp, double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed) { return adoptRef(new GeolocationPosition(timestamp, latitude, longitude, accuracy, providesAltitude, altitude, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed)); }
+
+ double timestamp() const { return m_timestamp; }
+
+ double latitude() const { return m_latitude; }
+ double longitude() const { return m_longitude; }
+ double accuracy() const { return m_accuracy; }
+ double altitude() const { return m_altitude; }
+ double altitudeAccuracy() const { return m_altitudeAccuracy; }
+ double heading() const { return m_heading; }
+ double speed() const { return m_speed; }
+
+ bool canProvideAltitude() const { return m_canProvideAltitude; }
+ bool canProvideAltitudeAccuracy() const { return m_canProvideAltitudeAccuracy; }
+ bool canProvideHeading() const { return m_canProvideHeading; }
+ bool canProvideSpeed() const { return m_canProvideSpeed; }
+
+private:
+ GeolocationPosition(double timestamp, double latitude, double longitude, double accuracy)
+ : m_timestamp(timestamp)
+ , m_latitude(latitude)
+ , m_longitude(longitude)
+ , m_accuracy(accuracy)
+ , m_altitude(0)
+ , m_altitudeAccuracy(0)
+ , m_heading(0)
+ , m_speed(0)
+ , m_canProvideAltitude(false)
+ , m_canProvideAltitudeAccuracy(false)
+ , m_canProvideHeading(false)
+ , m_canProvideSpeed(false)
+ {
+ }
+
+ GeolocationPosition(double timestamp, double latitude, double longitude, double accuracy, bool providesAltitude, double altitude, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed)
+ : m_timestamp(timestamp)
+ , m_latitude(latitude)
+ , m_longitude(longitude)
+ , m_accuracy(accuracy)
+ , m_altitude(altitude)
+ , m_altitudeAccuracy(altitudeAccuracy)
+ , m_heading(heading)
+ , m_speed(speed)
+ , m_canProvideAltitude(providesAltitude)
+ , m_canProvideAltitudeAccuracy(providesAltitudeAccuracy)
+ , m_canProvideHeading(providesHeading)
+ , m_canProvideSpeed(providesSpeed)
+ {
+ }
+
+ double m_timestamp;
+
+ double m_latitude;
+ double m_longitude;
+ double m_accuracy;
+ double m_altitude;
+ double m_altitudeAccuracy;
+ double m_heading;
+ double m_speed;
+
+ bool m_canProvideAltitude;
+ bool m_canProvideAltitudeAccuracy;
+ bool m_canProvideHeading;
+ bool m_canProvideSpeed;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(CLIENT_BASED_GEOLOCATION)
+
+#endif // GeolocationPosition_h
diff --git a/WebCore/page/Geoposition.h b/WebCore/page/Geoposition.h
index f3c703b..8b215b1 100644
--- a/WebCore/page/Geoposition.h
+++ b/WebCore/page/Geoposition.h
@@ -37,8 +37,11 @@ typedef int ExceptionCode;
class Geoposition : public RefCounted<Geoposition> {
public:
- static PassRefPtr<Geoposition> create(PassRefPtr<Coordinates> coordinates, DOMTimeStamp timestamp) { return adoptRef(new Geoposition(coordinates, timestamp)); }
-
+ static PassRefPtr<Geoposition> create(PassRefPtr<Coordinates> coordinates, DOMTimeStamp timestamp)
+ {
+ return adoptRef(new Geoposition(coordinates, timestamp));
+ }
+
DOMTimeStamp timestamp() const { return m_timestamp; }
Coordinates* coords() const { return m_coordinates.get(); }
diff --git a/WebCore/page/Navigator.cpp b/WebCore/page/Navigator.cpp
index a4193fc..8563a0e 100644
--- a/WebCore/page/Navigator.cpp
+++ b/WebCore/page/Navigator.cpp
@@ -24,6 +24,9 @@
#include "Navigator.h"
#include "CookieJar.h"
+#if PLATFORM(ANDROID)
+#include "Connection.h"
+#endif
#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
@@ -155,6 +158,15 @@ Geolocation* Navigator::geolocation() const
return m_geolocation.get();
}
+#if PLATFORM(ANDROID)
+Connection* Navigator::connection() const
+{
+ if (!m_connection)
+ m_connection = Connection::create();
+ return m_connection.get();
+}
+#endif
+
#if ENABLE(DOM_STORAGE)
void Navigator::getStorageUpdates()
{
diff --git a/WebCore/page/Navigator.h b/WebCore/page/Navigator.h
index 107082b..9967fba 100644
--- a/WebCore/page/Navigator.h
+++ b/WebCore/page/Navigator.h
@@ -27,6 +27,9 @@
namespace WebCore {
+#if PLATFORM(ANDROID)
+ class Connection;
+#endif
class Frame;
class Geolocation;
class MimeTypeArray;
@@ -57,6 +60,10 @@ namespace WebCore {
// This is used for GC marking.
Geolocation* optionalGeolocation() const { return m_geolocation.get(); }
+#if PLATFORM(ANDROID)
+ Connection* connection() const;
+#endif
+
#if ENABLE(DOM_STORAGE)
// Relinquishes the storage lock, if one exists.
void getStorageUpdates();
@@ -71,6 +78,9 @@ namespace WebCore {
mutable RefPtr<PluginArray> m_plugins;
mutable RefPtr<MimeTypeArray> m_mimeTypes;
mutable RefPtr<Geolocation> m_geolocation;
+#if PLATFORM(ANDROID)
+ mutable RefPtr<Connection> m_connection;
+#endif
};
}
diff --git a/WebCore/page/Navigator.idl b/WebCore/page/Navigator.idl
index 99b22af..f3079de 100644
--- a/WebCore/page/Navigator.idl
+++ b/WebCore/page/Navigator.idl
@@ -39,6 +39,9 @@ module window {
readonly attribute boolean onLine;
+ // ANDROID-only for now, upstreaming in progress.
+ readonly attribute Connection connection;
+
#if defined(ENABLE_GEOLOCATION) && ENABLE_GEOLOCATION
readonly attribute Geolocation geolocation;
#endif
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index c4f33d6..1a035a5 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -77,6 +77,10 @@
#include "WMLPageState.h"
#endif
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+#include "GeolocationController.h"
+#endif
+
namespace WebCore {
static HashSet<Page*>* allPages;
@@ -101,7 +105,7 @@ static void networkStateChanged()
frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false));
}
-Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient, DragClient* dragClient, InspectorClient* inspectorClient, PluginHalterClient* pluginHalterClient)
+Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient, DragClient* dragClient, InspectorClient* inspectorClient, PluginHalterClient* pluginHalterClient, GeolocationControllerClient* geolocationControllerClient)
: m_chrome(new Chrome(this, chromeClient))
, m_dragCaretController(new SelectionController(0, true))
#if ENABLE(DRAG_SUPPORT)
@@ -114,6 +118,9 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
#if ENABLE(INSPECTOR)
, m_inspectorController(new InspectorController(this, inspectorClient))
#endif
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ , m_geolocationController(new GeolocationController(this, geolocationControllerClient))
+#endif
, m_settings(new Settings(this))
, m_progress(new ProgressTracker)
, m_backForwardList(BackForwardList::create(this))
@@ -148,6 +155,10 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
#if !ENABLE(INSPECTOR)
UNUSED_PARAM(inspectorClient);
#endif
+#if !ENABLE(CLIENT_BASED_GEOLOCATION)
+ UNUSED_PARAM(geolocationControllerClient);
+#endif
+
if (!allPages) {
allPages = new HashSet<Page*>;
diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h
index 4886464..40d96a7 100644
--- a/WebCore/page/Page.h
+++ b/WebCore/page/Page.h
@@ -54,6 +54,8 @@ namespace WebCore {
class EditorClient;
class FocusController;
class Frame;
+ class GeolocationController;
+ class GeolocationControllerClient;
class HaltablePlugin;
class InspectorClient;
class InspectorController;
@@ -85,7 +87,7 @@ namespace WebCore {
public:
static void setNeedsReapplyStyles();
- Page(ChromeClient*, ContextMenuClient*, EditorClient*, DragClient*, InspectorClient*, PluginHalterClient*);
+ Page(ChromeClient*, ContextMenuClient*, EditorClient*, DragClient*, InspectorClient*, PluginHalterClient*, GeolocationControllerClient*);
~Page();
RenderTheme* theme() const { return m_theme.get(); };
@@ -144,6 +146,9 @@ namespace WebCore {
#if ENABLE(INSPECTOR)
InspectorController* inspectorController() const { return m_inspectorController.get(); }
#endif
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ GeolocationController* geolocationController() const { return m_geolocationController.get(); }
+#endif
Settings* settings() const { return m_settings.get(); }
ProgressTracker* progress() const { return m_progress.get(); }
@@ -250,6 +255,9 @@ namespace WebCore {
#if ENABLE(INSPECTOR)
OwnPtr<InspectorController> m_inspectorController;
#endif
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ OwnPtr<GeolocationController> m_geolocationController;
+#endif
OwnPtr<Settings> m_settings;
OwnPtr<ProgressTracker> m_progress;
diff --git a/WebCore/page/win/FrameWin.cpp b/WebCore/page/win/FrameWin.cpp
index b15d195..8440a80 100644
--- a/WebCore/page/win/FrameWin.cpp
+++ b/WebCore/page/win/FrameWin.cpp
@@ -24,14 +24,14 @@
*/
#include "config.h"
-#include "runtime.h"
#include "FrameWin.h"
-#include "TransformationMatrix.h"
-#include "FloatRect.h"
+#include "Bridge.h"
#include "Document.h"
+#include "FloatRect.h"
#include "RenderView.h"
#include "Settings.h"
+#include "TransformationMatrix.h"
using std::min;