diff options
author | Ben Murdoch <benm@google.com> | 2010-07-22 15:37:06 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-07-27 10:20:25 +0100 |
commit | 967717af5423377c967781471ee106e2bb4e11c8 (patch) | |
tree | 1e701dc0a12f7f07cce1df4a7681717de77a211b /WebCore/page | |
parent | dcc30a9fca45f634b1d3a12b276d3a0ccce99fc3 (diff) | |
download | external_webkit-967717af5423377c967781471ee106e2bb4e11c8.zip external_webkit-967717af5423377c967781471ee106e2bb4e11c8.tar.gz external_webkit-967717af5423377c967781471ee106e2bb4e11c8.tar.bz2 |
Merge WebKit at r63859 : Initial merge by git.
Change-Id: Ie8096c63ec7c991c9a9cba8bdd9c3b74a3b8ed62
Diffstat (limited to 'WebCore/page')
53 files changed, 900 insertions, 149 deletions
diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp index f2e1d9d..0c66925 100644 --- a/WebCore/page/Chrome.cpp +++ b/WebCore/page/Chrome.cpp @@ -426,9 +426,9 @@ void Chrome::chooseIconForFiles(const Vector<String>& filenames, FileChooser* fi m_client->chooseIconForFiles(filenames, fileChooser); } -bool Chrome::setCursor(PlatformCursorHandle cursor) +void Chrome::setCursor(const Cursor& cursor) { - return m_client->setCursor(cursor); + m_client->setCursor(cursor); } #if ENABLE(NOTIFICATIONS) diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h index 27bde83..537468a 100644 --- a/WebCore/page/Chrome.h +++ b/WebCore/page/Chrome.h @@ -69,6 +69,7 @@ namespace WebCore { virtual IntRect windowToScreen(const IntRect&) const; virtual PlatformPageClient platformPageClient() const; virtual void scrollbarsModeDidChange() const; + virtual void setCursor(const Cursor&); void scrollRectIntoView(const IntRect&) const; @@ -135,8 +136,6 @@ namespace WebCore { void runOpenPanel(Frame*, PassRefPtr<FileChooser>); void chooseIconForFiles(const Vector<String>&, FileChooser*); - bool setCursor(PlatformCursorHandle); - #if PLATFORM(MAC) void focusNSView(NSView*); #endif diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h index 8101c52..1b2d1cc 100644 --- a/WebCore/page/ChromeClient.h +++ b/WebCore/page/ChromeClient.h @@ -135,11 +135,13 @@ namespace WebCore { virtual IntPoint screenToWindow(const IntPoint&) const = 0; virtual IntRect windowToScreen(const IntRect&) const = 0; virtual PlatformPageClient platformPageClient() const = 0; - virtual void contentsSizeChanged(Frame*, const IntSize&) const = 0; - virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const = 0; // Currently only Mac has a non empty implementation. + virtual void scrollbarsModeDidChange() const = 0; + virtual void setCursor(const Cursor&) = 0; // End methods used by HostWindow. - virtual void scrollbarsModeDidChange() const = 0; + virtual void contentsSizeChanged(Frame*, const IntSize&) const = 0; + virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const = 0; // Currently only Mac has a non empty implementation. + virtual bool shouldMissingPluginMessageBeButton() const { return false; } virtual void missingPluginButtonClicked(Element*) const { } virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) = 0; @@ -194,8 +196,6 @@ namespace WebCore { // Asynchronous request to load an icon for specified filenames. virtual void chooseIconForFiles(const Vector<String>&, FileChooser*) = 0; - virtual bool setCursor(PlatformCursorHandle) = 0; - // Notification that the given form element has changed. This function // will be called frequently, so handling should be very fast. virtual void formStateDidChange(const Node*) = 0; @@ -236,6 +236,10 @@ namespace WebCore { virtual void willPopUpMenu(NSMenu *) { } #endif +#if PLATFORM(WIN) + virtual void setLastSetCursorToCurrentCursor() = 0; +#endif + #if ENABLE(TOUCH_EVENTS) virtual void needTouchEvents(bool) = 0; #endif diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp index 1d6c095..3d8a7de 100644 --- a/WebCore/page/Console.cpp +++ b/WebCore/page/Console.cpp @@ -36,6 +36,7 @@ #include "FrameLoader.h" #include "FrameTree.h" #include "InspectorController.h" +#include "MemoryInfo.h" #include "Page.h" #include "PageGroup.h" #include "PlatformString.h" @@ -61,6 +62,8 @@ Frame* Console::frame() const void Console::disconnectFrame() { + if (m_memory) + m_memory = 0; m_frame = 0; } @@ -141,7 +144,7 @@ static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel printf("%s %s:", sourceString, levelString); } -void Console::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL) +void Console::addMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned lineNumber, const String& sourceURL, ScriptCallStack* callStack) { Page* page = this->page(); if (!page) @@ -151,7 +154,10 @@ void Console::addMessage(MessageSource source, MessageType type, MessageLevel le page->chrome()->client()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL); #if ENABLE(INSPECTOR) - page->inspectorController()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL); + if (callStack) + page->inspectorController()->addMessageToConsole(source, type, level, callStack, message); + else + page->inspectorController()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL); #endif if (!Console::shouldPrintExceptions()) @@ -294,15 +300,15 @@ String Console::lastWMLErrorMessage() const if (!page) return String(); - const Vector<ConsoleMessage*>& consoleMessages = page->inspectorController()->consoleMessages(); + const Vector<OwnPtr<ConsoleMessage> >& consoleMessages = page->inspectorController()->consoleMessages(); if (consoleMessages.isEmpty()) return String(); - Vector<ConsoleMessage*>::const_iterator it = consoleMessages.begin(); - const Vector<ConsoleMessage*>::const_iterator end = consoleMessages.end(); + Vector<OwnPtr<ConsoleMessage> >::const_iterator it = consoleMessages.begin(); + const Vector<OwnPtr<ConsoleMessage> >::const_iterator end = consoleMessages.end(); for (; it != end; ++it) { - ConsoleMessage* message = *it; + ConsoleMessage* message = it->get(); if (message->source() != WMLMessageSource) continue; @@ -456,6 +462,12 @@ void Console::warn(ScriptCallStack* callStack) addMessage(LogMessageType, WarningMessageLevel, callStack); } +MemoryInfo* Console::memory() const +{ + m_memory = MemoryInfo::create(m_frame); + return m_memory.get(); +} + static bool printExceptions = false; bool Console::shouldPrintExceptions() diff --git a/WebCore/page/Console.h b/WebCore/page/Console.h index 04e743e..d057ff9 100644 --- a/WebCore/page/Console.h +++ b/WebCore/page/Console.h @@ -29,8 +29,8 @@ #ifndef Console_h #define Console_h +#include "MemoryInfo.h" #include "PlatformString.h" - #include "ScriptProfile.h" #include <wtf/PassRefPtr.h> @@ -43,7 +43,6 @@ typedef Vector<RefPtr<ScriptProfile> > ProfilesArray; #endif class Frame; -class MemoryInfo; class Page; class String; class ScriptCallStack; @@ -65,7 +64,8 @@ enum MessageType { StartGroupMessageType, StartGroupCollapsedMessageType, EndGroupMessageType, - AssertMessageType + AssertMessageType, + UncaughtExceptionMessageType }; enum MessageLevel { @@ -83,7 +83,7 @@ public: Frame* frame() const; void disconnectFrame(); - void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL); + void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL, ScriptCallStack* callStack = 0); void debug(ScriptCallStack*); void error(ScriptCallStack*); @@ -116,6 +116,8 @@ public: const ProfilesArray& profiles() const { return m_profiles; } #endif + MemoryInfo* memory() const; + private: inline Page* page() const; void addMessage(MessageType, MessageLevel, ScriptCallStack*, bool acceptNoArguments = false); @@ -126,6 +128,7 @@ private: #if ENABLE(JAVASCRIPT_DEBUGGER) ProfilesArray m_profiles; #endif + mutable RefPtr<MemoryInfo> m_memory; }; } // namespace WebCore diff --git a/WebCore/page/Console.idl b/WebCore/page/Console.idl index 1506210..52528f1 100644 --- a/WebCore/page/Console.idl +++ b/WebCore/page/Console.idl @@ -41,8 +41,8 @@ module window { [CustomArgumentHandling] void warn(); [CustomArgumentHandling] void dir(); [CustomArgumentHandling] void dirxml(); - [CustomArgumentHandling] void trace(); - [CustomArgumentHandling, ImplementationFunction=assertCondition] void assert(in boolean condition); + [V8Custom, CustomArgumentHandling] void trace(); + [V8Custom, CustomArgumentHandling, ImplementationFunction=assertCondition] void assert(in boolean condition); [CustomArgumentHandling] void count(); [CustomArgumentHandling] void markTimeline(); @@ -61,7 +61,7 @@ module window { [CustomArgumentHandling] void groupCollapsed(); void groupEnd(); - readonly attribute [CustomGetter] MemoryInfo memory; + readonly attribute MemoryInfo memory; }; } diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp index 18eef41..6498042 100644 --- a/WebCore/page/DOMWindow.cpp +++ b/WebCore/page/DOMWindow.cpp @@ -35,11 +35,13 @@ #include "CSSStyleSelector.h" #include "Chrome.h" #include "Console.h" -#include "Database.h" -#include "DatabaseCallback.h" +#include "DocumentLoader.h" #include "DOMApplicationCache.h" #include "DOMSelection.h" #include "DOMTimer.h" +#include "Database.h" +#include "DatabaseCallback.h" +#include "DeviceOrientationController.h" #include "PageTransitionEvent.h" #include "Document.h" #include "Element.h" @@ -671,6 +673,17 @@ NotificationCenter* DOMWindow::webkitNotifications() const } #endif +void DOMWindow::pageDestroyed() +{ +#if ENABLE(NOTIFICATIONS) + // Clearing Notifications requests involves accessing the client so it must be done + // before the frame is detached. + if (m_notifications) + m_notifications->disconnectFrame(); + m_notifications = 0; +#endif +} + #if ENABLE(INDEXED_DATABASE) IndexedDatabaseRequest* DOMWindow::indexedDB() const { @@ -1426,6 +1439,10 @@ bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<Event addUnloadEventListener(this); else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this)) addBeforeUnloadEventListener(this); +#if ENABLE(DEVICE_ORIENTATION) + else if (eventType == eventNames().deviceorientationEvent && frame() && frame()->page() && frame()->page()->deviceOrientationController()) + frame()->page()->deviceOrientationController()->addListener(this); +#endif return true; } @@ -1439,17 +1456,21 @@ bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener removeUnloadEventListener(this); else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this)) removeBeforeUnloadEventListener(this); +#if ENABLE(DEVICE_ORIENTATION) + else if (eventType == eventNames().deviceorientationEvent && frame() && frame()->page() && frame()->page()->deviceOrientationController()) + frame()->page()->deviceOrientationController()->removeListener(this); +#endif return true; } void DOMWindow::dispatchLoadEvent() { - if (m_frame) - m_frame->loader()->frameLoadTimeline()->loadEventStart = currentTime(); + if (DocumentLoader* documentLoader = m_frame ? m_frame->loader()->documentLoader() : 0) + documentLoader->timing()->loadEventStart = currentTime(); dispatchEvent(Event::create(eventNames().loadEvent, false, false), document()); - if (m_frame) - m_frame->loader()->frameLoadTimeline()->loadEventEnd = currentTime(); + if (DocumentLoader* documentLoader = m_frame ? m_frame->loader()->documentLoader() : 0) + documentLoader->timing()->loadEventEnd = currentTime(); // For load events, send a separate load event to the enclosing frame only. // This is a DOM extension and is independent of bubbling/capturing rules of @@ -1513,6 +1534,11 @@ void DOMWindow::removeAllEventListeners() { EventTarget::removeAllEventListeners(); +#if ENABLE(DEVICE_ORIENTATION) + if (frame() && frame()->page() && frame()->page()->deviceOrientationController()) + frame()->page()->deviceOrientationController()->removeAllListeners(this); +#endif + removeAllUnloadEventListeners(this); removeAllBeforeUnloadEventListeners(this); } diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h index beb2f7d..69d7428 100644 --- a/WebCore/page/DOMWindow.h +++ b/WebCore/page/DOMWindow.h @@ -228,6 +228,8 @@ namespace WebCore { NotificationCenter* webkitNotifications() const; #endif + void pageDestroyed(); + #if ENABLE(INDEXED_DATABASE) IndexedDatabaseRequest* indexedDB() const; #endif diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl index f3cf9fe..f6b9feb 100644 --- a/WebCore/page/DOMWindow.idl +++ b/WebCore/page/DOMWindow.idl @@ -305,8 +305,8 @@ module window { attribute [Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchend; attribute [Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchcancel; - attribute [Conditional=DEVICE_ORIENTATION] DeviceOrientationEventConstructor DeviceOrientationEvent; - attribute [Conditional=DEVICE_ORIENTATION] EventListener ondeviceorientation; + attribute [Conditional=DEVICE_ORIENTATION, EnabledAtRuntime] DeviceOrientationEventConstructor DeviceOrientationEvent; + attribute [Conditional=DEVICE_ORIENTATION, EnabledAtRuntime] EventListener ondeviceorientation; // EventTarget interface [Custom] void addEventListener(in DOMString type, diff --git a/WebCore/page/EditorClient.h b/WebCore/page/EditorClient.h index 69f48e7..ff5bf94 100644 --- a/WebCore/page/EditorClient.h +++ b/WebCore/page/EditorClient.h @@ -183,10 +183,10 @@ public: virtual void showSpellingUI(bool show) = 0; virtual bool spellingUIIsShowing() = 0; virtual void getGuessesForWord(const String&, Vector<String>& guesses) = 0; + virtual void willSetInputMethodState() = 0; virtual void setInputMethodState(bool enabled) = 0; }; } #endif // EditorClient_h - diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index 08b8257..4d7771d 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -197,6 +197,9 @@ EventHandler::EventHandler(Frame* frame) , m_sendingEventToSubview(false) , m_activationEventNumber(0) #endif +#if ENABLE(TOUCH_EVENTS) + , m_touchPressed(false) +#endif { } @@ -866,11 +869,15 @@ void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const } #endif // ENABLE(DRAG_SUPPORT) +<<<<<<< HEAD:WebCore/page/EventHandler.cpp #ifdef ANDROID_HITTEST_WITHSIZE HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars, const IntSize& pointPadding) #else HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars) #endif +======= +HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars, int hitType) +>>>>>>> webkit.org at r63859:WebCore/page/EventHandler.cpp { #ifdef ANDROID_HITTEST_WITHSIZE HitTestResult result(point, pointPadding); @@ -879,7 +886,6 @@ HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool all #endif if (!m_frame->contentRenderer()) return result; - int hitType = HitTestRequest::ReadOnly | HitTestRequest::Active; if (ignoreClipping) hitType |= HitTestRequest::IgnoreClipping; m_frame->contentRenderer()->layer()->hitTest(HitTestRequest(hitType), result); @@ -1460,6 +1466,12 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi hitType |= HitTestRequest::ReadOnly; if (m_mousePressed) hitType |= HitTestRequest::Active; + +#if ENABLE(TOUCH_EVENTS) + // Treat any mouse move events as readonly if the user is currently touching the screen. + if (m_touchPressed) + hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; +#endif HitTestRequest request(hitType); MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); if (hoveredNode) @@ -2064,10 +2076,6 @@ bool EventHandler::sendContextMenuEventForKey() Position start = selectionController->selection().start(); if (start.node() && (selectionController->rootEditableElement() || selectionController->isRange())) { - RenderObject* renderer = start.node()->renderer(); - if (!renderer) - return false; - RefPtr<Range> selection = selectionController->toNormalizedRange(); IntRect firstRect = m_frame->firstRectForRange(selection.get()); @@ -2867,7 +2875,29 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) for (unsigned i = 0; i < points.size(); ++i) { const PlatformTouchPoint& point = points[i]; IntPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos()); - HitTestResult result = hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false); + + int hitType = HitTestRequest::Active | HitTestRequest::ReadOnly; + // The HitTestRequest types used for mouse events map quite adequately + // to touch events. Note that in addition to meaning that the hit test + // should affect the active state of the current node if necessary, + // HitTestRequest::Active signifies that the hit test is taking place + // with the mouse (or finger in this case) being pressed. + switch (point.state()) { + case PlatformTouchPoint::TouchPressed: + hitType = HitTestRequest::Active; + break; + case PlatformTouchPoint::TouchMoved: + hitType = HitTestRequest::Active | HitTestRequest::MouseMove | HitTestRequest::ReadOnly; + break; + case PlatformTouchPoint::TouchReleased: + case PlatformTouchPoint::TouchCancelled: + hitType = HitTestRequest::MouseUp; + break; + default: + break; + } + + HitTestResult result = hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType); Node* target = result.innerNode(); // Touch events should not go to text nodes @@ -2930,6 +2960,8 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event) movedTouches->append(touch); } + m_touchPressed = touches->length() > 0; + bool defaultPrevented = false; Touch* changedTouch = 0; EventTarget* touchEventTarget = 0; diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h index d24d803..55c6b20 100644 --- a/WebCore/page/EventHandler.h +++ b/WebCore/page/EventHandler.h @@ -28,6 +28,7 @@ #include "DragActions.h" #include "FocusDirection.h" +#include "HitTestRequest.h" #include "PlatformMouseEvent.h" #include "ScrollTypes.h" #include "Timer.h" @@ -105,11 +106,15 @@ public: void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&); +<<<<<<< HEAD:WebCore/page/EventHandler.h #ifdef ANDROID_HITTEST_WITHSIZE HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars, const IntSize& pointPadding = IntSize()); #else HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars); #endif +======= + HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars, int hitType = HitTestRequest::ReadOnly | HitTestRequest::Active); +>>>>>>> webkit.org at r63859:WebCore/page/EventHandler.h bool mousePressed() const { return m_mousePressed; } void setMousePressed(bool pressed) { m_mousePressed = pressed; } @@ -435,6 +440,7 @@ private: #if ENABLE(TOUCH_EVENTS) typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap; TouchTargetMap m_originatingTouchPointTargets; + bool m_touchPressed; #endif }; diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp index 6ecdffd..53a4fa8 100644 --- a/WebCore/page/FocusController.cpp +++ b/WebCore/page/FocusController.cpp @@ -595,22 +595,21 @@ bool FocusController::setFocusedNode(Node* node, PassRefPtr<Frame> newFocusedFra if (oldFocusedNode && oldFocusedNode->rootEditableElement() == oldFocusedNode && !relinquishesEditingFocus(oldFocusedNode)) return false; - // Set input method state before changing the focused node, so that the - // input method can still have a chance to finish the ongoing composition - // session. - m_page->editorClient()->setInputMethodState(node ? node->shouldUseInputMethod() : false); + m_page->editorClient()->willSetInputMethodState(); clearSelectionIfNeeded(oldFocusedFrame.get(), newFocusedFrame.get(), node); if (!node) { if (oldDocument) oldDocument->setFocusedNode(0); + m_page->editorClient()->setInputMethodState(false); return true; } RefPtr<Document> newDocument = node->document(); if (newDocument && newDocument->focusedNode() == node) { + m_page->editorClient()->setInputMethodState(node->shouldUseInputMethod()); return true; } @@ -622,6 +621,8 @@ bool FocusController::setFocusedNode(Node* node, PassRefPtr<Frame> newFocusedFra if (newDocument) newDocument->setFocusedNode(node); + m_page->editorClient()->setInputMethodState(node->shouldUseInputMethod()); + return true; } diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp index 46917fd..a8d0f15 100644 --- a/WebCore/page/Frame.cpp +++ b/WebCore/page/Frame.cpp @@ -298,24 +298,31 @@ String Frame::selectedText() const IntRect Frame::firstRectForRange(Range* range) const { int extraWidthToEndOfLine = 0; - ExceptionCode ec = 0; - ASSERT(range->startContainer(ec)); - ASSERT(range->endContainer(ec)); + ASSERT(range->startContainer()); + ASSERT(range->endContainer()); InlineBox* startInlineBox; int startCaretOffset; - range->startPosition().getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset); + Position startPosition = VisiblePosition(range->startPosition()).deepEquivalent(); + if (startPosition.isNull()) + return IntRect(); + startPosition.getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset); - RenderObject* startRenderer = range->startContainer(ec)->renderer(); + RenderObject* startRenderer = startPosition.node()->renderer(); + ASSERT(startRenderer); IntRect startCaretRect = startRenderer->localCaretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine); if (startCaretRect != IntRect()) startCaretRect = startRenderer->localToAbsoluteQuad(FloatRect(startCaretRect)).enclosingBoundingBox(); InlineBox* endInlineBox; int endCaretOffset; - range->endPosition().getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset); + Position endPosition = VisiblePosition(range->endPosition()).deepEquivalent(); + if (endPosition.isNull()) + return IntRect(); + endPosition.getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset); - RenderObject* endRenderer = range->endContainer(ec)->renderer(); + RenderObject* endRenderer = endPosition.node()->renderer(); + ASSERT(endRenderer); IntRect endCaretRect = endRenderer->localCaretRect(endInlineBox, endCaretOffset); if (endCaretRect != IntRect()) endCaretRect = endRenderer->localToAbsoluteQuad(FloatRect(endCaretRect)).enclosingBoundingBox(); @@ -1344,6 +1351,9 @@ void Frame::pageDestroyed() if (Frame* parent = tree()->parent()) parent->loader()->checkLoadComplete(); + if (m_domWindow) + m_domWindow->pageDestroyed(); + // FIXME: It's unclear as to why this is called more than once, but it is, // so page() could be NULL. if (page() && page()->focusController()->focusedFrame() == this) diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp index defb34a..31f9910 100644 --- a/WebCore/page/FrameView.cpp +++ b/WebCore/page/FrameView.cpp @@ -1129,7 +1129,7 @@ void FrameView::setScrollPosition(const IntPoint& scrollPoint) m_inProgrammaticScroll = wasInProgrammaticScroll; } -void FrameView::scrollPositionChanged() +void FrameView::scrollPositionChangedViaPlatformWidget() { frame()->eventHandler()->sendScrollEvent(); repaintFixedElementsAfterScrolling(); diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h index b047db0..868a15f 100644 --- a/WebCore/page/FrameView.h +++ b/WebCore/page/FrameView.h @@ -143,7 +143,7 @@ public: virtual IntRect windowResizerRect() const; void setScrollPosition(const IntPoint&); - void scrollPositionChanged(); + void scrollPositionChangedViaPlatformWidget(); virtual void repaintFixedElementsAfterScrolling(); String mediaType() const; diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp index 13bc02a..abdb8bf 100644 --- a/WebCore/page/Geolocation.cpp +++ b/WebCore/page/Geolocation.cpp @@ -295,7 +295,7 @@ PassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<Positi else if (haveSuitableCachedPosition(notifier->m_options.get())) notifier->setUseCachedPosition(); else if (notifier->hasZeroTimeout() || startUpdating(notifier.get())) { -#if ENABLE(CLIENT_BASED_GEOLOCATION) +#if USE(PREEMPT_GEOLOCATION_PERMISSION) // Only start timer if we're not waiting for user permission. if (!m_startRequestPermissionNotifier) #endif @@ -416,18 +416,22 @@ void Geolocation::setIsAllowed(bool allowed) // position. m_allowGeolocation = allowed ? Yes : No; -#if ENABLE(CLIENT_BASED_GEOLOCATION) +#if USE(PREEMPT_GEOLOCATION_PERMISSION) if (m_startRequestPermissionNotifier) { if (isAllowed()) { // Permission request was made during the startUpdating process m_startRequestPermissionNotifier->startTimerIfNeeded(); m_startRequestPermissionNotifier = 0; +#if ENABLE(CLIENT_BASED_GEOLOCATION) if (!m_frame) return; Page* page = m_frame->page(); if (!page) return; page->geolocationController()->addObserver(this); +#else + // TODO: Handle startUpdate() for non-client based implementations using pre-emptive policy +#endif } else { m_startRequestPermissionNotifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); m_oneShots.add(m_startRequestPermissionNotifier); @@ -628,15 +632,15 @@ void Geolocation::geolocationServiceErrorOccurred(GeolocationService* service) bool Geolocation::startUpdating(GeoNotifier* notifier) { -#if ENABLE(CLIENT_BASED_GEOLOCATION) - // FIXME: Pass options to client. - +#if USE(PREEMPT_GEOLOCATION_PERMISSION) if (!isAllowed()) { m_startRequestPermissionNotifier = notifier; requestPermission(); return true; } - +#endif + +#if ENABLE(CLIENT_BASED_GEOLOCATION) if (!m_frame) return false; @@ -644,6 +648,7 @@ bool Geolocation::startUpdating(GeoNotifier* notifier) if (!page) return false; + // FIXME: Pass options to client. page->geolocationController()->addObserver(this); return true; #else diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h index f831b87..af10632 100644 --- a/WebCore/page/Geolocation.h +++ b/WebCore/page/Geolocation.h @@ -169,7 +169,8 @@ private: Frame* m_frame; #if !ENABLE(CLIENT_BASED_GEOLOCATION) OwnPtr<GeolocationService> m_service; -#else +#endif +#if USE(PREEMPT_GEOLOCATION_PERMISSION) RefPtr<GeoNotifier> m_startRequestPermissionNotifier; #endif RefPtr<Geoposition> m_lastPosition; diff --git a/WebCore/page/MemoryInfo.cpp b/WebCore/page/MemoryInfo.cpp index 010a19c..c2247b9 100644 --- a/WebCore/page/MemoryInfo.cpp +++ b/WebCore/page/MemoryInfo.cpp @@ -31,17 +31,21 @@ #include "config.h" #include "MemoryInfo.h" +#include "Frame.h" #include "ScriptGCEvent.h" +#include "Settings.h" namespace WebCore { -MemoryInfo::MemoryInfo() +MemoryInfo::MemoryInfo(Frame* frame) : m_totalJSHeapSize(0), m_usedJSHeapSize(0) { + if (frame && frame->settings() && frame->settings()->memoryInfoEnabled()) { #if ENABLE(INSPECTOR) - ScriptGCEvent::getHeapSize(m_usedJSHeapSize, m_totalJSHeapSize); + ScriptGCEvent::getHeapSize(m_usedJSHeapSize, m_totalJSHeapSize); #endif + } } } // namespace WebCore diff --git a/WebCore/page/MemoryInfo.h b/WebCore/page/MemoryInfo.h index e9e0fa5..615e952 100644 --- a/WebCore/page/MemoryInfo.h +++ b/WebCore/page/MemoryInfo.h @@ -36,15 +36,17 @@ namespace WebCore { +class Frame; + class MemoryInfo : public RefCounted<MemoryInfo> { public: - static PassRefPtr<MemoryInfo> create() { return adoptRef(new MemoryInfo()); } + static PassRefPtr<MemoryInfo> create(Frame* frame) { return adoptRef(new MemoryInfo(frame)); } size_t totalJSHeapSize() const { return m_totalJSHeapSize; } size_t usedJSHeapSize() const { return m_usedJSHeapSize; } private: - MemoryInfo(); + MemoryInfo(Frame*); size_t m_totalJSHeapSize; size_t m_usedJSHeapSize; diff --git a/WebCore/page/Navigation.cpp b/WebCore/page/Navigation.cpp index efda924..ad93b47 100644 --- a/WebCore/page/Navigation.cpp +++ b/WebCore/page/Navigation.cpp @@ -57,20 +57,20 @@ void Navigation::disconnectFrame() unsigned short Navigation::type() const { if (!m_frame) - return Navigate; + return NAVIGATE; DocumentLoader* documentLoader = m_frame->loader()->documentLoader(); if (!documentLoader) - return Navigate; + return NAVIGATE; WebCore::NavigationType navigationType = documentLoader->triggeringAction().type(); switch (navigationType) { case NavigationTypeReload: - return Reload; + return RELOAD; case NavigationTypeBackForward: - return BackForward; + return BACK_FORWARD; default: - return Navigate; + return NAVIGATE; } } @@ -79,7 +79,11 @@ unsigned short Navigation::redirectCount() const if (!m_frame) return 0; - return 0; // FIXME + DocumentLoader* loader = m_frame->loader()->documentLoader(); + if (!loader) + return 0; + + return loader->timing()->redirectCount; } } // namespace WebCore diff --git a/WebCore/page/Navigation.h b/WebCore/page/Navigation.h index 85c7b55..ba68ff3 100644 --- a/WebCore/page/Navigation.h +++ b/WebCore/page/Navigation.h @@ -47,17 +47,16 @@ public: Frame* frame() const; void disconnectFrame(); + enum NavigationType { + NAVIGATE, + RELOAD, + BACK_FORWARD + }; + unsigned short type() const; unsigned short redirectCount() const; private: - // Keep in sync with what's in the .idl file. - enum NavigationType { - Navigate = 0, - Reload = 1, - BackForward = 2, - }; - Navigation(Frame*); Frame* m_frame; diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp index ee99c43..8e471fc 100644 --- a/WebCore/page/Page.cpp +++ b/WebCore/page/Page.cpp @@ -57,10 +57,12 @@ #include "ProgressTracker.h" #include "RenderTheme.h" #include "RenderWidget.h" +#include "RuntimeEnabledFeatures.h" #include "ScriptController.h" #include "SelectionController.h" #include "Settings.h" #include "SharedBuffer.h" +#include "SpeechInputClient.h" #include "StringHash.h" #include "TextResourceDecoder.h" #include "Widget.h" @@ -153,7 +155,10 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi , m_geolocationController(new GeolocationController(this, geolocationControllerClient)) #endif #if ENABLE(DEVICE_ORIENTATION) - , m_deviceOrientationController(new DeviceOrientationController(this, deviceOrientationClient)) + , m_deviceOrientationController(RuntimeEnabledFeatures::deviceOrientationEnabled() ? new DeviceOrientationController(this, deviceOrientationClient) : 0) +#endif +#if ENABLE(INPUT_SPEECH) + , m_speechInputClient(0) #endif , m_settings(new Settings(this)) , m_progress(new ProgressTracker) diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h index 56a25eb..8599a83 100644 --- a/WebCore/page/Page.h +++ b/WebCore/page/Page.h @@ -70,6 +70,7 @@ namespace WebCore { class VisibleSelection; class SelectionController; class Settings; + class SpeechInputClient; #if ENABLE(DOM_STORAGE) class StorageNamespace; @@ -152,6 +153,10 @@ namespace WebCore { #if ENABLE(DEVICE_ORIENTATION) DeviceOrientationController* deviceOrientationController() const { return m_deviceOrientationController.get(); } #endif +#if ENABLE(INPUT_SPEECH) + void setSpeechInputClient(SpeechInputClient* client) { m_speechInputClient = client; } + SpeechInputClient* speechInputClient() const { return m_speechInputClient; } +#endif Settings* settings() const { return m_settings.get(); } ProgressTracker* progress() const { return m_progress.get(); } @@ -269,6 +274,9 @@ namespace WebCore { #if ENABLE(DEVICE_ORIENTATION) OwnPtr<DeviceOrientationController> m_deviceOrientationController; #endif +#if ENABLE(INPUT_SPEECH) + SpeechInputClient* m_speechInputClient; +#endif OwnPtr<Settings> m_settings; OwnPtr<ProgressTracker> m_progress; diff --git a/WebCore/page/PageGroup.cpp b/WebCore/page/PageGroup.cpp index b45b9ea..e0502c5 100644 --- a/WebCore/page/PageGroup.cpp +++ b/WebCore/page/PageGroup.cpp @@ -242,12 +242,7 @@ void PageGroup::addUserStyleSheetToWorld(DOMWrapperWorld* world, const String& s styleSheetsInWorld = new UserStyleSheetVector; styleSheetsInWorld->append(userStyleSheet.release()); - // Clear our cached sheets and have them just reparse. - HashSet<Page*>::const_iterator end = m_pages.end(); - for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) { - for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) - frame->document()->clearPageGroupUserSheets(); - } + resetUserStyleCacheInAllFrames(); } void PageGroup::removeUserScriptFromWorld(DOMWrapperWorld* world, const KURL& url) @@ -301,13 +296,8 @@ void PageGroup::removeUserStyleSheetFromWorld(DOMWrapperWorld* world, const KURL delete it->second; m_userStyleSheets->remove(it); } - - // Clear our cached sheets and have them just reparse. - HashSet<Page*>::const_iterator end = m_pages.end(); - for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) { - for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) - frame->document()->clearPageGroupUserSheets(); - } + + resetUserStyleCacheInAllFrames(); } void PageGroup::removeUserScriptsFromWorld(DOMWrapperWorld* world) @@ -339,12 +329,7 @@ void PageGroup::removeUserStyleSheetsFromWorld(DOMWrapperWorld* world) delete it->second; m_userStyleSheets->remove(it); - // Clear our cached sheets and have them just reparse. - HashSet<Page*>::const_iterator end = m_pages.end(); - for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) { - for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) - frame->document()->clearPageGroupUserSheets(); - } + resetUserStyleCacheInAllFrames(); } void PageGroup::removeAllUserContent() @@ -353,12 +338,24 @@ void PageGroup::removeAllUserContent() deleteAllValues(*m_userScripts); m_userScripts.clear(); } - - + if (m_userStyleSheets) { deleteAllValues(*m_userStyleSheets); m_userStyleSheets.clear(); + resetUserStyleCacheInAllFrames(); } } +void PageGroup::resetUserStyleCacheInAllFrames() +{ +#if !PLATFORM(CHROMIUM) + // Clear our cached sheets and have them just reparse. + HashSet<Page*>::const_iterator end = m_pages.end(); + for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) { + for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) + frame->document()->clearPageGroupUserSheets(); + } +#endif +} + } // namespace WebCore diff --git a/WebCore/page/PageGroup.h b/WebCore/page/PageGroup.h index 545df78..77aa281 100644 --- a/WebCore/page/PageGroup.h +++ b/WebCore/page/PageGroup.h @@ -94,7 +94,8 @@ namespace WebCore { private: void addVisitedLink(LinkHash stringHash); - + void resetUserStyleCacheInAllFrames(); + String m_name; HashSet<Page*> m_pages; diff --git a/WebCore/page/Performance.cpp b/WebCore/page/Performance.cpp index c19ce8f..c4234a7 100644 --- a/WebCore/page/Performance.cpp +++ b/WebCore/page/Performance.cpp @@ -31,6 +31,7 @@ #include "config.h" #include "Performance.h" +#include "MemoryInfo.h" #include "Navigation.h" #include "Timing.h" @@ -52,6 +53,8 @@ Frame* Performance::frame() const void Performance::disconnectFrame() { + if (m_memory) + m_memory = 0; if (m_navigation) { m_navigation->disconnectFrame(); m_navigation = 0; @@ -63,6 +66,12 @@ void Performance::disconnectFrame() m_frame = 0; } +MemoryInfo* Performance::memory() const +{ + m_memory = MemoryInfo::create(m_frame); + return m_memory.get(); +} + Navigation* Performance::navigation() const { if (!m_navigation) diff --git a/WebCore/page/Performance.h b/WebCore/page/Performance.h index f317076..9736fe7 100644 --- a/WebCore/page/Performance.h +++ b/WebCore/page/Performance.h @@ -33,6 +33,7 @@ #if ENABLE(WEB_TIMING) +#include "MemoryInfo.h" #include "Navigation.h" #include "Timing.h" #include <wtf/PassRefPtr.h> @@ -48,12 +49,14 @@ public: Frame* frame() const; void disconnectFrame(); + MemoryInfo* memory() const; Navigation* navigation() const; Timing* timing() const; private: Performance(Frame*); + mutable RefPtr<MemoryInfo> m_memory; mutable RefPtr<Navigation> m_navigation; mutable RefPtr<Timing> m_timing; Frame* m_frame; diff --git a/WebCore/page/Performance.idl b/WebCore/page/Performance.idl index 3885e2c..ffe8b6f 100644 --- a/WebCore/page/Performance.idl +++ b/WebCore/page/Performance.idl @@ -34,6 +34,7 @@ module window { interface [Conditional=WEB_TIMING, OmitConstructor] Performance { readonly attribute Navigation navigation; readonly attribute Timing timing; + readonly attribute MemoryInfo memory; }; } diff --git a/WebCore/page/PrintContext.cpp b/WebCore/page/PrintContext.cpp index cc3707e..2bbc63a 100644 --- a/WebCore/page/PrintContext.cpp +++ b/WebCore/page/PrintContext.cpp @@ -245,4 +245,52 @@ int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels) return printContext.pageCount(); } +void PrintContext::spoolAllPagesWithBoundaries(Frame* frame, GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels) +{ + if (!frame->document() || !frame->view() || !frame->document()->renderer()) + return; + + frame->document()->updateLayout(); + + PrintContext printContext(frame); + printContext.begin(pageSizeInPixels.width()); + + float pageHeight; + printContext.computePageRects(FloatRect(FloatPoint(0, 0), pageSizeInPixels), 0, 0, 1, pageHeight); + + const float pageWidth = pageSizeInPixels.width(); + const Vector<IntRect>& pageRects = printContext.pageRects(); + int totalHeight = pageRects.size() * (pageSizeInPixels.height() + 1) - 1; + + // Fill the whole background by white. + graphicsContext.setFillColor(Color(255, 255, 255), DeviceColorSpace); + graphicsContext.fillRect(FloatRect(0, 0, pageWidth, totalHeight)); + + graphicsContext.save(); + graphicsContext.translate(0, totalHeight); + graphicsContext.scale(FloatSize(1, -1)); + + int currentHeight = 0; + for (size_t pageIndex = 0; pageIndex < pageRects.size(); pageIndex++) { + // Draw a line for a page boundary if this isn't the first page. + if (pageIndex > 0) { + graphicsContext.save(); + graphicsContext.setStrokeColor(Color(0, 0, 255), DeviceColorSpace); + graphicsContext.setFillColor(Color(0, 0, 255), DeviceColorSpace); + graphicsContext.drawLine(IntPoint(0, currentHeight), + IntPoint(pageWidth, currentHeight)); + graphicsContext.restore(); + } + + graphicsContext.save(); + graphicsContext.translate(0, currentHeight); + printContext.spoolPage(graphicsContext, pageIndex, pageWidth); + graphicsContext.restore(); + + currentHeight += pageSizeInPixels.height() + 1; + } + + graphicsContext.restore(); +} + } diff --git a/WebCore/page/PrintContext.h b/WebCore/page/PrintContext.h index 1080c29..8492718 100644 --- a/WebCore/page/PrintContext.h +++ b/WebCore/page/PrintContext.h @@ -59,6 +59,10 @@ public: static bool isPageBoxVisible(Frame* frame, int pageNumber); static String pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft); static int numberOfPages(Frame*, const FloatSize& pageSizeInPixels); + // Draw all pages into a graphics context with lines which mean page boundaries. + // The height of the graphics context should be + // (pageSizeInPixels.height() + 1) * number-of-pages - 1 + static void spoolAllPagesWithBoundaries(Frame*, GraphicsContext&, const FloatSize& pageSizeInPixels); protected: Frame* m_frame; diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp index 51d387a..bca2c7b 100644 --- a/WebCore/page/Settings.cpp +++ b/WebCore/page/Settings.cpp @@ -148,9 +148,13 @@ Settings::Settings(Page* page) , m_html5TreeBuilderEnabled(false) // Will be deleted soon, do not use. , m_paginateDuringLayoutEnabled(false) , m_dnsPrefetchingEnabled(true) +<<<<<<< HEAD:WebCore/page/Settings.cpp #ifdef ANDROID_PLUGINS , m_pluginsOnDemand(false) #endif +======= + , m_memoryInfoEnabled(false) +>>>>>>> webkit.org at r63859:WebCore/page/Settings.cpp { // A Frame may not have been created yet, so we initialize the AtomicString // hash before trying to use it. diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h index abf0699..d1ffdbe 100644 --- a/WebCore/page/Settings.h +++ b/WebCore/page/Settings.h @@ -376,6 +376,9 @@ namespace WebCore { void setPaginateDuringLayoutEnabled(bool flag) { m_paginateDuringLayoutEnabled = flag; } bool paginateDuringLayoutEnabled() const { return m_paginateDuringLayoutEnabled; } + void setMemoryInfoEnabled(bool flag) { m_memoryInfoEnabled = flag; } + bool memoryInfoEnabled() const { return m_memoryInfoEnabled; } + private: Page* m_page; @@ -496,9 +499,13 @@ namespace WebCore { bool m_html5TreeBuilderEnabled: 1; // Will be deleted soon, do not use. bool m_paginateDuringLayoutEnabled : 1; bool m_dnsPrefetchingEnabled : 1; +<<<<<<< HEAD:WebCore/page/Settings.h #ifdef ANDROID_PLUGINS bool m_pluginsOnDemand : 1; #endif +======= + bool m_memoryInfoEnabled: 1; +>>>>>>> webkit.org at r63859:WebCore/page/Settings.h #if USE(SAFARI_THEME) static bool gShouldPaintNativeControls; diff --git a/WebCore/page/SpatialNavigation.cpp b/WebCore/page/SpatialNavigation.cpp index e748d12..40aa52b 100644 --- a/WebCore/page/SpatialNavigation.cpp +++ b/WebCore/page/SpatialNavigation.cpp @@ -103,14 +103,9 @@ void distanceDataForNode(FocusDirection direction, Node* start, FocusCandidate& // FIXME: This function does not behave correctly with transformed frames. static IntRect renderRectRelativeToRootDocument(RenderObject* render) { - ASSERT(render); + ASSERT(render && render->node()); - IntRect rect(render->absoluteClippedOverflowRect()); - - if (rect.isEmpty()) { - Element* e = static_cast<Element*>(render->node()); - rect = e->getRect(); - } + IntRect rect = render->node()->getRect(); // In cases when the |render|'s associated node is in a scrollable inner // document, we only consider its scrollOffset if it is not offscreen. @@ -517,7 +512,7 @@ static bool checkNegativeCoordsForNode(Node* node, const IntRect& curRect) { ASSERT(node || node->renderer()); - if (curRect.x() > 0 && curRect.y() > 0) + if (curRect.x() >= 0 && curRect.y() >= 0) return true; bool canBeScrolled = false; diff --git a/WebCore/page/SpeechInput.cpp b/WebCore/page/SpeechInput.cpp new file mode 100644 index 0000000..92df70e --- /dev/null +++ b/WebCore/page/SpeechInput.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 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 "SpeechInput.h" + +#if ENABLE(INPUT_SPEECH) + +#include "Frame.h" +#include "SpeechInputClient.h" +#include "SpeechInputListener.h" + +namespace WebCore { + +SpeechInput::SpeechInput(SpeechInputClient* client, SpeechInputListener* listener) + : m_client(client) + , m_listener(listener) +{ +} + +void SpeechInput::recordingComplete() +{ + m_listener->recordingComplete(); +} + +void SpeechInput::setRecognitionResult(const String& result) +{ + m_listener->setRecognitionResult(result); +} + +bool SpeechInput::startRecognition() +{ + if (m_client) + return m_client->startRecognition(this); + return false; +} + +} // namespace WebCore + +#endif // ENABLE(INPUT_SPEECH) diff --git a/WebCore/page/SpeechInput.h b/WebCore/page/SpeechInput.h new file mode 100644 index 0000000..201be99 --- /dev/null +++ b/WebCore/page/SpeechInput.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 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 SpeechInput_h +#define SpeechInput_h + +#if ENABLE(INPUT_SPEECH) + +#include "SpeechInputClientListener.h" +#include <wtf/Noncopyable.h> + +namespace WebCore { + +class SpeechInputClient; +class SpeechInputListener; +class String; + +// This class connects the input elements requiring speech input with the platform specific +// speech recognition engine. It provides methods for the input elements to activate speech +// recognition and methods for the speech recognition engine to return back the results. +class SpeechInput : public Noncopyable, public SpeechInputClientListener { +public: + SpeechInput(SpeechInputClient*, SpeechInputListener*); + virtual ~SpeechInput() { } + + // Methods invoked by the input elements. + virtual bool startRecognition(); + + // SpeechInputClient::Listener methods. + virtual void recordingComplete(); + virtual void setRecognitionResult(const String&); + +protected: + SpeechInputClient* client() const { return m_client; } + +private: + SpeechInputClient* m_client; + SpeechInputListener* m_listener; +}; + +} // namespace WebCore + +#endif // ENABLE(INPUT_SPEECH) + +#endif // SpeechInput_h diff --git a/WebCore/page/SpeechInputClient.h b/WebCore/page/SpeechInputClient.h new file mode 100644 index 0000000..be68f46 --- /dev/null +++ b/WebCore/page/SpeechInputClient.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Google 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: + * + * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 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 SpeechInputClient_h +#define SpeechInputClient_h + +#if ENABLE(INPUT_SPEECH) + +namespace WebCore { + +class SpeechInputClientListener; + +// Provides an interface for SpeechInput to call into the embedder. +class SpeechInputClient { +public: + virtual bool startRecognition(SpeechInputClientListener* listener) = 0; + +protected: + virtual ~SpeechInputClient() { } +}; + +} // namespace WebCore + +#endif // ENABLE(INPUT_SPEECH) + +#endif // SpeechInputClient_h diff --git a/WebCore/page/SpeechInputClientListener.h b/WebCore/page/SpeechInputClientListener.h new file mode 100644 index 0000000..a9a897e --- /dev/null +++ b/WebCore/page/SpeechInputClientListener.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 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 SpeechInputClientListener_h +#define SpeechInputClientListener_h + +#if ENABLE(INPUT_SPEECH) + +namespace WebCore { + +class String; + +// Provides an interface for the embedder to call into WebCore. +class SpeechInputClientListener { +public: + virtual void recordingComplete() = 0; + virtual void setRecognitionResult(const String& result) = 0; + +protected: + virtual ~SpeechInputClientListener() { } +}; + +} // namespace WebCore + +#endif // ENABLE(INPUT_SPEECH) + +#endif // SpeechInputClientListener_h diff --git a/WebCore/page/SpeechInputListener.h b/WebCore/page/SpeechInputListener.h new file mode 100644 index 0000000..d087d36 --- /dev/null +++ b/WebCore/page/SpeechInputListener.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 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 SpeechInputListener_h +#define SpeechInputListener_h + +#if ENABLE(INPUT_SPEECH) + +namespace WebCore { + +class String; + +// Interface to be implemented by the element which invokes SpeechInput. +class SpeechInputListener { +public: + virtual void recordingComplete() = 0; + virtual void setRecognitionResult(const String& result) = 0; + +protected: + virtual ~SpeechInputListener() { } +}; + +} // namespace WebCore + +#endif // ENABLE(INPUT_SPEECH) + +#endif // SpeechInputListener_h diff --git a/WebCore/page/Timing.cpp b/WebCore/page/Timing.cpp index af00441..527390a 100644 --- a/WebCore/page/Timing.cpp +++ b/WebCore/page/Timing.cpp @@ -33,10 +33,40 @@ #if ENABLE(WEB_TIMING) +#include "DocumentLoader.h" #include "Frame.h" +#include "ResourceLoadTiming.h" +#include "ResourceResponse.h" namespace WebCore { +static unsigned long long toIntegerMilliseconds(double seconds) +{ + ASSERT(seconds >= 0); + return static_cast<unsigned long long>(seconds * 1000.0); +} + +static double getPossiblySkewedTimeInKnownRange(double skewedTime, double lowerBound, double upperBound) +{ +#if PLATFORM(CHROMIUM) + // The chromium port's currentTime() implementation only syncs with the + // system clock every 60 seconds. So it is possible for timing marks + // collected in different threads or processes to have a small skew. + // FIXME: It may be possible to add a currentTimeFromSystemTime() method + // that eliminates the skew. + if (skewedTime <= lowerBound) + return lowerBound; + + if (skewedTime >= upperBound) + return upperBound; +#else + ASSERT_UNUSED(lowerBound, skewedTime >= lowerBound); + ASSERT_UNUSED(upperBound, skewedTime <= upperBound); +#endif + + return skewedTime; +} + Timing::Timing(Frame* frame) : m_frame(frame) { @@ -54,34 +84,214 @@ void Timing::disconnectFrame() unsigned long long Timing::navigationStart() const { - if (!m_frame) + DocumentLoadTiming* timing = documentLoadTiming(); + if (!timing) return 0; - return static_cast<unsigned long long>(m_frame->loader()->frameLoadTimeline()->navigationStart * 1000); + return toIntegerMilliseconds(timing->navigationStart); } unsigned long long Timing::unloadEventEnd() const { - if (!m_frame) + DocumentLoadTiming* timing = documentLoadTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->unloadEventEnd); +} + +unsigned long long Timing::redirectStart() const +{ + DocumentLoadTiming* timing = documentLoadTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->redirectStart); +} + +unsigned long long Timing::redirectEnd() const +{ + DocumentLoadTiming* timing = documentLoadTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->redirectEnd); +} + +unsigned long long Timing::fetchStart() const +{ + DocumentLoadTiming* timing = documentLoadTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->fetchStart); +} + +unsigned long long Timing::domainLookupStart() const +{ + ResourceLoadTiming* timing = resourceLoadTiming(); + if (!timing) + return 0; + + // This will be -1 when a DNS request is not performed. + // Rather than exposing a special value that indicates no DNS, we "backfill" with fetchStart. + int dnsStart = timing->dnsStart; + if (dnsStart < 0) + return fetchStart(); + + return resourceLoadTimeRelativeToAbsolute(dnsStart); +} + +unsigned long long Timing::domainLookupEnd() const +{ + ResourceLoadTiming* timing = resourceLoadTiming(); + if (!timing) return 0; - return static_cast<unsigned long long>(m_frame->loader()->frameLoadTimeline()->unloadEventEnd * 1000); + // This will be -1 when a DNS request is not performed. + // Rather than exposing a special value that indicates no DNS, we "backfill" with domainLookupStart. + int dnsEnd = timing->dnsEnd; + if (dnsEnd < 0) + return domainLookupStart(); + + return resourceLoadTimeRelativeToAbsolute(dnsEnd); +} + +unsigned long long Timing::connectStart() const +{ + ResourceLoadTiming* timing = resourceLoadTiming(); + if (!timing) + return 0; + + // This will be -1 when a new connection is not established. + // Rather than exposing a special value that indicates no new connection, we "backfill" with domainLookupEnd. + int connectStart = timing->connectStart; + if (connectStart < 0) + return domainLookupEnd(); + + return resourceLoadTimeRelativeToAbsolute(connectStart); +} + +unsigned long long Timing::connectEnd() const +{ + ResourceLoadTiming* timing = resourceLoadTiming(); + if (!timing) + return 0; + + // This will be -1 when a new connection is not established. + // Rather than exposing a special value that indicates no new connection, we "backfill" with connectStart. + int connectEnd = timing->connectEnd; + if (connectEnd < 0) + return connectStart(); + + return resourceLoadTimeRelativeToAbsolute(connectEnd); +} + +unsigned long long Timing::requestStart() const +{ + ResourceLoadTiming* timing = resourceLoadTiming(); + if (!timing) + return 0; + + ASSERT(timing->sendStart >= 0); + return resourceLoadTimeRelativeToAbsolute(timing->sendStart); +} + +unsigned long long Timing::requestEnd() const +{ + ResourceLoadTiming* timing = resourceLoadTiming(); + if (!timing) + return 0; + + ASSERT(timing->sendEnd >= 0); + return resourceLoadTimeRelativeToAbsolute(timing->sendEnd); +} + +unsigned long long Timing::responseStart() const +{ + ResourceLoadTiming* timing = resourceLoadTiming(); + if (!timing) + return 0; + + // FIXME: Response start needs to be the time of the first received byte. + // However, the ResourceLoadTiming API currently only supports the time + // the last header byte was received. For many responses with reasonable + // sized cookies, the HTTP headers fit into a single packet so this time + // is basically equivalent. But for some responses, particularly those with + // headers larger than a single packet, this time will be too late. + ASSERT(timing->receiveHeadersEnd >= 0); + return resourceLoadTimeRelativeToAbsolute(timing->receiveHeadersEnd); +} + +unsigned long long Timing::responseEnd() const +{ + DocumentLoadTiming* timing = documentLoadTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->responseEnd); } unsigned long long Timing::loadEventStart() const { - if (!m_frame) + DocumentLoadTiming* timing = documentLoadTiming(); + if (!timing) return 0; - return static_cast<unsigned long long>(m_frame->loader()->frameLoadTimeline()->loadEventStart * 1000); + return toIntegerMilliseconds(timing->loadEventStart); } unsigned long long Timing::loadEventEnd() const { + DocumentLoadTiming* timing = documentLoadTiming(); + if (!timing) + return 0; + + return toIntegerMilliseconds(timing->loadEventEnd); +} + +DocumentLoader* Timing::documentLoader() const +{ if (!m_frame) return 0; - return static_cast<unsigned long long>(m_frame->loader()->frameLoadTimeline()->loadEventEnd * 1000); + return m_frame->loader()->documentLoader(); +} + +DocumentLoadTiming* Timing::documentLoadTiming() const +{ + DocumentLoader* loader = documentLoader(); + if (!loader) + return 0; + + return loader->timing(); +} + +ResourceLoadTiming* Timing::resourceLoadTiming() const +{ + DocumentLoader* loader = documentLoader(); + if (!loader) + return 0; + + return loader->response().resourceLoadTiming(); +} + +unsigned long long Timing::resourceLoadTimeRelativeToAbsolute(int relativeSeconds) const +{ + ASSERT(relativeSeconds >= 0); + ResourceLoadTiming* resourceTiming = resourceLoadTiming(); + ASSERT(resourceTiming); + DocumentLoadTiming* documentTiming = documentLoadTiming(); + ASSERT(documentTiming); + + // The ResourceLoadTiming API's requestTime is the base time to which all + // other marks are relative. So to get an absolute time, we must add it to + // the relative marks. + // + // Since ResourceLoadTimings came from the network platform layer, we must + // check them for skew because they may be from another thread/process. + double baseTime = getPossiblySkewedTimeInKnownRange(resourceTiming->requestTime, documentTiming->fetchStart, documentTiming->responseEnd); + return toIntegerMilliseconds(baseTime) + relativeSeconds; } } // namespace WebCore diff --git a/WebCore/page/Timing.h b/WebCore/page/Timing.h index 47ce478..f48f525 100644 --- a/WebCore/page/Timing.h +++ b/WebCore/page/Timing.h @@ -38,7 +38,10 @@ namespace WebCore { +struct DocumentLoadTiming; +class DocumentLoader; class Frame; +class ResourceLoadTiming; class Timing : public RefCounted<Timing> { public: @@ -49,12 +52,28 @@ public: unsigned long long navigationStart() const; unsigned long long unloadEventEnd() const; + unsigned long long redirectStart() const; + unsigned long long redirectEnd() const; + unsigned long long fetchStart() const; + unsigned long long domainLookupStart() const; + unsigned long long domainLookupEnd() const; + unsigned long long connectStart() const; + unsigned long long connectEnd() const; + unsigned long long requestStart() const; + unsigned long long requestEnd() const; + unsigned long long responseStart() const; + unsigned long long responseEnd() const; unsigned long long loadEventStart() const; unsigned long long loadEventEnd() const; private: Timing(Frame*); + DocumentLoader* documentLoader() const; + DocumentLoadTiming* documentLoadTiming() const; + ResourceLoadTiming* resourceLoadTiming() const; + unsigned long long resourceLoadTimeRelativeToAbsolute(int) const; + Frame* m_frame; }; diff --git a/WebCore/page/Timing.idl b/WebCore/page/Timing.idl index dbe996e..e7e46cc 100644 --- a/WebCore/page/Timing.idl +++ b/WebCore/page/Timing.idl @@ -32,20 +32,19 @@ module window { // See: http://dev.w3.org/2006/webapi/WebTiming/ interface [Conditional=WEB_TIMING, OmitConstructor] Timing { - // FIXME: Implement remainder of interface. readonly attribute unsigned long long navigationStart; - // readonly attribute unsigned long long fetchStart; readonly attribute unsigned long long unloadEventEnd; - // readonly attribute unsigned long long redirectStart; - // readonly attribute unsigned long long redirectEnd; - // readonly attribute unsigned long long domainLookupStart; - // readonly attribute unsigned long long domainLookupEnd; - // readonly attribute unsigned long long connectStart; - // readonly attribute unsigned long long connectEnd; - // readonly attribute unsigned long long requestStart; - // readonly attribute unsigned long long requestEnd; - // readonly attribute unsigned long long responseStart; - // readonly attribute unsigned long long responseEnd; + readonly attribute unsigned long long redirectStart; + readonly attribute unsigned long long redirectEnd; + readonly attribute unsigned long long fetchStart; + readonly attribute unsigned long long domainLookupStart; + readonly attribute unsigned long long domainLookupEnd; + readonly attribute unsigned long long connectStart; + readonly attribute unsigned long long connectEnd; + readonly attribute unsigned long long requestStart; + readonly attribute unsigned long long requestEnd; + readonly attribute unsigned long long responseStart; + readonly attribute unsigned long long responseEnd; readonly attribute unsigned long long loadEventStart; readonly attribute unsigned long long loadEventEnd; }; diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp index 7195d1f..83fd039 100644 --- a/WebCore/page/animation/AnimationBase.cpp +++ b/WebCore/page/animation/AnimationBase.cpp @@ -774,7 +774,7 @@ AnimationBase::AnimationBase(const Animation* transition, RenderObject* renderer , m_object(renderer) , m_animation(const_cast<Animation*>(transition)) , m_compAnim(compAnim) - , m_fallbackAnimating(false) + , m_isAccelerated(false) , m_transformFunctionListValid(false) , m_nextIterationDuration(-1) , m_next(0) @@ -837,7 +837,7 @@ bool AnimationBase::blendProperties(const AnimationBase* anim, int prop, RenderS if (wrapper) { wrapper->blend(anim, dst, a, b, progress); #if USE(ACCELERATED_COMPOSITING) - return !wrapper->animationIsAccelerated() || anim->isFallbackAnimating(); + return !wrapper->animationIsAccelerated() || !anim->isAccelerated(); #else return true; #endif @@ -974,7 +974,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) // We won't try to start accelerated animations if we are overridden and // just move on to the next state. m_animState = AnimationStateStartWaitResponse; - m_fallbackAnimating = true; + m_isAccelerated = false; updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime()); } else { @@ -985,7 +985,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) bool started = startAnimation(timeOffset); m_compAnim->animationController()->addToStartTimeResponseWaitList(this, started); - m_fallbackAnimating = !started; + m_isAccelerated = started; } break; case AnimationStateStartWaitResponse: @@ -1108,11 +1108,11 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) // We won't try to start accelerated animations if we are overridden and // just move on to the next state. updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime()); - m_fallbackAnimating = true; + m_isAccelerated = false; } else { bool started = startAnimation(beginAnimationUpdateTime() - m_startTime); m_compAnim->animationController()->addToStartTimeResponseWaitList(this, started); - m_fallbackAnimating = !started; + m_isAccelerated = started; } break; case AnimationStateFillingForwards: diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h index 91ef8cf..9bdca3a 100644 --- a/WebCore/page/animation/AnimationBase.h +++ b/WebCore/page/animation/AnimationBase.h @@ -144,9 +144,10 @@ public: // Does this animation/transition involve the given property? virtual bool affectsProperty(int /*property*/) const { return false; } - bool isAnimatingProperty(int property, bool isRunningNow) const + + bool isAnimatingProperty(int property, bool acceleratedOnly, bool isRunningNow) const { - if (m_fallbackAnimating) + if (acceleratedOnly && !m_isAccelerated) return false; if (isRunningNow) @@ -197,7 +198,7 @@ protected: void goIntoEndingOrLoopingState(); - bool isFallbackAnimating() const { return m_fallbackAnimating; } + bool isAccelerated() const { return m_isAccelerated; } static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b); static int getPropertyAtIndex(int, bool& isShorthand); @@ -220,7 +221,7 @@ protected: RefPtr<Animation> m_animation; CompositeAnimation* m_compAnim; - bool m_fallbackAnimating; // true when animating an accelerated property but have to fall back to software + bool m_isAccelerated; bool m_transformFunctionListValid; double m_totalDuration, m_nextIterationDuration; diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp index 3761c5a..b5d87e6 100644 --- a/WebCore/page/animation/AnimationController.cpp +++ b/WebCore/page/animation/AnimationController.cpp @@ -209,13 +209,22 @@ void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPr fireEventsAndUpdateStyle(); } -bool AnimationControllerPrivate::isAnimatingPropertyOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const +bool AnimationControllerPrivate::isRunningAnimationOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const { RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer); if (!animation) return false; - return animation->isAnimatingProperty(property, isRunningNow); + return animation->isAnimatingProperty(property, false, isRunningNow); +} + +bool AnimationControllerPrivate::isRunningAcceleratedAnimationOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const +{ + RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer); + if (!animation) + return false; + + return animation->isAnimatingProperty(property, true, isRunningNow); } void AnimationControllerPrivate::suspendAnimations(Document* document) @@ -532,9 +541,14 @@ bool AnimationController::pauseTransitionAtTime(RenderObject* renderer, const St return m_data->pauseTransitionAtTime(renderer, property, t); } -bool AnimationController::isAnimatingPropertyOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const +bool AnimationController::isRunningAnimationOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const +{ + return m_data->isRunningAnimationOnRenderer(renderer, property, isRunningNow); +} + +bool AnimationController::isRunningAcceleratedAnimationOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const { - return m_data->isAnimatingPropertyOnRenderer(renderer, property, isRunningNow); + return m_data->isRunningAcceleratedAnimationOnRenderer(renderer, property, isRunningNow); } void AnimationController::suspendAnimations(Document* document) diff --git a/WebCore/page/animation/AnimationController.h b/WebCore/page/animation/AnimationController.h index db82618..d184b45 100644 --- a/WebCore/page/animation/AnimationController.h +++ b/WebCore/page/animation/AnimationController.h @@ -61,7 +61,8 @@ public: bool pauseTransitionAtTime(RenderObject*, const String& property, double t); // To be used only for testing unsigned numberOfActiveAnimations() const; // To be used only for testing - bool isAnimatingPropertyOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow = true) const; + bool isRunningAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow = true) const; + bool isRunningAcceleratedAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow = true) const; void suspendAnimations(Document*); void resumeAnimations(Document*); diff --git a/WebCore/page/animation/AnimationControllerPrivate.h b/WebCore/page/animation/AnimationControllerPrivate.h index 5ef9098..3ae15a5 100644 --- a/WebCore/page/animation/AnimationControllerPrivate.h +++ b/WebCore/page/animation/AnimationControllerPrivate.h @@ -70,7 +70,8 @@ public: void suspendAnimations(Document*); void resumeAnimations(Document*); - bool isAnimatingPropertyOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow) const; + bool isRunningAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow) const; + bool isRunningAcceleratedAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow) const; bool pauseAnimationAtTime(RenderObject*, const String& name, double t); bool pauseTransitionAtTime(RenderObject*, const String& property, double t); diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp index 7619b1f..57c2aa4 100644 --- a/WebCore/page/animation/CompositeAnimation.cpp +++ b/WebCore/page/animation/CompositeAnimation.cpp @@ -136,7 +136,7 @@ void CompositeAnimation::updateTransitions(RenderObject* renderer, RenderStyle* #if USE(ACCELERATED_COMPOSITING) // For accelerated animations we need to return a new RenderStyle with the _current_ value // of the property, so that restarted transitions use the correct starting point. - if (AnimationBase::animationOfPropertyIsAccelerated(prop) && !implAnim->isFallbackAnimating()) { + if (AnimationBase::animationOfPropertyIsAccelerated(prop) && implAnim->isAccelerated()) { if (!modifiedCurrentStyle) modifiedCurrentStyle = RenderStyle::clone(currentStyle); @@ -460,14 +460,14 @@ void CompositeAnimation::resumeOverriddenImplicitAnimations(int property) } } -bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) const +bool CompositeAnimation::isAnimatingProperty(int property, bool acceleratedOnly, bool isRunningNow) const { if (!m_keyframeAnimations.isEmpty()) { m_keyframeAnimations.checkConsistency(); AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end(); for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) { KeyframeAnimation* anim = it->second.get(); - if (anim && anim->isAnimatingProperty(property, isRunningNow)) + if (anim && anim->isAnimatingProperty(property, acceleratedOnly, isRunningNow)) return true; } } @@ -476,7 +476,7 @@ bool CompositeAnimation::isAnimatingProperty(int property, bool isRunningNow) co CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end(); for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) { ImplicitAnimation* anim = it->second.get(); - if (anim && anim->isAnimatingProperty(property, isRunningNow)) + if (anim && anim->isAnimatingProperty(property, acceleratedOnly, isRunningNow)) return true; } } diff --git a/WebCore/page/animation/CompositeAnimation.h b/WebCore/page/animation/CompositeAnimation.h index b7db442..51ba565 100644 --- a/WebCore/page/animation/CompositeAnimation.h +++ b/WebCore/page/animation/CompositeAnimation.h @@ -70,8 +70,8 @@ public: bool hasAnimations() const { return !m_transitions.isEmpty() || !m_keyframeAnimations.isEmpty(); } void setAnimating(bool); - bool isAnimatingProperty(int property, bool isRunningNow) const; - + bool isAnimatingProperty(int property, bool acceleratedOnly, bool isRunningNow) const; + PassRefPtr<KeyframeAnimation> getAnimationForProperty(int property) const; void overrideImplicitAnimations(int property); diff --git a/WebCore/page/animation/ImplicitAnimation.cpp b/WebCore/page/animation/ImplicitAnimation.cpp index 328fe0e..da0a810 100644 --- a/WebCore/page/animation/ImplicitAnimation.cpp +++ b/WebCore/page/animation/ImplicitAnimation.cpp @@ -273,7 +273,7 @@ double ImplicitAnimation::timeToNextService() // A return value of 0 means we need service. But if this is an accelerated animation we // only need service at the end of the transition. - if (animationOfPropertyIsAccelerated(m_animatingProperty) && !isFallbackAnimating()) { + if (animationOfPropertyIsAccelerated(m_animatingProperty) && isAccelerated()) { bool isLooping; getTimeToNextEvent(t, isLooping); } diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp index 4c2cbc8..2f2cfc0 100644 --- a/WebCore/page/animation/KeyframeAnimation.cpp +++ b/WebCore/page/animation/KeyframeAnimation.cpp @@ -400,7 +400,7 @@ double KeyframeAnimation::timeToNextService() bool acceleratedPropertiesOnly = true; for (HashSet<int>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) { - if (!animationOfPropertyIsAccelerated(*it) || isFallbackAnimating()) { + if (!animationOfPropertyIsAccelerated(*it) || !isAccelerated()) { acceleratedPropertiesOnly = false; break; } diff --git a/WebCore/page/chromium/ChromeClientChromium.h b/WebCore/page/chromium/ChromeClientChromium.h index e897c15..46985b1 100644 --- a/WebCore/page/chromium/ChromeClientChromium.h +++ b/WebCore/page/chromium/ChromeClientChromium.h @@ -39,6 +39,10 @@ class AccessibilityObject; class IntRect; class PopupContainer; +#if USE(ACCELERATED_COMPOSITING) +class GLES2Context; +#endif + // Contains Chromium-specific extensions to the ChromeClient. Only put // things here that don't make sense for other ports. class ChromeClientChromium : public ChromeClient { @@ -55,6 +59,12 @@ public: // Notifies embedder that the state of an accessibility object has changed. virtual void didChangeAccessibilityObjectState(AccessibilityObject*) = 0; + +#if USE(ACCELERATED_COMPOSITING) + // Request a GL ES 2 context to use for compositing this page's content. + virtual PassOwnPtr<GLES2Context> getOnscreenGLES2Context() = 0; + virtual PassOwnPtr<GLES2Context> getOffscreenGLES2Context() = 0; +#endif }; } // namespace WebCore diff --git a/WebCore/page/mac/EventHandlerMac.mm b/WebCore/page/mac/EventHandlerMac.mm index 8842e31..bb466db 100644 --- a/WebCore/page/mac/EventHandlerMac.mm +++ b/WebCore/page/mac/EventHandlerMac.mm @@ -215,10 +215,14 @@ bool EventHandler::passMouseDownEventToWidget(Widget* pWidget) return true; } + // In WebKit2 we will never have an NSView. Just return early and let the regular event handler machinery take care of + // dispatching the event. + if (!widget->platformWidget()) + return false; + BEGIN_BLOCK_OBJC_EXCEPTIONS; NSView *nodeView = widget->platformWidget(); - ASSERT(nodeView); ASSERT([nodeView superview]); NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentNSEvent() locationInWindow] fromView:nil]]; if (!view) { |