diff options
Diffstat (limited to 'WebCore/page')
| -rw-r--r-- | WebCore/page/ChromeClient.h | 4 | ||||
| -rw-r--r-- | WebCore/page/Connection.cpp | 39 | ||||
| -rw-r--r-- | WebCore/page/Connection.h | 54 | ||||
| -rw-r--r-- | WebCore/page/Connection.idl | 38 | ||||
| -rw-r--r-- | WebCore/page/DOMWindow.h | 5 | ||||
| -rw-r--r-- | WebCore/page/DOMWindow.idl | 19 | ||||
| -rw-r--r-- | WebCore/page/EventHandler.cpp | 333 | ||||
| -rw-r--r-- | WebCore/page/EventHandler.h | 33 | ||||
| -rw-r--r-- | WebCore/page/Geolocation.cpp | 149 | ||||
| -rw-r--r-- | WebCore/page/Geolocation.h | 29 | ||||
| -rw-r--r-- | WebCore/page/GeolocationController.cpp | 85 | ||||
| -rw-r--r-- | WebCore/page/GeolocationController.h | 67 | ||||
| -rw-r--r-- | WebCore/page/GeolocationControllerClient.h | 45 | ||||
| -rw-r--r-- | WebCore/page/GeolocationError.h | 60 | ||||
| -rw-r--r-- | WebCore/page/GeolocationPosition.h | 110 | ||||
| -rw-r--r-- | WebCore/page/Geoposition.h | 7 | ||||
| -rw-r--r-- | WebCore/page/Navigator.cpp | 12 | ||||
| -rw-r--r-- | WebCore/page/Navigator.h | 10 | ||||
| -rw-r--r-- | WebCore/page/Navigator.idl | 3 | ||||
| -rw-r--r-- | WebCore/page/Page.cpp | 13 | ||||
| -rw-r--r-- | WebCore/page/Page.h | 10 | ||||
| -rw-r--r-- | WebCore/page/win/FrameWin.cpp | 6 |
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; |
