summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/page
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@nokia.com>2010-04-06 10:36:47 (GMT)
committerJocelyn Turcotte <jocelyn.turcotte@nokia.com>2010-04-06 10:36:47 (GMT)
commitbb35b65bbfba82e0dd0ac306d3dab54436cdaff6 (patch)
tree8174cb262a960ff7b2e4aa8f1aaf154db71d2636 /src/3rdparty/webkit/WebCore/page
parent4b27d0d887269583a0f76e922948f8c25e96ab88 (diff)
downloadQt-bb35b65bbfba82e0dd0ac306d3dab54436cdaff6.zip
Qt-bb35b65bbfba82e0dd0ac306d3dab54436cdaff6.tar.gz
Qt-bb35b65bbfba82e0dd0ac306d3dab54436cdaff6.tar.bz2
Update src/3rdparty/webkit from trunk.
Imported from 839d8709327f925aacb3b6362c06152594def97e in branch qtwebkit-2.0 of repository git://gitorious.org/+qtwebkit-developers/webkit/qtwebkit.git Rubber-stamped-by: Simon Hausmann
Diffstat (limited to 'src/3rdparty/webkit/WebCore/page')
-rw-r--r--src/3rdparty/webkit/WebCore/page/AbstractView.idl3
-rw-r--r--src/3rdparty/webkit/WebCore/page/BarInfo.cpp22
-rw-r--r--src/3rdparty/webkit/WebCore/page/BarInfo.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/page/Chrome.cpp46
-rw-r--r--src/3rdparty/webkit/WebCore/page/Chrome.h15
-rw-r--r--src/3rdparty/webkit/WebCore/page/ChromeClient.h27
-rw-r--r--src/3rdparty/webkit/WebCore/page/Console.cpp41
-rw-r--r--src/3rdparty/webkit/WebCore/page/Console.h145
-rw-r--r--src/3rdparty/webkit/WebCore/page/Console.idl6
-rw-r--r--src/3rdparty/webkit/WebCore/page/ContextMenuController.cpp46
-rw-r--r--src/3rdparty/webkit/WebCore/page/ContextMenuController.h9
-rw-r--r--src/3rdparty/webkit/WebCore/page/ContextMenuProvider.h52
-rw-r--r--src/3rdparty/webkit/WebCore/page/Coordinates.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/page/DOMSelection.cpp1
-rw-r--r--src/3rdparty/webkit/WebCore/page/DOMSelection.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/page/DOMTimer.cpp11
-rw-r--r--src/3rdparty/webkit/WebCore/page/DOMTimer.h7
-rw-r--r--src/3rdparty/webkit/WebCore/page/DOMWindow.cpp165
-rw-r--r--src/3rdparty/webkit/WebCore/page/DOMWindow.h76
-rw-r--r--src/3rdparty/webkit/WebCore/page/DOMWindow.idl189
-rw-r--r--src/3rdparty/webkit/WebCore/page/DragController.cpp67
-rw-r--r--src/3rdparty/webkit/WebCore/page/DragController.h4
-rw-r--r--src/3rdparty/webkit/WebCore/page/EventHandler.cpp552
-rw-r--r--src/3rdparty/webkit/WebCore/page/EventHandler.h48
-rw-r--r--src/3rdparty/webkit/WebCore/page/EventSource.cpp25
-rw-r--r--src/3rdparty/webkit/WebCore/page/EventSource.h2
-rw-r--r--src/3rdparty/webkit/WebCore/page/EventSource.idl9
-rw-r--r--src/3rdparty/webkit/WebCore/page/FocusController.cpp171
-rw-r--r--src/3rdparty/webkit/WebCore/page/FocusController.h56
-rw-r--r--src/3rdparty/webkit/WebCore/page/FocusDirection.h9
-rw-r--r--src/3rdparty/webkit/WebCore/page/Frame.cpp431
-rw-r--r--src/3rdparty/webkit/WebCore/page/Frame.h89
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameTree.cpp1
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameView.cpp266
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameView.h33
-rw-r--r--src/3rdparty/webkit/WebCore/page/Geolocation.cpp363
-rw-r--r--src/3rdparty/webkit/WebCore/page/Geolocation.h70
-rw-r--r--src/3rdparty/webkit/WebCore/page/Geolocation.idl4
-rw-r--r--src/3rdparty/webkit/WebCore/page/GeolocationController.cpp93
-rw-r--r--src/3rdparty/webkit/WebCore/page/GeolocationController.h67
-rw-r--r--src/3rdparty/webkit/WebCore/page/GeolocationControllerClient.h47
-rw-r--r--src/3rdparty/webkit/WebCore/page/GeolocationError.h65
-rw-r--r--src/3rdparty/webkit/WebCore/page/GeolocationPosition.h111
-rw-r--r--src/3rdparty/webkit/WebCore/page/GeolocationPositionCache.cpp178
-rw-r--r--src/3rdparty/webkit/WebCore/page/GeolocationPositionCache.h58
-rw-r--r--src/3rdparty/webkit/WebCore/page/Geoposition.h7
-rw-r--r--src/3rdparty/webkit/WebCore/page/Geoposition.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/page/HaltablePlugin.h2
-rw-r--r--src/3rdparty/webkit/WebCore/page/History.cpp45
-rw-r--r--src/3rdparty/webkit/WebCore/page/History.h42
-rw-r--r--src/3rdparty/webkit/WebCore/page/History.idl8
-rw-r--r--src/3rdparty/webkit/WebCore/page/Location.idl3
-rw-r--r--src/3rdparty/webkit/WebCore/page/MediaCanStartListener.h (renamed from src/3rdparty/webkit/WebCore/page/android/DragControllerAndroid.cpp)44
-rw-r--r--src/3rdparty/webkit/WebCore/page/MouseEventWithHitTestResults.h2
-rw-r--r--src/3rdparty/webkit/WebCore/page/Navigator.cpp92
-rw-r--r--src/3rdparty/webkit/WebCore/page/Navigator.h5
-rw-r--r--src/3rdparty/webkit/WebCore/page/Navigator.idl10
-rw-r--r--src/3rdparty/webkit/WebCore/page/NavigatorBase.cpp12
-rw-r--r--src/3rdparty/webkit/WebCore/page/Page.cpp148
-rw-r--r--src/3rdparty/webkit/WebCore/page/Page.h79
-rw-r--r--src/3rdparty/webkit/WebCore/page/PageGroup.cpp47
-rw-r--r--src/3rdparty/webkit/WebCore/page/PageGroup.h12
-rw-r--r--src/3rdparty/webkit/WebCore/page/PluginHalter.cpp3
-rw-r--r--src/3rdparty/webkit/WebCore/page/PluginHalter.h2
-rw-r--r--src/3rdparty/webkit/WebCore/page/PluginHalterClient.h3
-rw-r--r--src/3rdparty/webkit/WebCore/page/PositionCallback.h1
-rw-r--r--src/3rdparty/webkit/WebCore/page/PositionError.h1
-rw-r--r--src/3rdparty/webkit/WebCore/page/PositionError.idl5
-rw-r--r--src/3rdparty/webkit/WebCore/page/PositionErrorCallback.h1
-rw-r--r--src/3rdparty/webkit/WebCore/page/PrintContext.cpp85
-rw-r--r--src/3rdparty/webkit/WebCore/page/PrintContext.h10
-rw-r--r--src/3rdparty/webkit/WebCore/page/Screen.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp221
-rw-r--r--src/3rdparty/webkit/WebCore/page/SecurityOrigin.h312
-rw-r--r--src/3rdparty/webkit/WebCore/page/Settings.cpp90
-rw-r--r--src/3rdparty/webkit/WebCore/page/Settings.h60
-rw-r--r--src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp503
-rw-r--r--src/3rdparty/webkit/WebCore/page/SpatialNavigation.h129
-rw-r--r--src/3rdparty/webkit/WebCore/page/UserScript.h7
-rw-r--r--src/3rdparty/webkit/WebCore/page/UserScriptTypes.h3
-rw-r--r--src/3rdparty/webkit/WebCore/page/UserStyleSheet.h8
-rw-r--r--src/3rdparty/webkit/WebCore/page/UserStyleSheetTypes.h3
-rw-r--r--src/3rdparty/webkit/WebCore/page/WebKitPoint.idl2
-rw-r--r--src/3rdparty/webkit/WebCore/page/WorkerNavigator.idl3
-rw-r--r--src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp163
-rw-r--r--src/3rdparty/webkit/WebCore/page/XSSAuditor.h54
-rw-r--r--src/3rdparty/webkit/WebCore/page/ZoomMode.h32
-rw-r--r--src/3rdparty/webkit/WebCore/page/android/EventHandlerAndroid.cpp128
-rw-r--r--src/3rdparty/webkit/WebCore/page/android/InspectorControllerAndroid.cpp106
-rw-r--r--src/3rdparty/webkit/WebCore/page/animation/AnimationBase.cpp73
-rw-r--r--src/3rdparty/webkit/WebCore/page/animation/AnimationBase.h14
-rw-r--r--src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp5
-rw-r--r--src/3rdparty/webkit/WebCore/page/animation/AnimationControllerPrivate.h2
-rw-r--r--src/3rdparty/webkit/WebCore/page/animation/CompositeAnimation.cpp15
-rw-r--r--src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp14
-rw-r--r--src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.h5
-rw-r--r--src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.cpp66
-rw-r--r--src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.h8
-rw-r--r--src/3rdparty/webkit/WebCore/page/qt/DragControllerQt.cpp1
-rw-r--r--src/3rdparty/webkit/WebCore/page/qt/EventHandlerQt.cpp6
-rw-r--r--src/3rdparty/webkit/WebCore/page/win/EventHandlerWin.cpp2
-rw-r--r--src/3rdparty/webkit/WebCore/page/win/FrameCGWin.cpp11
-rw-r--r--src/3rdparty/webkit/WebCore/page/win/FrameCairoWin.cpp1
-rw-r--r--src/3rdparty/webkit/WebCore/page/win/FrameWin.cpp64
-rw-r--r--src/3rdparty/webkit/WebCore/page/win/FrameWin.h7
-rw-r--r--src/3rdparty/webkit/WebCore/page/win/PageWin.cpp62
106 files changed, 4835 insertions, 1704 deletions
diff --git a/src/3rdparty/webkit/WebCore/page/AbstractView.idl b/src/3rdparty/webkit/WebCore/page/AbstractView.idl
index 36865de..290bf48 100644
--- a/src/3rdparty/webkit/WebCore/page/AbstractView.idl
+++ b/src/3rdparty/webkit/WebCore/page/AbstractView.idl
@@ -28,7 +28,8 @@ module views {
// Introduced in DOM Level 2:
interface [
- ObjCCustomImplementation
+ ObjCCustomImplementation,
+ OmitConstructor
] AbstractView {
readonly attribute Document document;
readonly attribute Media media;
diff --git a/src/3rdparty/webkit/WebCore/page/BarInfo.cpp b/src/3rdparty/webkit/WebCore/page/BarInfo.cpp
index 0f6cad5..b6ab686 100644
--- a/src/3rdparty/webkit/WebCore/page/BarInfo.cpp
+++ b/src/3rdparty/webkit/WebCore/page/BarInfo.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,23 +60,25 @@ bool BarInfo::visible() const
{
if (!m_frame)
return false;
+ Page* page = m_frame->page();
+ if (!page)
+ return false;
switch (m_type) {
case Locationbar:
- return m_frame->page()->chrome()->toolbarsVisible();
- case Toolbar:
- return m_frame->page()->chrome()->toolbarsVisible();
case Personalbar:
- return m_frame->page()->chrome()->toolbarsVisible();
+ case Toolbar:
+ return page->chrome()->toolbarsVisible();
case Menubar:
- return m_frame->page()->chrome()->menubarVisible();
+ return page->chrome()->menubarVisible();
case Scrollbars:
- return m_frame->page()->chrome()->scrollbarsVisible();
+ return page->chrome()->scrollbarsVisible();
case Statusbar:
- return m_frame->page()->chrome()->statusbarVisible();
- default:
- return false;
+ return page->chrome()->statusbarVisible();
}
+
+ ASSERT_NOT_REACHED();
+ return false;
}
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/BarInfo.idl b/src/3rdparty/webkit/WebCore/page/BarInfo.idl
index 42041c5..2089895 100644
--- a/src/3rdparty/webkit/WebCore/page/BarInfo.idl
+++ b/src/3rdparty/webkit/WebCore/page/BarInfo.idl
@@ -28,7 +28,7 @@
module window {
- interface BarInfo {
+ interface [OmitConstructor] BarInfo {
readonly attribute boolean visible;
};
diff --git a/src/3rdparty/webkit/WebCore/page/Chrome.cpp b/src/3rdparty/webkit/WebCore/page/Chrome.cpp
index 96f0fb7..4174695 100644
--- a/src/3rdparty/webkit/WebCore/page/Chrome.cpp
+++ b/src/3rdparty/webkit/WebCore/page/Chrome.cpp
@@ -67,9 +67,19 @@ Chrome::~Chrome()
m_client->chromeDestroyed();
}
-void Chrome::repaint(const IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly)
+void Chrome::invalidateWindow(const IntRect& updateRect, bool immediate)
{
- m_client->repaint(windowRect, contentChanged, immediate, repaintContentOnly);
+ m_client->invalidateWindow(updateRect, immediate);
+}
+
+void Chrome::invalidateContentsAndWindow(const IntRect& updateRect, bool immediate)
+{
+ m_client->invalidateContentsAndWindow(updateRect, immediate);
+}
+
+void Chrome::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
+{
+ m_client->invalidateContentsForSlowScroll(updateRect, immediate);
}
void Chrome::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
@@ -147,6 +157,11 @@ void Chrome::takeFocus(FocusDirection direction) const
m_client->takeFocus(direction);
}
+void Chrome::focusedNodeChanged(Node* node) const
+{
+ m_client->focusedNodeChanged(node);
+}
+
Page* Chrome::createWindow(Frame* frame, const FrameLoadRequest& request, const WindowFeatures& features) const
{
Page* newPage = m_client->createWindow(frame, request, features);
@@ -302,6 +317,16 @@ bool Chrome::shouldInterruptJavaScript()
return m_client->shouldInterruptJavaScript();
}
+void Chrome::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title)
+{
+ m_client->registerProtocolHandler(scheme, baseURL, url, title);
+}
+
+void Chrome::registerContentHandler(const String& mimeType, const String& baseURL, const String& url, const String& title)
+{
+ m_client->registerContentHandler(mimeType, baseURL, url, title);
+}
+
IntRect Chrome::windowResizerRect() const
{
return m_client->windowResizerRect();
@@ -312,7 +337,7 @@ void Chrome::mouseDidMoveOverElement(const HitTestResult& result, unsigned modif
if (result.innerNode()) {
Document* document = result.innerNode()->document();
if (document && document->isDNSPrefetchEnabled())
- prefetchDNS(result.absoluteLinkURL().host());
+ ResourceHandle::prepareForURL(result.absoluteLinkURL());
}
m_client->mouseDidMoveOverElement(result, modifierFlags);
@@ -392,19 +417,24 @@ void Chrome::print(Frame* frame)
void Chrome::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation)
{
- // Defer loads in case the client method runs a new event loop that would
- // otherwise cause the load to continue while we're in the middle of executing JavaScript.
- PageGroupLoadDeferrer deferrer(m_page, true);
-
- ASSERT(frame);
m_client->requestGeolocationPermissionForFrame(frame, geolocation);
}
+void Chrome::cancelGeolocationPermissionRequestForFrame(Frame* frame)
+{
+ m_client->cancelGeolocationPermissionRequestForFrame(frame);
+}
+
void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
{
m_client->runOpenPanel(frame, fileChooser);
}
+void Chrome::chooseIconForFiles(const Vector<String>& filenames, PassRefPtr<FileChooser> fileChooser)
+{
+ m_client->chooseIconForFiles(filenames, fileChooser);
+}
+
bool Chrome::setCursor(PlatformCursorHandle cursor)
{
return m_client->setCursor(cursor);
diff --git a/src/3rdparty/webkit/WebCore/page/Chrome.h b/src/3rdparty/webkit/WebCore/page/Chrome.h
index 033311d..72312bc 100644
--- a/src/3rdparty/webkit/WebCore/page/Chrome.h
+++ b/src/3rdparty/webkit/WebCore/page/Chrome.h
@@ -42,6 +42,7 @@ namespace WebCore {
class Geolocation;
class HitTestResult;
class IntRect;
+ class Node;
class Page;
class String;
#if ENABLE(NOTIFICATIONS)
@@ -59,8 +60,11 @@ namespace WebCore {
ChromeClient* client() { return m_client; }
// HostWindow methods.
- virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false);
- virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
+
+ virtual void invalidateWindow(const IntRect&, bool);
+ virtual void invalidateContentsAndWindow(const IntRect&, bool);
+ virtual void invalidateContentsForSlowScroll(const IntRect&, bool);
+ virtual void scroll(const IntSize&, const IntRect&, const IntRect&);
virtual IntPoint screenToWindow(const IntPoint&) const;
virtual IntRect windowToScreen(const IntRect&) const;
virtual PlatformPageClient platformPageClient() const;
@@ -82,6 +86,8 @@ namespace WebCore {
bool canTakeFocus(FocusDirection) const;
void takeFocus(FocusDirection) const;
+ void focusedNodeChanged(Node*) const;
+
Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&) const;
void show() const;
@@ -114,6 +120,9 @@ namespace WebCore {
void setStatusbarText(Frame*, const String&);
bool shouldInterruptJavaScript();
+ void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title);
+ void registerContentHandler(const String& mimeType, const String& baseURL, const String& url, const String& title);
+
IntRect windowResizerRect() const;
void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags);
@@ -123,8 +132,10 @@ namespace WebCore {
void print(Frame*);
void requestGeolocationPermissionForFrame(Frame*, Geolocation*);
+ void cancelGeolocationPermissionRequestForFrame(Frame*);
void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
+ void chooseIconForFiles(const Vector<String>&, PassRefPtr<FileChooser>);
bool setCursor(PlatformCursorHandle);
diff --git a/src/3rdparty/webkit/WebCore/page/ChromeClient.h b/src/3rdparty/webkit/WebCore/page/ChromeClient.h
index 5231603..34e2893 100644
--- a/src/3rdparty/webkit/WebCore/page/ChromeClient.h
+++ b/src/3rdparty/webkit/WebCore/page/ChromeClient.h
@@ -83,6 +83,8 @@ namespace WebCore {
virtual bool canTakeFocus(FocusDirection) = 0;
virtual void takeFocus(FocusDirection) = 0;
+ virtual void focusedNodeChanged(Node*) = 0;
+
// The Frame pointer provides the ChromeClient with context about which
// Frame wants to create the new Page. Also, the newly created window
// should not be shown to the user until the ChromeClient of the newly
@@ -121,11 +123,16 @@ namespace WebCore {
virtual bool shouldInterruptJavaScript() = 0;
virtual bool tabsToLinks() const = 0;
+ virtual void registerProtocolHandler(const String&, const String&, const String&, const String&) { }
+ virtual void registerContentHandler(const String&, const String&, const String&, const String&) { }
+
virtual IntRect windowResizerRect() const = 0;
// Methods used by HostWindow.
- virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false) = 0;
- virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) = 0;
+ virtual void invalidateWindow(const IntRect&, bool) = 0;
+ virtual void invalidateContentsAndWindow(const IntRect&, bool) = 0;
+ virtual void invalidateContentsForSlowScroll(const IntRect&, bool) = 0;
+ virtual void scroll(const IntSize&, const IntRect&, const IntRect&) = 0;
virtual IntPoint screenToWindow(const IntPoint&) const = 0;
virtual IntRect windowToScreen(const IntRect&) const = 0;
virtual PlatformPageClient platformPageClient() const = 0;
@@ -176,10 +183,13 @@ namespace WebCore {
virtual bool paintCustomScrollCorner(GraphicsContext*, const FloatRect&);
// This can be either a synchronous or asynchronous call. The ChromeClient can display UI asking the user for permission
- // to use Geolococation. The ChromeClient must call Geolocation::setShouldClearCache() appropriately.
+ // to use Geolocation.
virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*) = 0;
+ virtual void cancelGeolocationPermissionRequestForFrame(Frame*) = 0;
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0;
+ // Asynchronous request to load an icon for specified filenames.
+ virtual void chooseIconForFiles(const Vector<String>&, PassRefPtr<FileChooser>) = 0;
virtual bool setCursor(PlatformCursorHandle) = 0;
@@ -216,6 +226,17 @@ namespace WebCore {
virtual void willPopUpMenu(NSMenu *) { }
#endif
+#if ENABLE(TOUCH_EVENTS)
+ virtual void needTouchEvents(bool) = 0;
+#endif
+
+#if ENABLE(WIDGETS_10_SUPPORT)
+ virtual bool isDocked() { return false; }
+ virtual bool isFloating() { return false; }
+ virtual bool isApplication() { return false; }
+ virtual bool isFullscreen() { return false; }
+#endif
+
protected:
virtual ~ChromeClient() { }
};
diff --git a/src/3rdparty/webkit/WebCore/page/Console.cpp b/src/3rdparty/webkit/WebCore/page/Console.cpp
index 7d0f697..99b3106 100644
--- a/src/3rdparty/webkit/WebCore/page/Console.cpp
+++ b/src/3rdparty/webkit/WebCore/page/Console.cpp
@@ -30,6 +30,7 @@
#include "Console.h"
#include "CString.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "ConsoleMessage.h"
#include "Frame.h"
@@ -40,11 +41,9 @@
#include "PageGroup.h"
#include "PlatformString.h"
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-#include <profiler/Profiler.h>
-#endif
-
#include "ScriptCallStack.h"
+#include "ScriptProfile.h"
+#include "ScriptProfiler.h"
#include <stdio.h>
#include <wtf/UnusedParam.h>
@@ -191,7 +190,7 @@ void Console::addMessage(MessageType type, MessageLevel level, ScriptCallStack*
for (unsigned i = 0; i < lastCaller.argumentCount(); ++i) {
String argAsString;
- if (lastCaller.argumentAt(i).getString(argAsString))
+ if (lastCaller.argumentAt(i).getString(callStack->state(), argAsString))
printf(" %s", argAsString.utf8().data());
}
printf("\n");
@@ -270,6 +269,23 @@ void Console::count(ScriptCallStack* callStack)
#endif
}
+void Console::markTimeline(ScriptCallStack* callStack)
+{
+#if ENABLE(INSPECTOR)
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ const ScriptCallFrame& lastCaller = callStack->at(0);
+ String message;
+ getFirstArgumentAsString(callStack->state(), lastCaller, message);
+
+ page->inspectorController()->markTimeline(message);
+#else
+ UNUSED_PARAM(callStack);
+#endif
+}
+
#if ENABLE(WML)
String Console::lastWMLErrorMessage() const
{
@@ -298,7 +314,7 @@ String Console::lastWMLErrorMessage() const
#if ENABLE(JAVASCRIPT_DEBUGGER)
-void Console::profile(const JSC::UString& title, ScriptCallStack* callStack)
+void Console::profile(const String& title, ScriptCallStack* callStack)
{
Page* page = this->page();
if (!page)
@@ -311,15 +327,15 @@ void Console::profile(const JSC::UString& title, ScriptCallStack* callStack)
return;
#endif
- JSC::UString resolvedTitle = title;
- if (title.isNull()) // no title so give it the next user initiated profile title.
+ String resolvedTitle = title;
+ if (title.isNull()) // no title so give it the next user initiated profile title.
#if ENABLE(INSPECTOR)
resolvedTitle = controller->getCurrentUserInitiatedProfileName(true);
#else
resolvedTitle = "";
#endif
- JSC::Profiler::profiler()->startProfiling(callStack->state(), resolvedTitle);
+ ScriptProfiler::start(callStack->state(), resolvedTitle);
#if ENABLE(INSPECTOR)
const ScriptCallFrame& lastCaller = callStack->at(0);
@@ -327,22 +343,19 @@ void Console::profile(const JSC::UString& title, ScriptCallStack* callStack)
#endif
}
-void Console::profileEnd(const JSC::UString& title, ScriptCallStack* callStack)
+void Console::profileEnd(const String& title, ScriptCallStack* callStack)
{
Page* page = this->page();
if (!page)
return;
- if (!this->page())
- return;
-
#if ENABLE(INSPECTOR)
InspectorController* controller = page->inspectorController();
if (!controller->profilerEnabled())
return;
#endif
- RefPtr<JSC::Profile> profile = JSC::Profiler::profiler()->stopProfiling(callStack->state(), title);
+ RefPtr<ScriptProfile> profile = ScriptProfiler::stop(callStack->state(), title);
if (!profile)
return;
diff --git a/src/3rdparty/webkit/WebCore/page/Console.h b/src/3rdparty/webkit/WebCore/page/Console.h
index 1b93a4a..9a6d88c 100644
--- a/src/3rdparty/webkit/WebCore/page/Console.h
+++ b/src/3rdparty/webkit/WebCore/page/Console.h
@@ -31,100 +31,99 @@
#include "PlatformString.h"
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-#include <profiler/Profile.h>
-#endif
+#include "ScriptProfile.h"
-#include <wtf/RefCounted.h>
#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
namespace WebCore {
#if ENABLE(JAVASCRIPT_DEBUGGER)
- typedef Vector<RefPtr<JSC::Profile> > ProfilesArray;
+typedef Vector<RefPtr<ScriptProfile> > ProfilesArray;
#endif
- class Frame;
- class Page;
- class String;
- class ScriptCallStack;
-
- // Keep in sync with inspector/front-end/Console.js
- enum MessageSource {
- HTMLMessageSource,
- WMLMessageSource,
- XMLMessageSource,
- JSMessageSource,
- CSSMessageSource,
- OtherMessageSource
- };
-
- enum MessageType {
- LogMessageType,
- ObjectMessageType,
- TraceMessageType,
- StartGroupMessageType,
- EndGroupMessageType,
- AssertMessageType
- };
-
- enum MessageLevel {
- TipMessageLevel,
- LogMessageLevel,
- WarningMessageLevel,
- ErrorMessageLevel,
- DebugMessageLevel
- };
-
- class Console : public RefCounted<Console> {
- public:
- static PassRefPtr<Console> create(Frame* frame) { return adoptRef(new Console(frame)); }
-
- Frame* frame() const;
- void disconnectFrame();
-
- void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
-
- void debug(ScriptCallStack*);
- void error(ScriptCallStack*);
- void info(ScriptCallStack*);
- void log(ScriptCallStack*);
- void warn(ScriptCallStack*);
- void dir(ScriptCallStack*);
- void dirxml(ScriptCallStack*);
- void trace(ScriptCallStack*);
- void assertCondition(bool condition, ScriptCallStack*);
- void count(ScriptCallStack*);
+class Frame;
+class Page;
+class String;
+class ScriptCallStack;
+
+// Keep in sync with inspector/front-end/Console.js
+enum MessageSource {
+ HTMLMessageSource,
+ WMLMessageSource,
+ XMLMessageSource,
+ JSMessageSource,
+ CSSMessageSource,
+ OtherMessageSource
+};
+
+enum MessageType {
+ LogMessageType,
+ ObjectMessageType,
+ TraceMessageType,
+ StartGroupMessageType,
+ EndGroupMessageType,
+ AssertMessageType
+};
+
+enum MessageLevel {
+ TipMessageLevel,
+ LogMessageLevel,
+ WarningMessageLevel,
+ ErrorMessageLevel,
+ DebugMessageLevel
+};
+
+class Console : public RefCounted<Console> {
+public:
+ static PassRefPtr<Console> create(Frame* frame) { return adoptRef(new Console(frame)); }
+
+ Frame* frame() const;
+ void disconnectFrame();
+
+ void addMessage(MessageSource, MessageType, MessageLevel, const String& message, unsigned lineNumber, const String& sourceURL);
+
+ void debug(ScriptCallStack*);
+ void error(ScriptCallStack*);
+ void info(ScriptCallStack*);
+ void log(ScriptCallStack*);
+ void warn(ScriptCallStack*);
+ void dir(ScriptCallStack*);
+ void dirxml(ScriptCallStack*);
+ void trace(ScriptCallStack*);
+ void assertCondition(bool condition, ScriptCallStack*);
+ void count(ScriptCallStack*);
+ void markTimeline(ScriptCallStack*);
#if ENABLE(WML)
- String lastWMLErrorMessage() const;
+ String lastWMLErrorMessage() const;
#endif
#if ENABLE(JAVASCRIPT_DEBUGGER)
- void profile(const JSC::UString&, ScriptCallStack*);
- void profileEnd(const JSC::UString&, ScriptCallStack*);
+ void profile(const String&, ScriptCallStack*);
+ void profileEnd(const String&, ScriptCallStack*);
#endif
- void time(const String&);
- void timeEnd(const String&, ScriptCallStack*);
- void group(ScriptCallStack*);
- void groupEnd();
+ void time(const String&);
+ void timeEnd(const String&, ScriptCallStack*);
+ void group(ScriptCallStack*);
+ void groupEnd();
- static bool shouldPrintExceptions();
- static void setShouldPrintExceptions(bool);
+ static bool shouldPrintExceptions();
+ static void setShouldPrintExceptions(bool);
#if ENABLE(JAVASCRIPT_DEBUGGER)
- const ProfilesArray& profiles() const { return m_profiles; }
+ const ProfilesArray& profiles() const { return m_profiles; }
#endif
- private:
- inline Page* page() const;
- void addMessage(MessageType, MessageLevel, ScriptCallStack*, bool acceptNoArguments = false);
+private:
+ inline Page* page() const;
+ void addMessage(MessageType, MessageLevel, ScriptCallStack*, bool acceptNoArguments = false);
- Console(Frame*);
+ Console(Frame*);
- Frame* m_frame;
+ Frame* m_frame;
#if ENABLE(JAVASCRIPT_DEBUGGER)
- ProfilesArray m_profiles;
+ ProfilesArray m_profiles;
#endif
- };
+};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/Console.idl b/src/3rdparty/webkit/WebCore/page/Console.idl
index 0e9f3dc..c08fcc0 100644
--- a/src/3rdparty/webkit/WebCore/page/Console.idl
+++ b/src/3rdparty/webkit/WebCore/page/Console.idl
@@ -28,9 +28,10 @@
module window {
- interface Console {
+ interface [OmitConstructor] Console {
-#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER
+ // Not enabled in V8 because it requires request-reply style.
+#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER && !(defined(V8_BINDING) && V8_BINDING)
readonly attribute [CustomGetter] Array profiles;
#endif
@@ -44,6 +45,7 @@ module window {
[CustomArgumentHandling] void trace();
[CustomArgumentHandling, ImplementationFunction=assertCondition] void assert(in boolean condition);
[CustomArgumentHandling] void count();
+ [CustomArgumentHandling] void markTimeline();
#if defined(ENABLE_WML) && ENABLE_WML
[DontEnum] DOMString lastWMLErrorMessage();
diff --git a/src/3rdparty/webkit/WebCore/page/ContextMenuController.cpp b/src/3rdparty/webkit/WebCore/page/ContextMenuController.cpp
index 7d773ca..d384b02 100644
--- a/src/3rdparty/webkit/WebCore/page/ContextMenuController.cpp
+++ b/src/3rdparty/webkit/WebCore/page/ContextMenuController.cpp
@@ -31,6 +31,7 @@
#include "Chrome.h"
#include "ContextMenu.h"
#include "ContextMenuClient.h"
+#include "ContextMenuProvider.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DocumentLoader.h"
@@ -79,13 +80,38 @@ ContextMenuController::~ContextMenuController()
void ContextMenuController::clearContextMenu()
{
m_contextMenu.set(0);
+ if (m_menuProvider)
+ m_menuProvider->contextMenuCleared();
+ m_menuProvider = 0;
}
void ContextMenuController::handleContextMenuEvent(Event* event)
{
- ASSERT(event->type() == eventNames().contextmenuEvent);
- if (!event->isMouseEvent())
+ m_contextMenu.set(createContextMenu(event));
+ if (!m_contextMenu)
return;
+ m_contextMenu->populate();
+ showContextMenu(event);
+}
+
+void ContextMenuController::showContextMenu(Event* event, PassRefPtr<ContextMenuProvider> menuProvider)
+{
+ m_menuProvider = menuProvider;
+
+ m_contextMenu.set(createContextMenu(event));
+ if (!m_contextMenu) {
+ clearContextMenu();
+ return;
+ }
+
+ m_menuProvider->populateContextMenu(m_contextMenu.get());
+ showContextMenu(event);
+}
+
+ContextMenu* ContextMenuController::createContextMenu(Event* event)
+{
+ if (!event->isMouseEvent())
+ return 0;
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
HitTestResult result(mouseEvent->absoluteLocation());
@@ -93,18 +119,18 @@ void ContextMenuController::handleContextMenuEvent(Event* event)
result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false);
if (!result.innerNonSharedNode())
- return;
+ return 0;
+ return new ContextMenu(result);
+}
- m_contextMenu.set(new ContextMenu(result));
- m_contextMenu->populate();
+void ContextMenuController::showContextMenu(Event* event)
+{
#if ENABLE(INSPECTOR)
if (m_page->inspectorController()->enabled())
m_contextMenu->addInspectElementItem();
#endif
-
PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get());
m_contextMenu->setPlatformDescription(customMenu);
-
event->setDefaultHandled();
}
@@ -126,6 +152,12 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
return;
}
+ if (item->action() >= ContextMenuItemBaseCustomTag) {
+ ASSERT(m_menuProvider);
+ m_menuProvider->contextMenuItemSelected(item);
+ return;
+ }
+
HitTestResult result = m_contextMenu->hitTestResult();
Frame* frame = result.innerNonSharedNode()->document()->frame();
if (!frame)
diff --git a/src/3rdparty/webkit/WebCore/page/ContextMenuController.h b/src/3rdparty/webkit/WebCore/page/ContextMenuController.h
index 38095f6..833b909 100644
--- a/src/3rdparty/webkit/WebCore/page/ContextMenuController.h
+++ b/src/3rdparty/webkit/WebCore/page/ContextMenuController.h
@@ -28,12 +28,15 @@
#include <wtf/Noncopyable.h>
#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
namespace WebCore {
class ContextMenu;
class ContextMenuClient;
class ContextMenuItem;
+ class ContextMenuProvider;
class Event;
class Page;
@@ -48,12 +51,18 @@ namespace WebCore {
void clearContextMenu();
void handleContextMenuEvent(Event*);
+ void showContextMenu(Event*, PassRefPtr<ContextMenuProvider>);
+
void contextMenuItemSelected(ContextMenuItem*);
private:
+ ContextMenu* createContextMenu(Event*);
+ void showContextMenu(Event*);
+
Page* m_page;
ContextMenuClient* m_client;
OwnPtr<ContextMenu> m_contextMenu;
+ RefPtr<ContextMenuProvider> m_menuProvider;
};
}
diff --git a/src/3rdparty/webkit/WebCore/page/ContextMenuProvider.h b/src/3rdparty/webkit/WebCore/page/ContextMenuProvider.h
new file mode 100644
index 0000000..57598d1
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/ContextMenuProvider.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 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 ContextMenuProvider_h
+#define ContextMenuProvider_h
+
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class ContextMenu;
+class ContextMenuItem;
+
+class ContextMenuProvider : public RefCounted<ContextMenuProvider> {
+public:
+ virtual ~ContextMenuProvider() { };
+
+ virtual void populateContextMenu(ContextMenu*) = 0;
+ virtual void contextMenuItemSelected(ContextMenuItem*) = 0;
+ virtual void contextMenuCleared() = 0;
+};
+
+}
+
+#endif // ContextMenuProvider_h
diff --git a/src/3rdparty/webkit/WebCore/page/Coordinates.idl b/src/3rdparty/webkit/WebCore/page/Coordinates.idl
index f847325..5a5a141 100644
--- a/src/3rdparty/webkit/WebCore/page/Coordinates.idl
+++ b/src/3rdparty/webkit/WebCore/page/Coordinates.idl
@@ -25,7 +25,7 @@
module core {
- interface Coordinates {
+ interface [OmitConstructor] Coordinates {
readonly attribute double latitude;
readonly attribute double longitude;
readonly attribute [Custom] double altitude;
diff --git a/src/3rdparty/webkit/WebCore/page/DOMSelection.cpp b/src/3rdparty/webkit/WebCore/page/DOMSelection.cpp
index 0d21c56..12ae59d 100644
--- a/src/3rdparty/webkit/WebCore/page/DOMSelection.cpp
+++ b/src/3rdparty/webkit/WebCore/page/DOMSelection.cpp
@@ -326,7 +326,6 @@ void DOMSelection::extend(Node* node, int offset, ExceptionCode& ec)
}
SelectionController* selection = m_frame->selection();
- selection->expandUsingGranularity(CharacterGranularity);
selection->setExtent(VisiblePosition(node, offset, DOWNSTREAM));
}
diff --git a/src/3rdparty/webkit/WebCore/page/DOMSelection.idl b/src/3rdparty/webkit/WebCore/page/DOMSelection.idl
index be6c2b4..4d0c942 100644
--- a/src/3rdparty/webkit/WebCore/page/DOMSelection.idl
+++ b/src/3rdparty/webkit/WebCore/page/DOMSelection.idl
@@ -31,7 +31,7 @@ module window {
// This is based off of Mozilla's Selection interface
// https://developer.mozilla.org/En/DOM/Selection
- interface DOMSelection {
+ interface [OmitConstructor] DOMSelection {
readonly attribute Node anchorNode;
readonly attribute long anchorOffset;
readonly attribute Node focusNode;
diff --git a/src/3rdparty/webkit/WebCore/page/DOMTimer.cpp b/src/3rdparty/webkit/WebCore/page/DOMTimer.cpp
index 83bcb02..72dc9ac 100644
--- a/src/3rdparty/webkit/WebCore/page/DOMTimer.cpp
+++ b/src/3rdparty/webkit/WebCore/page/DOMTimer.cpp
@@ -43,7 +43,7 @@ double DOMTimer::s_minTimerInterval = 0.010; // 10 milliseconds
static int timerNestingLevel = 0;
-DOMTimer::DOMTimer(ScriptExecutionContext* context, ScheduledAction* action, int timeout, bool singleShot)
+DOMTimer::DOMTimer(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int timeout, bool singleShot)
: ActiveDOMObject(context, this)
, m_action(action)
, m_nextFireInterval(0)
@@ -82,7 +82,7 @@ DOMTimer::~DOMTimer()
scriptExecutionContext()->removeTimeout(m_timeoutId);
}
-int DOMTimer::install(ScriptExecutionContext* context, ScheduledAction* action, int timeout, bool singleShot)
+int DOMTimer::install(ScriptExecutionContext* context, PassOwnPtr<ScheduledAction> action, int timeout, bool singleShot)
{
// DOMTimer constructor links the new timer into a list of ActiveDOMObjects held by the 'context'.
// The timer is deleted when context is deleted (DOMTimer::contextDestroyed) or explicitly via DOMTimer::removeById(),
@@ -119,8 +119,7 @@ void DOMTimer::fired()
timerNestingLevel = m_nestingLevel;
#if ENABLE(INSPECTOR)
- InspectorTimelineAgent* timelineAgent = InspectorTimelineAgent::retrieve(context);
- if (timelineAgent)
+ if (InspectorTimelineAgent* timelineAgent = InspectorTimelineAgent::retrieve(context))
timelineAgent->willFireTimer(m_timeoutId);
#endif
@@ -135,7 +134,7 @@ void DOMTimer::fired()
// No access to member variables after this point, it can delete the timer.
m_action->execute(context);
#if ENABLE(INSPECTOR)
- if (timelineAgent)
+ if (InspectorTimelineAgent* timelineAgent = InspectorTimelineAgent::retrieve(context))
timelineAgent->didFireTimer();
#endif
return;
@@ -149,7 +148,7 @@ void DOMTimer::fired()
action->execute(context);
#if ENABLE(INSPECTOR)
- if (timelineAgent)
+ if (InspectorTimelineAgent* timelineAgent = InspectorTimelineAgent::retrieve(context))
timelineAgent->didFireTimer();
#endif
delete action;
diff --git a/src/3rdparty/webkit/WebCore/page/DOMTimer.h b/src/3rdparty/webkit/WebCore/page/DOMTimer.h
index 460430f..da38178 100644
--- a/src/3rdparty/webkit/WebCore/page/DOMTimer.h
+++ b/src/3rdparty/webkit/WebCore/page/DOMTimer.h
@@ -28,20 +28,21 @@
#define DOMTimer_h
#include "ActiveDOMObject.h"
+#include "ScheduledAction.h"
#include "Timer.h"
#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
class InspectorTimelineAgent;
- class ScheduledAction;
class DOMTimer : public TimerBase, public ActiveDOMObject {
public:
virtual ~DOMTimer();
// Creates a new timer owned by specified ScriptExecutionContext, starts it
// and returns its Id.
- static int install(ScriptExecutionContext*, ScheduledAction*, int timeout, bool singleShot);
+ static int install(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int timeout, bool singleShot);
static void removeById(ScriptExecutionContext*, int timeoutId);
// ActiveDOMObject
@@ -59,7 +60,7 @@ namespace WebCore {
static void setMinTimerInterval(double value) { s_minTimerInterval = value; }
private:
- DOMTimer(ScriptExecutionContext*, ScheduledAction*, int timeout, bool singleShot);
+ DOMTimer(ScriptExecutionContext*, PassOwnPtr<ScheduledAction>, int timeout, bool singleShot);
virtual void fired();
int m_timeoutId;
diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp
index c30b6b9..dd90200 100644
--- a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp
+++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "DOMWindow.h"
+#include "Base64.h"
#include "BarInfo.h"
#include "BeforeUnloadEvent.h"
#include "CSSComputedStyleDeclaration.h"
@@ -35,6 +36,7 @@
#include "Chrome.h"
#include "Console.h"
#include "Database.h"
+#include "DatabaseCallback.h"
#include "DOMApplicationCache.h"
#include "DOMSelection.h"
#include "DOMTimer.h"
@@ -53,6 +55,7 @@
#include "HTMLFrameOwnerElement.h"
#include "History.h"
#include "InspectorController.h"
+#include "InspectorTimelineAgent.h"
#include "Location.h"
#include "Media.h"
#include "MessageEvent.h"
@@ -262,7 +265,7 @@ void DOMWindow::dispatchAllPendingUnloadEvents()
if (!set.contains(window))
continue;
- window->dispatchEvent(PageTransitionEvent::create(EventNames().pagehideEvent, false), window->document());
+ window->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, false), window->document());
window->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), window->document());
}
@@ -341,8 +344,6 @@ void DOMWindow::parseModalDialogFeatures(const String& featuresArg, HashMap<Stri
bool DOMWindow::allowPopUp(Frame* activeFrame)
{
ASSERT(activeFrame);
- if (activeFrame->script()->processingUserGesture())
- return true;
Settings* settings = activeFrame->settings();
return settings && settings->javaScriptCanOpenWindowsAutomatically();
}
@@ -441,6 +442,10 @@ void DOMWindow::clear()
if (m_location)
m_location->disconnectFrame();
m_location = 0;
+
+ if (m_media)
+ m_media->disconnectFrame();
+ m_media = 0;
#if ENABLE(DOM_STORAGE)
if (m_sessionStorage)
@@ -459,6 +464,8 @@ void DOMWindow::clear()
#endif
#if ENABLE(NOTIFICATIONS)
+ if (m_notifications)
+ m_notifications->disconnectFrame();
m_notifications = 0;
#endif
}
@@ -573,9 +580,6 @@ Storage* DOMWindow::sessionStorage() const
if (!page)
return 0;
- if (!page->settings()->sessionStorageEnabled())
- return 0;
-
RefPtr<StorageArea> storageArea = page->sessionStorage()->storageArea(document->securityOrigin());
#if ENABLE(INSPECTOR)
page->inspectorController()->didUseDOMStorage(storageArea.get(), false, m_frame);
@@ -585,7 +589,7 @@ Storage* DOMWindow::sessionStorage() const
return m_sessionStorage.get();
}
-Storage* DOMWindow::localStorage() const
+Storage* DOMWindow::localStorage(ExceptionCode& ec) const
{
if (m_localStorage)
return m_localStorage.get();
@@ -593,6 +597,11 @@ Storage* DOMWindow::localStorage() const
Document* document = this->document();
if (!document)
return 0;
+
+ if (!document->securityOrigin()->canAccessLocalStorage()) {
+ ec = SECURITY_ERR;
+ return 0;
+ }
Page* page = document->page();
if (!page)
@@ -625,9 +634,6 @@ NotificationCenter* DOMWindow::webkitNotifications() const
if (!page)
return 0;
- if (!page->settings()->experimentalNotificationsEnabled())
- return 0;
-
NotificationPresenter* provider = page->chrome()->notificationPresenter();
if (provider)
m_notifications = NotificationCenter::create(document, provider);
@@ -636,6 +642,13 @@ NotificationCenter* DOMWindow::webkitNotifications() const
}
#endif
+#if ENABLE(INDEXED_DATABASE)
+IndexedDatabaseRequest* DOMWindow::indexedDB() const
+{
+ return 0;
+}
+#endif
+
void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort* port, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec)
{
MessagePortArray ports;
@@ -814,6 +827,57 @@ String DOMWindow::prompt(const String& message, const String& defaultValue)
return String();
}
+static bool isSafeToConvertCharList(const String& string)
+{
+ for (unsigned i = 0; i < string.length(); i++) {
+ if (string[i] > 0xFF)
+ return false;
+ }
+
+ return true;
+}
+
+String DOMWindow::btoa(const String& stringToEncode, ExceptionCode& ec)
+{
+ if (stringToEncode.isNull())
+ return String();
+
+ if (!isSafeToConvertCharList(stringToEncode)) {
+ ec = INVALID_CHARACTER_ERR;
+ return String();
+ }
+
+ Vector<char> in;
+ in.append(stringToEncode.characters(), stringToEncode.length());
+ Vector<char> out;
+
+ base64Encode(in, out);
+
+ return String(out.data(), out.size());
+}
+
+String DOMWindow::atob(const String& encodedString, ExceptionCode& ec)
+{
+ if (encodedString.isNull())
+ return String();
+
+ if (!isSafeToConvertCharList(encodedString)) {
+ ec = INVALID_CHARACTER_ERR;
+ return String();
+ }
+
+ Vector<char> in;
+ in.append(encodedString.characters(), encodedString.length());
+ Vector<char> out;
+
+ if (!base64Decode(in, out)) {
+ ec = INVALID_CHARACTER_ERR;
+ return String();
+ }
+
+ return String(out.data(), out.size());
+}
+
bool DOMWindow::find(const String& string, bool caseSensitive, bool backwards, bool wrap, bool /*wholeWord*/, bool /*searchInFrames*/, bool /*showDialog*/) const
{
if (!m_frame)
@@ -1050,7 +1114,9 @@ Document* DOMWindow::document() const
PassRefPtr<Media> DOMWindow::media() const
{
- return Media::create(const_cast<DOMWindow*>(this));
+ if (!m_media)
+ m_media = Media::create(m_frame);
+ return m_media.get();
}
PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* elt, const String&) const
@@ -1078,7 +1144,9 @@ PassRefPtr<WebKitPoint> DOMWindow::webkitConvertPointFromNodeToPage(Node* node,
{
if (!node || !p)
return 0;
-
+
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
+
FloatPoint pagePoint(p->x(), p->y());
pagePoint = node->convertToPage(pagePoint);
return WebKitPoint::create(pagePoint.x(), pagePoint.y());
@@ -1088,7 +1156,9 @@ PassRefPtr<WebKitPoint> DOMWindow::webkitConvertPointFromPageToNode(Node* node,
{
if (!node || !p)
return 0;
-
+
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
+
FloatPoint nodePoint(p->x(), p->y());
nodePoint = node->convertFromPage(nodePoint);
return WebKitPoint::create(nodePoint.x(), nodePoint.y());
@@ -1107,18 +1177,21 @@ double DOMWindow::devicePixelRatio() const
}
#if ENABLE(DATABASE)
-PassRefPtr<Database> DOMWindow::openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, ExceptionCode& ec)
+PassRefPtr<Database> DOMWindow::openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode& ec)
{
if (!m_frame)
return 0;
- Document* doc = m_frame->document();
+ if (!Database::isAvailable())
+ return 0;
- Settings* settings = m_frame->settings();
- if (!settings || !settings->databasesEnabled())
+ Document* document = m_frame->document();
+ if (!document->securityOrigin()->canAccessDatabase()) {
+ ec = SECURITY_ERR;
return 0;
+ }
- return Database::openDatabase(doc, name, version, displayName, estimatedSize, ec);
+ return Database::openDatabase(document, name, version, displayName, estimatedSize, creationCallback, ec);
}
#endif
@@ -1232,24 +1305,40 @@ void DOMWindow::resizeTo(float width, float height) const
page->chrome()->setWindowRect(fr);
}
-int DOMWindow::setTimeout(ScheduledAction* action, int timeout)
+int DOMWindow::setTimeout(PassOwnPtr<ScheduledAction> action, int timeout, ExceptionCode& ec)
{
- return DOMTimer::install(scriptExecutionContext(), action, timeout, true);
+ ScriptExecutionContext* context = scriptExecutionContext();
+ if (!context) {
+ ec = INVALID_ACCESS_ERR;
+ return -1;
+ }
+ return DOMTimer::install(context, action, timeout, true);
}
void DOMWindow::clearTimeout(int timeoutId)
{
- DOMTimer::removeById(scriptExecutionContext(), timeoutId);
+ ScriptExecutionContext* context = scriptExecutionContext();
+ if (!context)
+ return;
+ DOMTimer::removeById(context, timeoutId);
}
-int DOMWindow::setInterval(ScheduledAction* action, int timeout)
+int DOMWindow::setInterval(PassOwnPtr<ScheduledAction> action, int timeout, ExceptionCode& ec)
{
- return DOMTimer::install(scriptExecutionContext(), action, timeout, false);
+ ScriptExecutionContext* context = scriptExecutionContext();
+ if (!context) {
+ ec = INVALID_ACCESS_ERR;
+ return -1;
+ }
+ return DOMTimer::install(context, action, timeout, false);
}
void DOMWindow::clearInterval(int timeoutId)
{
- DOMTimer::removeById(scriptExecutionContext(), timeoutId);
+ ScriptExecutionContext* context = scriptExecutionContext();
+ if (!context)
+ return;
+ DOMTimer::removeById(context, timeoutId);
}
bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
@@ -1304,6 +1393,15 @@ void DOMWindow::dispatchLoadEvent()
#endif
}
+#if ENABLE(INSPECTOR)
+InspectorTimelineAgent* DOMWindow::inspectorTimelineAgent()
+{
+ if (frame() && frame()->page())
+ return frame()->page()->inspectorTimelineAgent();
+ return 0;
+}
+#endif
+
bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget)
{
RefPtr<EventTarget> protect = this;
@@ -1313,7 +1411,24 @@ bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget
event->setCurrentTarget(this);
event->setEventPhase(Event::AT_TARGET);
- return fireEventListeners(event.get());
+#if ENABLE(INSPECTOR)
+ InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
+ bool timelineAgentIsActive = timelineAgent && hasEventListeners(event->type());
+ if (timelineAgentIsActive)
+ timelineAgent->willDispatchEvent(*event);
+#endif
+
+ bool result = fireEventListeners(event.get());
+
+#if ENABLE(INSPECTOR)
+ if (timelineAgentIsActive) {
+ timelineAgent = inspectorTimelineAgent();
+ if (timelineAgent)
+ timelineAgent->didDispatchEvent();
+ }
+#endif
+
+ return result;
}
void DOMWindow::removeAllEventListeners()
diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.h b/src/3rdparty/webkit/WebCore/page/DOMWindow.h
index 25eadc8..a70713b 100644
--- a/src/3rdparty/webkit/WebCore/page/DOMWindow.h
+++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.h
@@ -45,6 +45,7 @@ namespace WebCore {
class Console;
class DOMSelection;
class Database;
+ class DatabaseCallback;
class Document;
class Element;
class Event;
@@ -52,6 +53,8 @@ namespace WebCore {
class FloatRect;
class Frame;
class History;
+ class IndexedDatabaseRequest;
+ class InspectorTimelineAgent;
class Location;
class Media;
class Navigator;
@@ -137,6 +140,8 @@ namespace WebCore {
void alert(const String& message);
bool confirm(const String& message);
String prompt(const String& message, const String& defaultValue);
+ String btoa(const String& stringToEncode, ExceptionCode&);
+ String atob(const String& encodedString, ExceptionCode&);
bool find(const String&, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const;
@@ -196,13 +201,13 @@ namespace WebCore {
#if ENABLE(DATABASE)
// HTML 5 client-side database
- PassRefPtr<Database> openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, ExceptionCode&);
+ PassRefPtr<Database> openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode&);
#endif
#if ENABLE(DOM_STORAGE)
// HTML 5 key/value storage
Storage* sessionStorage() const;
- Storage* localStorage() const;
+ Storage* localStorage(ExceptionCode&) const;
#endif
Console* console() const;
@@ -215,6 +220,10 @@ namespace WebCore {
NotificationCenter* webkitNotifications() const;
#endif
+#if ENABLE(INDEXED_DATABASE)
+ IndexedDatabaseRequest* indexedDB() const;
+#endif
+
void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
// FIXME: remove this when we update the ObjC bindings (bug #28774).
void postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
@@ -231,9 +240,9 @@ namespace WebCore {
void resizeTo(float width, float height) const;
// Timers
- int setTimeout(ScheduledAction*, int timeout);
+ int setTimeout(PassOwnPtr<ScheduledAction>, int timeout, ExceptionCode&);
void clearTimeout(int timeoutId);
- int setInterval(ScheduledAction*, int timeout);
+ int setInterval(PassOwnPtr<ScheduledAction>, int timeout, ExceptionCode&);
void clearInterval(int timeoutId);
// Events
@@ -247,9 +256,13 @@ namespace WebCore {
void dispatchLoadEvent();
DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(beforeunload);
DEFINE_ATTRIBUTE_EVENT_LISTENER(blur);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough);
DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
@@ -258,13 +271,22 @@ namespace WebCore {
DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
DEFINE_ATTRIBUTE_EVENT_LISTENER(focus);
DEFINE_ATTRIBUTE_EVENT_LISTENER(hashchange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
@@ -275,39 +297,30 @@ namespace WebCore {
DEFINE_ATTRIBUTE_EVENT_LISTENER(online);
DEFINE_ATTRIBUTE_EVENT_LISTENER(pagehide);
DEFINE_ATTRIBUTE_EVENT_LISTENER(pageshow);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pause);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(play);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(playing);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(popstate);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
DEFINE_ATTRIBUTE_EVENT_LISTENER(resize);
DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking);
DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled);
DEFINE_ATTRIBUTE_EVENT_LISTENER(storage);
DEFINE_ATTRIBUTE_EVENT_LISTENER(submit);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(unload);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(beforeunload);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(ended);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(pause);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(play);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(playing);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend);
DEFINE_ATTRIBUTE_EVENT_LISTENER(timeupdate);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(unload);
DEFINE_ATTRIBUTE_EVENT_LISTENER(volumechange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(waiting);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(input);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitbeginfullscreen);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitendfullscreen);
+
#if ENABLE(ORIENTATION_EVENTS)
DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
#endif
@@ -317,6 +330,12 @@ namespace WebCore {
DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd);
DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd);
+#if ENABLE(TOUCH_EVENTS)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
+#endif
void captureEvents();
void releaseEvents();
@@ -334,6 +353,7 @@ namespace WebCore {
Console* optionalConsole() const { return m_console.get(); }
Navigator* optionalNavigator() const { return m_navigator.get(); }
Location* optionalLocation() const { return m_location.get(); }
+ Media* optionalMedia() const { return m_media.get(); }
#if ENABLE(DOM_STORAGE)
Storage* optionalSessionStorage() const { return m_sessionStorage.get(); }
Storage* optionalLocalStorage() const { return m_localStorage.get(); }
@@ -352,6 +372,7 @@ namespace WebCore {
virtual void derefEventTarget() { deref(); }
virtual EventTargetData* eventTargetData();
virtual EventTargetData* ensureEventTargetData();
+ InspectorTimelineAgent* inspectorTimelineAgent();
RefPtr<SecurityOrigin> m_securityOrigin;
KURL m_url;
@@ -369,6 +390,7 @@ namespace WebCore {
mutable RefPtr<Console> m_console;
mutable RefPtr<Navigator> m_navigator;
mutable RefPtr<Location> m_location;
+ mutable RefPtr<Media> m_media;
#if ENABLE(DOM_STORAGE)
mutable RefPtr<Storage> m_sessionStorage;
mutable RefPtr<Storage> m_localStorage;
diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl
index 5addb83..d457bdc 100644
--- a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl
+++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl
@@ -31,15 +31,15 @@ module window {
CustomDefineSetter,
CustomDeleteProperty,
CustomGetOwnPropertySlot,
- CustomGetPropertyAttributes,
CustomGetPropertyNames,
CustomLookupGetter,
CustomLookupSetter,
CustomMarkFunction,
CustomNativeConverter,
CustomPutFunction,
- ExtendsDOMGlobalObject,
EventTarget,
+ OmitConstructor,
+ ExtendsDOMGlobalObject,
GenerateNativeConverter,
LegacyParent=JSDOMWindowBase
] DOMWindow {
@@ -157,19 +157,23 @@ module window {
WebKitPoint webkitConvertPointFromNodeToPage(in Node node, in WebKitPoint p);
#if defined(ENABLE_OFFLINE_WEB_APPLICATIONS) && ENABLE_OFFLINE_WEB_APPLICATIONS
- readonly attribute DOMApplicationCache applicationCache;
+ readonly attribute [EnabledAtRuntime] DOMApplicationCache applicationCache;
#endif
#if defined(ENABLE_DATABASE) && ENABLE_DATABASE
- [EnabledAtRuntime] Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize)
+ [EnabledAtRuntime, Custom] Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in DatabaseCallback creationCallback)
raises(DOMException);
#endif
#if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE
readonly attribute [EnabledAtRuntime] Storage sessionStorage;
- readonly attribute [EnabledAtRuntime] Storage localStorage;
+ readonly attribute [EnabledAtRuntime] Storage localStorage
+ getter raises(DOMException);
#endif
#if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS
readonly attribute [EnabledAtRuntime] NotificationCenter webkitNotifications;
#endif
+#if defined(ENABLE_INDEXED_DATABASE) && ENABLE_INDEXED_DATABASE
+ readonly attribute [EnabledAtRuntime] IndexedDatabaseRequest indexedDB;
+#endif
#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
// This is the interface orientation in degrees. Some examples are:
@@ -201,9 +205,9 @@ module window {
void clearInterval(in long handle);
// Base64
- [Custom] DOMString atob(in DOMString string)
+ DOMString atob(in [ConvertNullToNullString] DOMString string)
raises(DOMException);
- [Custom] DOMString btoa(in DOMString string)
+ DOMString btoa(in [ConvertNullToNullString] DOMString string)
raises(DOMException);
// Events
@@ -252,6 +256,7 @@ module window {
attribute EventListener onpause;
attribute EventListener onplay;
attribute EventListener onplaying;
+ attribute EventListener onpopstate;
attribute EventListener onprogress;
attribute EventListener onratechange;
attribute EventListener onresize;
@@ -273,7 +278,6 @@ module window {
// attribute EventListener onbeforeprint;
// attribute EventListener onformchange;
// attribute EventListener onforminput;
- // attribute EventListener onpopstate;
// attribute EventListener onreadystatechange;
// attribute EventListener onredo;
// attribute EventListener onshow;
@@ -289,6 +293,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,
@@ -411,6 +421,9 @@ module window {
attribute HTMLParagraphElementConstructor HTMLParagraphElement;
attribute HTMLParamElementConstructor HTMLParamElement;
attribute HTMLPreElementConstructor HTMLPreElement;
+#if defined(ENABLE_PROGRESS_TAG) && ENABLE_PROGRESS_TAG
+ attribute HTMLProgressElementConstructor HTMLProgressElement;
+#endif
attribute HTMLQuoteElementConstructor HTMLQuoteElement;
attribute HTMLScriptElementConstructor HTMLScriptElement;
attribute HTMLSelectElementConstructor HTMLSelectElement;
@@ -432,17 +445,18 @@ module window {
attribute [CustomGetter] HTMLOptionElementConstructor Option; // Usable with new operator
attribute CanvasRenderingContext2DConstructor CanvasRenderingContext2D;
- attribute [Conditional=3D_CANVAS] CanvasRenderingContext3DConstructor CanvasRenderingContext3D;
+ attribute ImageDataConstructor ImageData;
+ attribute [Conditional=3D_CANVAS,EnabledAtRuntime] WebGLRenderingContextConstructor WebGLRenderingContext;
attribute TextMetricsConstructor TextMetrics;
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasArrayBufferConstructor CanvasArrayBuffer; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasByteArrayConstructor CanvasByteArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasUnsignedByteArrayConstructor CanvasUnsignedByteArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasShortArrayConstructor CanvasShortArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasUnsignedShortArrayConstructor CanvasUnsignedShortArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasIntArrayConstructor CanvasIntArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasUnsignedIntArrayConstructor CanvasUnsignedIntArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasFloatArrayConstructor CanvasFloatArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLArrayBufferConstructor WebGLArrayBuffer; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLByteArrayConstructor WebGLByteArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLUnsignedByteArrayConstructor WebGLUnsignedByteArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLShortArrayConstructor WebGLShortArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLUnsignedShortArrayConstructor WebGLUnsignedShortArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLIntArrayConstructor WebGLIntArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLUnsignedIntArrayConstructor WebGLUnsignedIntArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLFloatArrayConstructor WebGLFloatArray; // Usable with new operator
attribute EventConstructor Event;
attribute BeforeLoadEventConstructor BeforeLoadEvent;
@@ -471,6 +485,7 @@ module window {
attribute FileConstructor File;
attribute FileListConstructor FileList;
+ attribute BlobConstructor Blob;
attribute NodeFilterConstructor NodeFilter;
attribute RangeConstructor Range;
@@ -537,35 +552,172 @@ module window {
#endif
#if defined(ENABLE_SVG) && ENABLE_SVG
+ // Expose all implemented SVG 1.1 interfaces, excluding the SVG MI interfaces:
+ // SVGAnimatedPathData, SVGAnimatedPoints, SVGExternalResourcesRequired,
+ // SVGFilterPrimitiveStandardAttributes, SVGFitToViewBox, SVGLangSpace, SVGLocatable
+ // SVGStylable, SVGTests, SVGTransformable, SVGURIReference, SVGZoomAndPan
+ attribute SVGAElementConstructor SVGAElement;
attribute SVGAngleConstructor SVGAngle;
+ attribute SVGAnimatedAngleConstructor SVGAnimatedAngle;
+ attribute SVGAnimatedBooleanConstructor SVGAnimatedBoolean;
+ attribute SVGAnimatedEnumerationConstructor SVGAnimatedEnumeration;
+ attribute SVGAnimatedIntegerConstructor SVGAnimatedInteger;
+ attribute SVGAnimatedLengthConstructor SVGAnimatedLength;
+ attribute SVGAnimatedLengthListConstructor SVGAnimatedLengthList;
+ attribute SVGAnimatedNumberConstructor SVGAnimatedNumber;
+ attribute SVGAnimatedNumberListConstructor SVGAnimatedNumberList;
+ attribute SVGAnimatedPreserveAspectRatioConstructor SVGAnimatedPreserveAspectRatio;
+ attribute SVGAnimatedRectConstructor SVGAnimatedRect;
+ attribute SVGAnimatedStringConstructor SVGAnimatedString;
+ attribute SVGAnimatedTransformListConstructor SVGAnimatedTransformList;
+ attribute SVGCircleElementConstructor SVGCircleElement;
+ attribute SVGClipPathElementConstructor SVGClipPathElement;
attribute SVGColorConstructor SVGColor;
+ attribute SVGCursorElementConstructor SVGCursorElement;
// attribute SVGCSSRuleConstructor SVGCSSRule;
+ attribute SVGDefsElementConstructor SVGDefsElement;
+ attribute SVGDescElementConstructor SVGDescElement;
+ attribute SVGDocumentConstructor SVGDocument;
+ attribute SVGElementConstructor SVGElement;
+ attribute SVGElementInstanceConstructor SVGElementInstance;
+ attribute SVGElementInstanceListConstructor SVGElementInstanceList;
+ attribute SVGEllipseElementConstructor SVGEllipseElement;
attribute SVGExceptionConstructor SVGException;
+ attribute SVGGElementConstructor SVGGElement;
attribute SVGGradientElementConstructor SVGGradientElement;
+ attribute SVGImageElementConstructor SVGImageElement;
attribute SVGLengthConstructor SVGLength;
+ attribute SVGLengthListConstructor SVGLengthList;
+ attribute SVGLinearGradientElementConstructor SVGLinearGradientElement;
+ attribute SVGLineElementConstructor SVGLineElement;
attribute SVGMarkerElementConstructor SVGMarkerElement;
+ attribute SVGMaskElementConstructor SVGMaskElement;
+ attribute SVGMatrixConstructor SVGMatrix;
+ attribute SVGMetadataElementConstructor SVGMetadataElement;
+ attribute SVGNumberConstructor SVGNumber;
+ attribute SVGNumberListConstructor SVGNumberList;
attribute SVGPaintConstructor SVGPaint;
+ attribute SVGPathElementConstructor SVGPathElement;
attribute SVGPathSegConstructor SVGPathSeg;
+ attribute SVGPathSegArcAbsConstructor SVGPathSegArcAbs;
+ attribute SVGPathSegArcRelConstructor SVGPathSegArcRel;
+ attribute SVGPathSegClosePathConstructor SVGPathSegClosePath;
+ attribute SVGPathSegCurvetoCubicAbsConstructor SVGPathSegCurvetoCubicAbs;
+ attribute SVGPathSegCurvetoCubicRelConstructor SVGPathSegCurvetoCubicRel;
+ attribute SVGPathSegCurvetoCubicSmoothAbsConstructor SVGPathSegCurvetoCubicSmoothAbs;
+ attribute SVGPathSegCurvetoCubicSmoothRelConstructor SVGPathSegCurvetoCubicSmoothRel;
+ attribute SVGPathSegCurvetoQuadraticAbsConstructor SVGPathSegCurvetoQuadraticAbs;
+ attribute SVGPathSegCurvetoQuadraticRelConstructor SVGPathSegCurvetoQuadraticRel;
+ attribute SVGPathSegCurvetoQuadraticSmoothAbsConstructor SVGPathSegCurvetoQuadraticSmoothAbs;
+ attribute SVGPathSegCurvetoQuadraticSmoothRelConstructor SVGPathSegCurvetoQuadraticSmoothRel;
+ attribute SVGPathSegLinetoAbsConstructor SVGPathSegLinetoAbs;
+ attribute SVGPathSegLinetoHorizontalAbsConstructor SVGPathSegLinetoHorizontalAbs;
+ attribute SVGPathSegLinetoHorizontalRelConstructor SVGPathSegLinetoHorizontalRel;
+ attribute SVGPathSegLinetoRelConstructor SVGPathSegLinetoRel;
+ attribute SVGPathSegLinetoVerticalAbsConstructor SVGPathSegLinetoVerticalAbs;
+ attribute SVGPathSegLinetoVerticalRelConstructor SVGPathSegLinetoVerticalRel;
+ attribute SVGPathSegListConstructor SVGPathSegList;
+ attribute SVGPathSegMovetoAbsConstructor SVGPathSegMovetoAbs;
+ attribute SVGPathSegMovetoRelConstructor SVGPathSegMovetoRel;
+ attribute SVGPatternElementConstructor SVGPatternElement;
+ attribute SVGPointConstructor SVGPoint;
+ attribute SVGPointListConstructor SVGPointList;
+ attribute SVGPolygonElementConstructor SVGPolygonElement;
+ attribute SVGPolylineElementConstructor SVGPolylineElement;
attribute SVGPreserveAspectRatioConstructor SVGPreserveAspectRatio;
+ attribute SVGRadialGradientElementConstructor SVGRadialGradientElement;
+ attribute SVGRectConstructor SVGRect;
+ attribute SVGRectElementConstructor SVGRectElement;
attribute SVGRenderingIntentConstructor SVGRenderingIntent;
+ attribute SVGScriptElementConstructor SVGScriptElement;
+ attribute SVGStopElementConstructor SVGStopElement;
+ attribute SVGStringListConstructor SVGStringList;
+ attribute SVGStyleElementConstructor SVGStyleElement;
+ attribute SVGSVGElementConstructor SVGSVGElement;
+ attribute SVGSwitchElementConstructor SVGSwitchElement;
+ attribute SVGSymbolElementConstructor SVGSymbolElement;
attribute SVGTextContentElementConstructor SVGTextContentElement;
+ attribute SVGTextElementConstructor SVGTextElement;
attribute SVGTextPathElementConstructor SVGTextPathElement;
+ attribute SVGTextPositioningElementConstructor SVGTextPositioningElement;
+ attribute SVGTitleElementConstructor SVGTitleElement;
attribute SVGTransformConstructor SVGTransform;
+ attribute SVGTransformListConstructor SVGTransformList;
+ attribute SVGTRefElementConstructor SVGTRefElement;
+ attribute SVGTSpanElementConstructor SVGTSpanElement;
attribute SVGUnitTypesConstructor SVGUnitTypes;
-// attribute SVGZoomAndPanConstructor SVGZoomAndPan;
+ attribute SVGUseElementConstructor SVGUseElement;
+ attribute SVGViewElementConstructor SVGViewElement;
+// attribute SVGViewSpecConstructor SVGViewSpec;
+ attribute SVGZoomEventConstructor SVGZoomEvent;
+
+#if defined(ENABLE_SVG_ANIMATION) && ENABLE_SVG_ANIMATION
+ attribute SVGAnimateColorElementConstructor SVGAnimateColorElement;
+ attribute SVGAnimateElementConstructor SVGAnimateElement;
+// attribute SVGAnimateMotionElementConstructor SVGAnimateMotionElement;
+ attribute SVGAnimateTransformElementConstructor SVGAnimateTransformElement;
+// attribute SVGMPathElementConstructor SVGMPathElement;
+ attribute SVGSetElementConstructor SVGSetElement;
+#endif
+
+#if ENABLE_SVG_FONTS && ENABLE_SVG_FONTS
+// attribute SVGAltGlyphDefElementConstructor SVGAltGlyphDefElement;
+ attribute SVGAltGlyphElementConstructor SVGAltGlyphElement;
+// attribute SVGAltGlyphItemElementConstructor SVGAltGlyphItemElement;
+// attribute SVGDefinitionSrcElementConstructor SVGDefinitionSrcElement;
+ attribute SVGFontElementConstructor SVGFontElement;
+ attribute SVGFontFaceElementConstructor SVGFontFaceElement;
+ attribute SVGFontFaceFormatElementConstructor SVGFontFaceFormatElement;
+ attribute SVGFontFaceNameElementConstructor SVGFontFaceNameElement;
+ attribute SVGFontFaceSrcElementConstructor SVGFontFaceSrcElement;
+ attribute SVGFontFaceUriElementConstructor SVGFontFaceUriElement;
+ attribute SVGGlyphElementConstructor SVGGlyphElement;
+// attribute SVGGlyphRefElementConstructor SVGGlyphRefElement;
+// attribute SVGHKernElementConstructor SVGHKernElement;
+ attribute SVGMissingGlyphElementConstructor SVGMissingGlyphElement;
+// attribute SVGVKernElementConstructor SVGVKernElement;
+#endif
+
+#if defined(ENABLE_SVG_FOREIGN_OBJECT) && ENABLE_SVG_FOREIGN_OBJECT
+ attribute SVGForeignObjectElementConstructor SVGForeignObjectElement;
+#endif
#if defined(ENABLE_FILTERS) && ENABLE_FILTERS
attribute SVGComponentTransferFunctionElementConstructor SVGComponentTransferFunctionElement;
attribute SVGFEBlendElementConstructor SVGFEBlendElement;
attribute SVGFEColorMatrixElementConstructor SVGFEColorMatrixElement;
+ attribute SVGFEComponentTransferElementConstructor SVGFEComponentTransferElement;
attribute SVGFECompositeElementConstructor SVGFECompositeElement;
// attribute SVGFEConvolveMatrixElementConstructor SVGFEConvolveMatrixElement;
+ attribute SVGFEDiffuseLightingElementConstructor SVGFEDiffuseLightingElement;
attribute SVGFEDisplacementMapElementConstructor SVGFEDisplacementMapElement;
+ attribute SVGFEDistantLightElementConstructor SVGFEDistantLightElement;
+ attribute SVGFEFloodElementConstructor SVGFEFloodElement;
+ attribute SVGFEFuncAElementConstructor SVGFEFuncAElement;
+ attribute SVGFEFuncBElementConstructor SVGFEFuncBElement;
+ attribute SVGFEFuncGElementConstructor SVGFEFuncGElement;
+ attribute SVGFEFuncRElementConstructor SVGFEFuncRElement;
+ attribute SVGFEGaussianBlurElementConstructor SVGFEGaussianBlurElement;
+ attribute SVGFEImageElementConstructor SVGFEImageElement;
+ attribute SVGFEMergeElementConstructor SVGFEMergeElement;
+ attribute SVGFEMergeNodeElementConstructor SVGFEMergeNodeElement;
attribute SVGFEMorphologyElementConstructor SVGFEMorphologyElement;
+ attribute SVGFEOffsetElementConstructor SVGFEOffsetElement;
+ attribute SVGFEPointLightElementConstructor SVGFEPointLightElement;
+ attribute SVGFESpecularLightingElementConstructor SVGFESpecularLightingElement;
+ attribute SVGFESpotLightElementConstructor SVGFESpotLightElement;
+ attribute SVGFETileElementConstructor SVGFETileElement;
attribute SVGFETurbulenceElementConstructor SVGFETurbulenceElement;
+ attribute SVGFilterElementConstructor SVGFilterElement;
+#endif
#endif
+
+#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
+ attribute TouchEventConstructor TouchEvent;
#endif
+ attribute DOMFormDataConstructor FormData;
+
#endif // defined(LANGUAGE_JAVASCRIPT)
#if defined(V8_BINDING) && V8_BINDING
@@ -575,3 +727,4 @@ module window {
};
}
+
diff --git a/src/3rdparty/webkit/WebCore/page/DragController.cpp b/src/3rdparty/webkit/WebCore/page/DragController.cpp
index 634595a..f238b27 100644
--- a/src/3rdparty/webkit/WebCore/page/DragController.cpp
+++ b/src/3rdparty/webkit/WebCore/page/DragController.cpp
@@ -53,6 +53,7 @@
#include "MoveSelectionCommand.h"
#include "Node.h"
#include "Page.h"
+#include "PlatformKeyboardEvent.h"
#include "RenderFileUploadControl.h"
#include "RenderImage.h"
#include "RenderView.h"
@@ -70,10 +71,12 @@ namespace WebCore {
static PlatformMouseEvent createMouseEvent(DragData* dragData)
{
- // FIXME: We should fake modifier keys here.
+ bool shiftKey, ctrlKey, altKey, metaKey;
+ shiftKey = ctrlKey = altKey = metaKey = false;
+ PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
return PlatformMouseEvent(dragData->clientPosition(), dragData->globalPosition(),
- LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime());
-
+ LeftButton, MouseEventMoved, 0, shiftKey, ctrlKey, altKey,
+ metaKey, currentTime());
}
DragController::DragController(Page* page, DragClient* client)
@@ -429,10 +432,11 @@ bool DragController::concludeEditDrag(DragData* dragData)
m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData);
if (dragIsMove(innerFrame->selection())) {
- bool smartMove = innerFrame->selectionGranularity() == WordGranularity
- && innerFrame->editor()->smartInsertDeleteEnabled()
- && dragData->canSmartReplace();
- applyCommand(MoveSelectionCommand::create(fragment, dragCaret.base(), smartMove));
+ // NSTextView behavior is to always smart delete on moving a selection,
+ // but only to smart insert if the selection granularity is word granularity.
+ bool smartDelete = innerFrame->editor()->smartInsertDeleteEnabled();
+ bool smartInsert = smartDelete && innerFrame->selectionGranularity() == WordGranularity && dragData->canSmartReplace();
+ applyCommand(MoveSelectionCommand::create(fragment, dragCaret.base(), smartInsert, smartDelete));
} else {
if (setSelectionToDragCaret(innerFrame, dragCaret, range, point))
applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse, fragment, true, dragData->canSmartReplace(), chosePlainText));
@@ -486,13 +490,17 @@ static DragOperation defaultOperationForDrag(DragOperation srcOpMask)
{
// This is designed to match IE's operation fallback for the case where
// the page calls preventDefault() in a drag event but doesn't set dropEffect.
- if (srcOpMask & DragOperationCopy)
- return DragOperationCopy;
+ if (srcOpMask == DragOperationEvery)
+ return DragOperationCopy;
+ if (srcOpMask == DragOperationNone)
+ return DragOperationNone;
if (srcOpMask & DragOperationMove || srcOpMask & DragOperationGeneric)
return DragOperationMove;
+ if (srcOpMask & DragOperationCopy)
+ return DragOperationCopy;
if (srcOpMask & DragOperationLink)
return DragOperationLink;
-
+
// FIXME: Does IE really return "generic" even if no operations were allowed by the source?
return DragOperationGeneric;
}
@@ -517,10 +525,10 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
return false;
}
- if (!clipboard->destinationOperation(operation)) {
- // The element accepted but they didn't pick an operation, so we pick one (to match IE).
+ operation = clipboard->destinationOperation();
+ if (clipboard->dropEffectIsUninitialized())
operation = defaultOperationForDrag(srcOpMask);
- } else if (!(srcOpMask & operation)) {
+ else if (!(srcOpMask & operation)) {
// The element picked an operation which is not supported by the source
operation = DragOperationNone;
}
@@ -529,7 +537,7 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
return true;
}
-bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPoint& framePos)
+bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPoint& framePos, Node* node)
{
ASSERT(frame);
ASSERT(frame->settings());
@@ -540,6 +548,8 @@ bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPo
HitTestResult mouseDownTarget = HitTestResult(framePos);
mouseDownTarget = frame->eventHandler()->hitTestResultAtPoint(framePos, true);
+ if (node)
+ mouseDownTarget.setInnerNonSharedNode(node);
if (mouseDownTarget.image()
&& !mouseDownTarget.absoluteImageURL().isEmpty()
@@ -549,7 +559,8 @@ bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPo
if (!mouseDownTarget.absoluteLinkURL().isEmpty()
&& m_dragSourceAction & DragSourceActionLink
- && mouseDownTarget.isLiveLink())
+ && mouseDownTarget.isLiveLink()
+ && mouseDownTarget.URLElement()->renderer() && mouseDownTarget.URLElement()->renderer()->style()->userDrag() != DRAG_NONE)
return true;
if (mouseDownTarget.isSelected()
@@ -557,7 +568,6 @@ bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPo
return true;
return false;
-
}
static CachedImage* getCachedImage(Element* element)
@@ -573,14 +583,9 @@ static CachedImage* getCachedImage(Element* element)
static Image* getImage(Element* element)
{
ASSERT(element);
- RenderObject* renderer = element->renderer();
- if (!renderer || !renderer->isImage())
- return 0;
-
- RenderImage* image = toRenderImage(renderer);
- if (image->cachedImage() && !image->cachedImage()->errorOccurred())
- return image->cachedImage()->image();
- return 0;
+ CachedImage* cachedImage = getCachedImage(element);
+ return (cachedImage && !cachedImage->errorOccurred()) ?
+ cachedImage->image() : 0;
}
static void prepareClipboardForImageDrag(Frame* src, Clipboard* clipboard, Element* node, const KURL& linkURL, const KURL& imageURL, const String& label)
@@ -714,10 +719,16 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
}
doSystemDrag(dragImage, dragLoc, mouseDraggedPoint, clipboard, src, true);
} else if (isSelected && (m_dragSourceAction & DragSourceActionSelection)) {
- RefPtr<Range> selectionRange = src->selection()->toNormalizedRange();
- ASSERT(selectionRange);
- if (!clipboard->hasData())
- clipboard->writeRange(selectionRange.get(), src);
+ if (!clipboard->hasData()) {
+ if (isNodeInTextFormControl(src->selection()->start().node()))
+ clipboard->writePlainText(src->selectedText());
+ else {
+ RefPtr<Range> selectionRange = src->selection()->toNormalizedRange();
+ ASSERT(selectionRange);
+
+ clipboard->writeRange(selectionRange.get(), src);
+ }
+ }
m_client->willPerformDragSourceAction(DragSourceActionSelection, dragOrigin, clipboard);
if (!dragImage) {
dragImage = createDragImageForSelection(src);
diff --git a/src/3rdparty/webkit/WebCore/page/DragController.h b/src/3rdparty/webkit/WebCore/page/DragController.h
index 9472589..3b2b083 100644
--- a/src/3rdparty/webkit/WebCore/page/DragController.h
+++ b/src/3rdparty/webkit/WebCore/page/DragController.h
@@ -47,7 +47,7 @@ namespace WebCore {
class Range;
class SelectionController;
- class DragController {
+ class DragController : public Noncopyable {
public:
DragController(Page*, DragClient*);
~DragController();
@@ -77,7 +77,7 @@ namespace WebCore {
DragDestinationAction dragDestinationAction() const { return m_dragDestinationAction; }
DragSourceAction delegateDragSourceAction(const IntPoint& pagePoint);
- bool mayStartDragAtEventLocation(const Frame*, const IntPoint& framePos);
+ bool mayStartDragAtEventLocation(const Frame*, const IntPoint& framePos, Node*);
void dragEnded();
void placeDragCaret(const IntPoint&);
diff --git a/src/3rdparty/webkit/WebCore/page/EventHandler.cpp b/src/3rdparty/webkit/WebCore/page/EventHandler.cpp
index 4e97aba..0a0e8c6 100644
--- a/src/3rdparty/webkit/WebCore/page/EventHandler.cpp
+++ b/src/3rdparty/webkit/WebCore/page/EventHandler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
*
* Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,7 @@
#include "AXObjectCache.h"
#include "CachedImage.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "Cursor.h"
#include "Document.h"
@@ -56,6 +57,7 @@
#include "Page.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
+#include "PluginDocument.h"
#include "RenderFrameSet.h"
#include "RenderTextControlSingleLine.h"
#include "RenderView.h"
@@ -64,7 +66,9 @@
#include "SelectionController.h"
#include "Settings.h"
#include "TextEvent.h"
+#include "WheelEvent.h"
#include "htmlediting.h" // for comparePositions()
+#include <wtf/CurrentTime.h>
#include <wtf/StdLibExtras.h>
#if ENABLE(SVG)
@@ -74,6 +78,11 @@
#include "SVGUseElement.h"
#endif
+#if ENABLE(TOUCH_EVENTS)
+#include "PlatformTouchEvent.h"
+#include "TouchEvent.h"
+#endif
+
namespace WebCore {
using namespace HTMLNames;
@@ -99,28 +108,36 @@ using namespace SVGNames;
// When the autoscroll or the panScroll is triggered when do the scroll every 0.05s to make it smooth
const double autoscrollInterval = 0.05;
+const double fakeMouseMoveInterval = 0.1;
+
static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
-static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node, Node** stopNode)
+static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Node** stopNode)
{
if (!delta)
- return;
-
+ return false;
+
+ if (!node->renderer())
+ return false;
+
// Find the nearest enclosing box.
RenderBox* enclosingBox = node->renderer()->enclosingBox();
- if (e.granularity() == ScrollByPageWheelEvent) {
- if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1, stopNode))
- e.accept();
- return;
- }
+ float absDelta = delta > 0 ? delta : -delta;
+
+ if (granularity == WheelEvent::Page)
+ return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, absDelta, stopNode);
+
+ if (granularity == WheelEvent::Line)
+ return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByLine, absDelta, stopNode);
- float pixelsToScroll = delta > 0 ? delta : -delta;
- if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll, stopNode))
- e.accept();
+ if (granularity == WheelEvent::Pixel)
+ return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, absDelta, stopNode);
+
+ return false;
}
-#if !PLATFORM(MAC)
+#if !PLATFORM(MAC) || ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
inline bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
{
@@ -155,6 +172,7 @@ EventHandler::EventHandler(Frame* frame)
, m_autoscrollInProgress(false)
, m_mouseDownMayStartAutoscroll(false)
, m_mouseDownWasInSubframe(false)
+ , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFired)
#if ENABLE(SVG)
, m_svgPan(false)
#endif
@@ -164,7 +182,7 @@ EventHandler::EventHandler(Frame* frame)
, m_mouseDownTimestamp(0)
, m_useLatchedWheelEventNode(false)
, m_widgetIsLatched(false)
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
, m_mouseDownView(nil)
, m_sendingEventToSubview(false)
, m_activationEventNumber(0)
@@ -174,6 +192,7 @@ EventHandler::EventHandler(Frame* frame)
EventHandler::~EventHandler()
{
+ ASSERT(!m_fakeMouseMoveEventTimer.isActive());
}
#if ENABLE(DRAG_SUPPORT)
@@ -187,6 +206,7 @@ EventHandler::EventHandlerDragState& EventHandler::dragState()
void EventHandler::clear()
{
m_hoverTimer.stop();
+ m_fakeMouseMoveEventTimer.stop();
m_resizeLayer = 0;
m_nodeUnderMouse = 0;
m_lastNodeUnderMouse = 0;
@@ -201,6 +221,7 @@ void EventHandler::clear()
m_frameSetBeingResized = 0;
#if ENABLE(DRAG_SUPPORT)
m_dragTarget = 0;
+ m_shouldOnlyFireDragOverEvent = false;
#endif
m_currentMousePosition = IntPoint();
m_mousePressNode = 0;
@@ -218,20 +239,21 @@ void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestRe
if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) {
VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
+ TextGranularity granularity = CharacterGranularity;
if (pos.isNotNull()) {
newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(WordGranularity);
}
if (newSelection.isRange()) {
- m_frame->setSelectionGranularity(WordGranularity);
+ granularity = WordGranularity;
m_beganSelectingText = true;
if (result.event().clickCount() == 2 && m_frame->editor()->isSelectTrailingWhitespaceEnabled())
newSelection.appendTrailingWhitespace();
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection, granularity);
}
}
@@ -249,13 +271,14 @@ void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit
if (pos.isNotNull() && pos.deepEquivalent().node()->isDescendantOf(URLElement))
newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
+ TextGranularity granularity = CharacterGranularity;
if (newSelection.isRange()) {
- m_frame->setSelectionGranularity(WordGranularity);
+ granularity = WordGranularity;
m_beganSelectingText = true;
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection, granularity);
}
}
@@ -292,13 +315,15 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR
newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(ParagraphGranularity);
}
+
+ TextGranularity granularity = CharacterGranularity;
if (newSelection.isRange()) {
- m_frame->setSelectionGranularity(ParagraphGranularity);
+ granularity = ParagraphGranularity;
m_beganSelectingText = true;
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection, granularity);
return true;
}
@@ -328,6 +353,8 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
Position pos = visiblePos.deepEquivalent();
VisibleSelection newSelection = m_frame->selection()->selection();
+ TextGranularity granularity = CharacterGranularity;
+
if (extendSelection && newSelection.isCaretOrRange()) {
m_frame->selection()->setLastChangeWasHorizontalExtension(false);
@@ -340,16 +367,17 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
else
newSelection = VisibleSelection(start, pos);
- if (m_frame->selectionGranularity() != CharacterGranularity)
+ if (m_frame->selectionGranularity() != CharacterGranularity) {
+ granularity = m_frame->selectionGranularity();
newSelection.expandUsingGranularity(m_frame->selectionGranularity());
+ }
+
m_beganSelectingText = true;
- } else {
+ } else
newSelection = VisibleSelection(visiblePos);
- m_frame->setSelectionGranularity(CharacterGranularity);
- }
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection, granularity);
return true;
}
@@ -361,6 +389,8 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
dragState().m_dragSrc = 0;
#endif
+ cancelFakeMouseMoveEvent();
+
if (ScrollView* scrollView = m_frame->view()) {
if (scrollView->isPointInScrollbarCorner(event.event().pos()))
return false;
@@ -562,7 +592,7 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
if (m_frame->shouldChangeSelection(newSelection)) {
m_frame->selection()->setLastChangeWasHorizontalExtension(false);
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection, m_frame->selectionGranularity());
}
}
#endif // ENABLE(DRAG_SUPPORT)
@@ -688,6 +718,14 @@ void EventHandler::autoscrollTimerFired(Timer<EventHandler>*)
#if ENABLE(PAN_SCROLLING)
+void EventHandler::startPanScrolling(RenderObject* renderer)
+{
+ m_panScrollInProgress = true;
+ m_panScrollButtonPressed = true;
+ handleAutoscroll(renderer);
+ invalidateClick();
+}
+
void EventHandler::updatePanScrollState()
{
FrameView* view = m_frame->view();
@@ -1128,6 +1166,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame->view());
+ cancelFakeMouseMoveEvent();
m_mousePressed = true;
m_capturesDragging = true;
m_currentMousePosition = mouseEvent.pos();
@@ -1187,25 +1226,6 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
invalidateClick();
return true;
}
-
- if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) {
- RenderObject* renderer = mev.targetNode()->renderer();
-
- while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) {
- if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
- renderer = renderer->document()->ownerElement()->renderer();
- else
- renderer = renderer->parent();
- }
-
- if (renderer) {
- m_panScrollInProgress = true;
- m_panScrollButtonPressed = true;
- handleAutoscroll(renderer);
- invalidateClick();
- return true;
- }
- }
#endif
m_clickCount = mouseEvent.clickCount();
@@ -1338,6 +1358,8 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
if (m_hoverTimer.isActive())
m_hoverTimer.stop();
+ cancelFakeMouseMoveEvent();
+
#if ENABLE(SVG)
if (m_svgPan) {
static_cast<SVGDocument*>(m_frame->document())->updatePan(m_currentMousePosition);
@@ -1400,8 +1422,18 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
scrollbar->mouseMoved(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
if (Page* page = m_frame->page()) {
if ((!m_resizeLayer || !m_resizeLayer->inResizeMode()) && !page->mainFrame()->eventHandler()->panScrollInProgress()) {
- if (FrameView* view = m_frame->view())
- view->setCursor(selectCursor(mev, scrollbar));
+ // Plugins set cursor on their own. The only case WebKit intervenes is resetting cursor to arrow on mouse enter,
+ // in case the particular plugin doesn't manipulate cursor at all. Thus, even a CSS cursor set on body has no
+ // effect on plugins (which matches Firefox).
+ bool overPluginElement = false;
+ if (mev.targetNode() && mev.targetNode()->isHTMLElement()) {
+ HTMLElement* el = static_cast<HTMLElement*>(mev.targetNode());
+ overPluginElement = el->hasTagName(appletTag) || el->hasTagName(objectTag) || el->hasTagName(embedTag);
+ }
+ if (!overPluginElement) {
+ if (FrameView* view = m_frame->view())
+ view->setCursor(selectCursor(mev, scrollbar));
+ }
}
}
}
@@ -1508,6 +1540,35 @@ bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa
return me->defaultPrevented();
}
+bool EventHandler::canHandleDragAndDropForTarget(DragAndDropHandleType type, Node* target, const PlatformMouseEvent& event, Clipboard* clipboard, bool* accepted)
+{
+ bool canHandle = false;
+ bool wasAccepted = false;
+
+ if (target->hasTagName(frameTag) || target->hasTagName(iframeTag)) {
+ Frame* frame = static_cast<HTMLFrameElementBase*>(target)->contentFrame();
+ if (frame) {
+ switch (type) {
+ case UpdateDragAndDrop:
+ wasAccepted = frame->eventHandler()->updateDragAndDrop(event, clipboard);
+ break;
+ case CancelDragAndDrop:
+ frame->eventHandler()->cancelDragAndDrop(event, clipboard);
+ break;
+ case PerformDragAndDrop:
+ wasAccepted = frame->eventHandler()->performDragAndDrop(event, clipboard);
+ break;
+ }
+ }
+ } else
+ canHandle = true;
+
+ if (accepted)
+ *accepted = wasAccepted;
+
+ return canHandle;
+}
+
bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
{
bool accept = false;
@@ -1529,28 +1590,34 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
// FIXME: this ordering was explicitly chosen to match WinIE. However,
// it is sometimes incorrect when dragging within subframes, as seen with
// LayoutTests/fast/events/drag-in-frames.html.
- if (newTarget) {
- Frame* frame = (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame() : 0;
- if (frame)
- accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);
- else
- accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard);
+ //
+ // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <http://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>.
+ if (newTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, newTarget, event, clipboard, &accept)) {
+ // As per section 7.9.4 of the HTML 5 spec., we must always fire a drag event before firing a dragenter, dragleave, or dragover event.
+ if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) {
+ // for now we don't care if event handler cancels default behavior, since there is none
+ dispatchDragSrcEvent(eventNames().dragEvent, event);
+ }
+ accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard);
}
- if (m_dragTarget) {
- Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
- if (frame)
- accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);
- else
- dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
+ if (m_dragTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, m_dragTarget.get(), event, clipboard, &accept))
+ dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
+
+ if (newTarget) {
+ // We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that
+ // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function.
+ m_shouldOnlyFireDragOverEvent = true;
}
} else {
- if (newTarget) {
- Frame* frame = (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame() : 0;
- if (frame)
- accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);
- else
- accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard);
+ if (newTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, newTarget, event, clipboard, &accept)) {
+ // Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier.
+ if (!m_shouldOnlyFireDragOverEvent && dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) {
+ // for now we don't care if event handler cancels default behavior, since there is none
+ dispatchDragSrcEvent(eventNames().dragEvent, event);
+ }
+ accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard);
+ m_shouldOnlyFireDragOverEvent = false;
}
}
m_dragTarget = newTarget;
@@ -1560,13 +1627,10 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
{
- if (m_dragTarget) {
- Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag))
- ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
- if (frame)
- frame->eventHandler()->cancelDragAndDrop(event, clipboard);
- else
- dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
+ if (m_dragTarget && canHandleDragAndDropForTarget(CancelDragAndDrop, m_dragTarget.get(), event, clipboard)) {
+ if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML)
+ dispatchDragSrcEvent(eventNames().dragEvent, event);
+ dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
}
clearDragState();
}
@@ -1574,14 +1638,8 @@ void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard*
bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
{
bool accept = false;
- if (m_dragTarget) {
- Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag))
- ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
- if (frame)
- accept = frame->eventHandler()->performDragAndDrop(event, clipboard);
- else
- accept = dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard);
- }
+ if (m_dragTarget && canHandleDragAndDropForTarget(PerformDragAndDrop, m_dragTarget.get(), event, clipboard, &accept))
+ dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard);
clearDragState();
return accept;
}
@@ -1590,7 +1648,8 @@ void EventHandler::clearDragState()
{
m_dragTarget = 0;
m_capturingMouseEventsNode = 0;
-#if PLATFORM(MAC)
+ m_shouldOnlyFireDragOverEvent = false;
+#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
m_sendingEventToSubview = false;
#endif
}
@@ -1763,7 +1822,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
return swallowEvent;
}
-#if !PLATFORM(GTK)
+#if !PLATFORM(GTK) && !(PLATFORM(CHROMIUM) && OS(LINUX))
bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&) const
{
return false;
@@ -1832,21 +1891,6 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
node->dispatchWheelEvent(e);
if (e.isAccepted())
return true;
-
- // If we don't have a renderer, send the wheel event to the first node we find with a renderer.
- // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
- while (node && !node->renderer())
- node = node->parent();
-
- if (node && node->renderer()) {
- // Just break up into two scrolls if we need to. Diagonal movement on
- // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
- Node* stopNode = m_previousWheelScrolledNode.get();
- scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node, &stopNode);
- scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node, &stopNode);
- if (!m_useLatchedWheelEventNode)
- m_previousWheelScrolledNode = stopNode;
- }
}
if (e.isAccepted())
@@ -1859,6 +1903,25 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
view->wheelEvent(e);
return e.isAccepted();
}
+
+void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEvent)
+{
+ if (!startNode || !wheelEvent)
+ return;
+
+ Node* stopNode = m_previousWheelScrolledNode.get();
+
+ // Break up into two scrolls if we need to. Diagonal movement on
+ // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
+ if (scrollNode(wheelEvent->rawDeltaX(), wheelEvent->granularity(), ScrollLeft, ScrollRight, startNode, &stopNode))
+ wheelEvent->setDefaultHandled();
+
+ if (scrollNode(wheelEvent->rawDeltaY(), wheelEvent->granularity(), ScrollUp, ScrollDown, startNode, &stopNode))
+ wheelEvent->setDefaultHandled();
+
+ if (!m_useLatchedWheelEventNode)
+ m_previousWheelScrolledNode = stopNode;
+}
#if ENABLE(CONTEXT_MENUS)
bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
@@ -1899,6 +1962,43 @@ void EventHandler::scheduleHoverStateUpdate()
m_hoverTimer.startOneShot(0);
}
+void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
+{
+ FrameView* view = m_frame->view();
+ if (!view)
+ return;
+
+ if (m_mousePressed || !quad.containsPoint(view->windowToContents(m_currentMousePosition)))
+ return;
+
+ if (!m_fakeMouseMoveEventTimer.isActive())
+ m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveInterval);
+}
+
+void EventHandler::cancelFakeMouseMoveEvent()
+{
+ m_fakeMouseMoveEventTimer.stop();
+}
+
+void EventHandler::fakeMouseMoveEventTimerFired(Timer<EventHandler>* timer)
+{
+ ASSERT_UNUSED(timer, timer == &m_fakeMouseMoveEventTimer);
+ ASSERT(!m_mousePressed);
+
+ FrameView* view = m_frame->view();
+ if (!view)
+ return;
+
+ bool shiftKey;
+ bool ctrlKey;
+ bool altKey;
+ bool metaKey;
+ PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
+ IntPoint globalPoint = view->contentsToScreen(IntRect(view->windowToContents(m_currentMousePosition), IntSize())).location();
+ PlatformMouseEvent fakeMouseMoveEvent(m_currentMousePosition, globalPoint, NoButton, MouseEventMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime());
+ mouseMoved(fakeMouseMoveEvent);
+}
+
// Whether or not a mouse down can begin the creation of a selection. Fires the selectStart event.
bool EventHandler::canMouseDownStartSelect(Node* node)
{
@@ -1965,6 +2065,10 @@ static Node* eventTargetNodeForDocument(Document* doc)
if (!doc)
return 0;
Node* node = doc->focusedNode();
+ if (!node && doc->isPluginDocument()) {
+ PluginDocument* pluginDocument = static_cast<PluginDocument*>(doc);
+ node = pluginDocument->pluginNode();
+ }
if (!node && doc->isHTMLDocument())
node = doc->body();
if (!node)
@@ -2133,10 +2237,15 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
return;
if (event->keyIdentifier() == "U+0009")
defaultTabEventHandler(event);
+ else {
+ FocusDirection direction = focusDirectionForKey(event->keyIdentifier());
+ if (direction != FocusDirectionNone)
+ defaultArrowEventHandler(direction, event);
+ }
- // provides KB navigation and selection for enhanced accessibility users
- if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
- handleKeyboardSelectionMovement(event);
+ // provides KB navigation and selection for enhanced accessibility users
+ if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
+ handleKeyboardSelectionMovement(event);
}
if (event->type() == eventNames().keypressEvent) {
m_frame->editor()->handleKeyboardEvent(event);
@@ -2147,6 +2256,27 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
}
}
+FocusDirection EventHandler::focusDirectionForKey(const AtomicString& keyIdentifier) const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, Down, ("Down"));
+ DEFINE_STATIC_LOCAL(AtomicString, Up, ("Up"));
+ DEFINE_STATIC_LOCAL(AtomicString, Left, ("Left"));
+ DEFINE_STATIC_LOCAL(AtomicString, Right, ("Right"));
+
+ FocusDirection retVal = FocusDirectionNone;
+
+ if (keyIdentifier == Down)
+ retVal = FocusDirectionDown;
+ else if (keyIdentifier == Up)
+ retVal = FocusDirectionUp;
+ else if (keyIdentifier == Left)
+ retVal = FocusDirectionLeft;
+ else if (keyIdentifier == Right)
+ retVal = FocusDirectionRight;
+
+ return retVal;
+}
+
#if ENABLE(DRAG_SUPPORT)
bool EventHandler::dragHysteresisExceeded(const FloatPoint& floatDragViewportLocation) const
{
@@ -2184,16 +2314,9 @@ bool EventHandler::shouldDragAutoNode(Node* node, const IntPoint& point) const
if (!node || !m_frame->view())
return false;
Page* page = m_frame->page();
- return page && page->dragController()->mayStartDragAtEventLocation(m_frame, point);
-}
-
-void EventHandler::dragSourceMovedTo(const PlatformMouseEvent& event)
-{
- if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML)
- // for now we don't care if event handler cancels default behavior, since there is none
- dispatchDragSrcEvent(eventNames().dragEvent, event);
+ return page && page->dragController()->mayStartDragAtEventLocation(m_frame, point, node);
}
-
+
void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
{
if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) {
@@ -2276,9 +2399,11 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
// We are starting a text/image/url drag, so the cursor should be an arrow
- if (FrameView* view = m_frame->view())
+ if (FrameView* view = m_frame->view()) {
+ // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and drop (default to pointer).
view->setCursor(pointerCursor());
-
+ }
+
if (!dragHysteresisExceeded(event.event().pos()))
return true;
@@ -2299,7 +2424,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
// FIXME: This doesn't work correctly with transforms.
FloatPoint absPos = renderer->localToAbsolute();
IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
- dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint() + delta);
+ dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), toPoint(delta));
} else {
// The renderer has disappeared, this can happen if the onStartDrag handler has hidden
// the element in some way. In this case we just kill the drag.
@@ -2317,11 +2442,12 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
if (m_mouseDownMayStartDrag) {
// gather values from DHTML element, if it set any
- dragState().m_dragClipboard->sourceOperation(srcOp);
+ srcOp = dragState().m_dragClipboard->sourceOperation();
- // Yuck, dragSourceMovedTo() can be called as a result of kicking off the drag with
- // dragImage! Because of that dumb reentrancy, we may think we've not started the
- // drag when that happens. So we have to assume it's started before we kick it off.
+ // Yuck, a draggedImage:moveTo: message can be fired as a result of kicking off the
+ // drag with dragImage! Because of that dumb reentrancy, we may think we've not
+ // started the drag when that happens. So we have to assume it's started before we
+ // kick it off.
dragState().m_dragClipboard->setDragHasStarted();
}
}
@@ -2378,8 +2504,7 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
return event->defaultHandled();
}
-
-#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(HAIKU)
+#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(HAIKU) && !PLATFORM(EFL)
bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent*) const
{
return false;
@@ -2445,6 +2570,27 @@ void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
#endif
+void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, KeyboardEvent* event)
+{
+ if (event->ctrlKey() || event->metaKey() || event->altGraphKey() || event->shiftKey())
+ return;
+
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
+ if (!page->settings() || !page->settings()->isSpatialNavigationEnabled())
+ return;
+
+ // Arrows and other possible directional navigation keys can be used in design
+ // mode editing.
+ if (m_frame->document()->inDesignMode())
+ return;
+
+ if (page->focusController()->advanceFocus(focusDirection, event))
+ event->setDefaultHandled();
+}
+
void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
{
// We should only advance focus on tabs if no special modifier keys are held down.
@@ -2517,4 +2663,174 @@ void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setL
}
}
+#if ENABLE(TOUCH_EVENTS)
+
+static PassRefPtr<TouchList> assembleTargetTouches(Touch* touchTarget, TouchList* touches)
+{
+ RefPtr<TouchList> targetTouches = TouchList::create();
+
+ for (unsigned i = 0; i < touches->length(); ++i) {
+ if (touches->item(i)->target()->toNode()->isSameNode(touchTarget->target()->toNode()))
+ targetTouches->append(touches->item(i));
+ }
+
+ return targetTouches.release();
+}
+
+bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
+{
+ RefPtr<TouchList> touches = TouchList::create();
+ RefPtr<TouchList> pressedTouches = TouchList::create();
+ RefPtr<TouchList> releasedTouches = TouchList::create();
+ RefPtr<TouchList> movedTouches = TouchList::create();
+ RefPtr<TouchList> cancelTouches = TouchList::create();
+
+ const Vector<PlatformTouchPoint>& points = event.touchPoints();
+ AtomicString* eventName = 0;
+
+ 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);
+ 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;
+
+ if (m_frame != doc->frame()) {
+ // pagePoint should always be relative to the target elements containing frame.
+ pagePoint = documentPointForWindowPoint(doc->frame(), point.pos());
+ }
+
+ int adjustedPageX = lroundf(pagePoint.x() / m_frame->pageZoomFactor());
+ int adjustedPageY = lroundf(pagePoint.y() / m_frame->pageZoomFactor());
+
+ // Increment the platform touch id by 1 to avoid storing a key of 0 in the hashmap.
+ unsigned touchPointTargetKey = point.id() + 1;
+ EventTarget* touchTarget = 0;
+ if (point.state() == PlatformTouchPoint::TouchPressed) {
+ m_originatingTouchPointTargets.set(touchPointTargetKey, target);
+ touchTarget = target;
+ } else if (point.state() == PlatformTouchPoint::TouchReleased || point.state() == PlatformTouchPoint::TouchCancelled) {
+ // The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel
+ // we also remove it from the map.
+ touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey).get();
+ } else
+ touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey).get();
+
+ if (!touchTarget)
+ continue;
+
+ RefPtr<Touch> touch = Touch::create(doc->frame(), touchTarget, point.id(),
+ point.screenPos().x(), point.screenPos().y(),
+ adjustedPageX, adjustedPageY);
+
+ // touches should contain information about every touch currently on the screen.
+ if (point.state() != PlatformTouchPoint::TouchReleased)
+ touches->append(touch);
+
+ // Now build up the correct list for changedTouches.
+ 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 if (point.state() == PlatformTouchPoint::TouchMoved)
+ movedTouches->append(touch);
+ }
+
+ bool defaultPrevented = false;
+ Touch* changedTouch = 0;
+ EventTarget* touchEventTarget = 0;
+
+ if (cancelTouches->length() > 0) {
+ // We dispatch the event to the target of the touch that caused this touch event to be generated, i.e.
+ // we take it from the list that will be used as the changedTouches property of the event.
+ // The choice to use the touch at index 0 guarantees that there is a target (as we checked the length
+ // above). In the case that there are multiple touches in what becomes the changedTouches list, it is
+ // difficult to say how we should prioritise touches and as such, item 0 is an arbitrary choice.
+ changedTouch = cancelTouches->item(0);
+ ASSERT(changedTouch);
+ touchEventTarget = changedTouch->target();
+ ASSERT(touchEventTarget);
+
+ eventName = &eventNames().touchcancelEvent;
+ RefPtr<TouchEvent> cancelEv =
+ TouchEvent::create(TouchList::create().get(), TouchList::create().get(), cancelTouches.get(),
+ *eventName, touchEventTarget->toNode()->document()->defaultView(),
+ 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+ ExceptionCode ec = 0;
+ touchEventTarget->dispatchEvent(cancelEv.get(), ec);
+ defaultPrevented |= cancelEv->defaultPrevented();
+ }
+
+ if (releasedTouches->length() > 0) {
+ Touch* changedTouch = releasedTouches->item(0);
+ ASSERT(changedTouch);
+ touchEventTarget = changedTouch->target();
+ ASSERT(touchEventTarget);
+
+ RefPtr<TouchList> targetTouches = assembleTargetTouches(changedTouch, touches.get());
+
+ eventName = &eventNames().touchendEvent;
+ RefPtr<TouchEvent> endEv =
+ TouchEvent::create(touches.get(), targetTouches.get(), releasedTouches.get(),
+ *eventName, touchEventTarget->toNode()->document()->defaultView(),
+ 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+ ExceptionCode ec = 0;
+ touchEventTarget->dispatchEvent(endEv.get(), ec);
+ defaultPrevented |= endEv->defaultPrevented();
+ }
+ if (pressedTouches->length() > 0) {
+ Touch* changedTouch = pressedTouches->item(0);
+ ASSERT(changedTouch);
+ touchEventTarget = changedTouch->target();
+ ASSERT(touchEventTarget);
+
+ RefPtr<TouchList> targetTouches = assembleTargetTouches(changedTouch, touches.get());
+
+ eventName = &eventNames().touchstartEvent;
+ RefPtr<TouchEvent> startEv =
+ TouchEvent::create(touches.get(), targetTouches.get(), pressedTouches.get(),
+ *eventName, touchEventTarget->toNode()->document()->defaultView(),
+ 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+ ExceptionCode ec = 0;
+ touchEventTarget->dispatchEvent(startEv.get(), ec);
+ defaultPrevented |= startEv->defaultPrevented();
+ }
+
+ if (movedTouches->length() > 0) {
+ Touch* changedTouch = movedTouches->item(0);
+ ASSERT(changedTouch);
+ touchEventTarget = changedTouch->target();
+ ASSERT(touchEventTarget);
+
+ RefPtr<TouchList> targetTouches = assembleTargetTouches(changedTouch, touches.get());
+
+ eventName = &eventNames().touchmoveEvent;
+ RefPtr<TouchEvent> moveEv =
+ TouchEvent::create(touches.get(), targetTouches.get(), movedTouches.get(),
+ *eventName, touchEventTarget->toNode()->document()->defaultView(),
+ 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
+ event.metaKey());
+ ExceptionCode ec = 0;
+ touchEventTarget->dispatchEvent(moveEv.get(), ec);
+ defaultPrevented |= moveEv->defaultPrevented();
+ }
+
+ return defaultPrevented;
+}
+#endif
+
}
diff --git a/src/3rdparty/webkit/WebCore/page/EventHandler.h b/src/3rdparty/webkit/WebCore/page/EventHandler.h
index 0221397..282100d 100644
--- a/src/3rdparty/webkit/WebCore/page/EventHandler.h
+++ b/src/3rdparty/webkit/WebCore/page/EventHandler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +27,7 @@
#define EventHandler_h
#include "DragActions.h"
+#include "FocusDirection.h"
#include "PlatformMouseEvent.h"
#include "ScrollTypes.h"
#include "Timer.h"
@@ -37,13 +38,19 @@
class NSView;
#endif
+#if ENABLE(TOUCH_EVENTS)
+#include <wtf/HashMap.h>
+#endif
+
namespace WebCore {
class AtomicString;
class Clipboard;
class Cursor;
class Event;
+class EventTarget;
class FloatPoint;
+class FloatQuad;
class Frame;
class HitTestRequest;
class HitTestResult;
@@ -52,6 +59,7 @@ class KeyboardEvent;
class MouseEventWithHitTestResults;
class Node;
class PlatformKeyboardEvent;
+class PlatformTouchEvent;
class PlatformWheelEvent;
class RenderLayer;
class RenderObject;
@@ -60,6 +68,8 @@ class Scrollbar;
class String;
class SVGElementInstance;
class TextEvent;
+class TouchEvent;
+class WheelEvent;
class Widget;
#if ENABLE(DRAG_SUPPORT)
@@ -85,6 +95,7 @@ public:
Node* mousePressNode() const;
void setMousePressNode(PassRefPtr<Node>);
+ void startPanScrolling(RenderObject*);
bool panScrollInProgress() { return m_panScrollInProgress; }
void setPanScrollInProgress(bool inProgress) { m_panScrollInProgress = inProgress; }
@@ -92,6 +103,8 @@ public:
RenderObject* autoscrollRenderer() const;
void updateAutoscrollRenderer();
+ void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
+
HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars);
bool mousePressed() const { return m_mousePressed; }
@@ -138,6 +151,7 @@ public:
bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0);
bool handleMouseReleaseEvent(const PlatformMouseEvent&);
bool handleWheelEvent(PlatformWheelEvent&);
+ void defaultWheelEventHandler(Node*, WheelEvent*);
#if ENABLE(CONTEXT_MENUS)
bool sendContextMenuEvent(const PlatformMouseEvent&);
@@ -159,7 +173,6 @@ public:
#if ENABLE(DRAG_SUPPORT)
bool eventMayStartDrag(const PlatformMouseEvent&) const;
- void dragSourceMovedTo(const PlatformMouseEvent&);
void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
#endif
@@ -192,9 +205,19 @@ public:
static NSEvent *currentNSEvent();
#endif
+#if ENABLE(TOUCH_EVENTS)
+ bool handleTouchEvent(const PlatformTouchEvent&);
+#endif
+
private:
#if ENABLE(DRAG_SUPPORT)
- struct EventHandlerDragState {
+ enum DragAndDropHandleType {
+ UpdateDragAndDrop,
+ CancelDragAndDrop,
+ PerformDragAndDrop
+ };
+
+ struct EventHandlerDragState : Noncopyable {
RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
bool m_dragSrcIsLink;
bool m_dragSrcIsImage;
@@ -206,6 +229,8 @@ private:
};
static EventHandlerDragState& dragState();
static const double TextDragDelay;
+
+ bool canHandleDragAndDropForTarget(DragAndDropHandleType, Node* target, const PlatformMouseEvent&, Clipboard*, bool* accepted = 0);
PassRefPtr<Clipboard> createDraggingClipboard() const;
#endif // ENABLE(DRAG_SUPPORT)
@@ -244,6 +269,9 @@ private:
void setAutoscrollRenderer(RenderObject*);
void autoscrollTimerFired(Timer<EventHandler>*);
+ void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
+ void cancelFakeMouseMoveEvent();
+
void invalidateClick();
Node* nodeUnderMouse() const;
@@ -287,6 +315,7 @@ private:
void defaultSpaceEventHandler(KeyboardEvent*);
void defaultTabEventHandler(KeyboardEvent*);
+ void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
#if ENABLE(DRAG_SUPPORT)
void allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const;
@@ -309,9 +338,11 @@ private:
void setFrameWasScrolledByUser();
+ FocusDirection focusDirectionForKey(const AtomicString&) const;
+
bool capturesDragging() const { return m_capturesDragging; }
-#if PLATFORM(MAC) && defined(__OBJC__)
+#if PLATFORM(MAC) && defined(__OBJC__) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
NSView *mouseDownViewIfStillGood();
PlatformMouseEvent currentPlatformMouseEvent() const;
@@ -348,6 +379,8 @@ private:
bool m_mouseDownMayStartAutoscroll;
bool m_mouseDownWasInSubframe;
+ Timer<EventHandler> m_fakeMouseMoveEventTimer;
+
#if ENABLE(SVG)
bool m_svgPan;
RefPtr<SVGElementInstance> m_instanceUnderMouse;
@@ -368,6 +401,7 @@ private:
#if ENABLE(DRAG_SUPPORT)
RefPtr<Node> m_dragTarget;
+ bool m_shouldOnlyFireDragOverEvent;
#endif
RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
@@ -386,10 +420,16 @@ private:
RefPtr<Node> m_previousWheelScrolledNode;
#if PLATFORM(MAC)
+#if !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
NSView *m_mouseDownView;
bool m_sendingEventToSubview;
+#endif
int m_activationEventNumber;
#endif
+#if ENABLE(TOUCH_EVENTS)
+ typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
+ TouchTargetMap m_originatingTouchPointTargets;
+#endif
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/EventSource.cpp b/src/3rdparty/webkit/WebCore/page/EventSource.cpp
index 2c9a343..9ccccd7 100644
--- a/src/3rdparty/webkit/WebCore/page/EventSource.cpp
+++ b/src/3rdparty/webkit/WebCore/page/EventSource.cpp
@@ -57,6 +57,7 @@ EventSource::EventSource(const String& url, ScriptExecutionContext* context, Exc
: ActiveDOMObject(context, this)
, m_state(CONNECTING)
, m_reconnectTimer(this, &EventSource::reconnectTimerFired)
+ , m_discardTrailingNewline(false)
, m_failSilently(false)
, m_requestInFlight(false)
, m_reconnectDelay(defaultReconnectDelay)
@@ -210,21 +211,24 @@ void EventSource::parseEventStream()
{
unsigned int bufPos = 0;
unsigned int bufSize = m_receiveBuf.size();
- for (;;) {
+ while (bufPos < bufSize) {
+ if (m_discardTrailingNewline) {
+ if (m_receiveBuf[bufPos] == '\n')
+ bufPos++;
+ m_discardTrailingNewline = false;
+ }
+
int lineLength = -1;
int fieldLength = -1;
- int carriageReturn = 0;
for (unsigned int i = bufPos; lineLength < 0 && i < bufSize; i++) {
switch (m_receiveBuf[i]) {
case ':':
if (fieldLength < 0)
fieldLength = i - bufPos;
break;
+ case '\r':
+ m_discardTrailingNewline = true;
case '\n':
- if (i > bufPos && m_receiveBuf[i - 1] == '\r') {
- carriageReturn++;
- i--;
- }
lineLength = i - bufPos;
break;
}
@@ -234,7 +238,7 @@ void EventSource::parseEventStream()
break;
parseEventStreamLine(bufPos, fieldLength, lineLength);
- bufPos += lineLength + carriageReturn + 1;
+ bufPos += lineLength + 1;
}
if (bufPos == bufSize)
@@ -246,8 +250,10 @@ void EventSource::parseEventStream()
void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int lineLength)
{
if (!lineLength) {
- if (!m_data.isEmpty())
+ if (!m_data.isEmpty()) {
+ m_data.removeLast();
dispatchEvent(createMessageEvent());
+ }
if (!m_eventName.isEmpty())
m_eventName = "";
} else if (fieldLength) {
@@ -265,10 +271,9 @@ void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int
int valueLength = lineLength - step;
if (field == "data") {
- if (m_data.size() > 0)
- m_data.append('\n');
if (valueLength)
m_data.append(&m_receiveBuf[bufPos], valueLength);
+ m_data.append('\n');
} else if (field == "event")
m_eventName = valueLength ? String(&m_receiveBuf[bufPos], valueLength) : "";
else if (field == "id")
diff --git a/src/3rdparty/webkit/WebCore/page/EventSource.h b/src/3rdparty/webkit/WebCore/page/EventSource.h
index 5b037a4..d0d45cb 100644
--- a/src/3rdparty/webkit/WebCore/page/EventSource.h
+++ b/src/3rdparty/webkit/WebCore/page/EventSource.h
@@ -36,7 +36,6 @@
#include "ActiveDOMObject.h"
#include "AtomicStringHash.h"
-#include "EventListener.h"
#include "EventNames.h"
#include "EventTarget.h"
#include "KURL.h"
@@ -115,6 +114,7 @@ namespace WebCore {
RefPtr<ThreadableLoader> m_loader;
Timer<EventSource> m_reconnectTimer;
Vector<UChar> m_receiveBuf;
+ bool m_discardTrailingNewline;
bool m_failSilently;
bool m_requestInFlight;
diff --git a/src/3rdparty/webkit/WebCore/page/EventSource.idl b/src/3rdparty/webkit/WebCore/page/EventSource.idl
index 561bd68..57bd807 100644
--- a/src/3rdparty/webkit/WebCore/page/EventSource.idl
+++ b/src/3rdparty/webkit/WebCore/page/EventSource.idl
@@ -33,6 +33,7 @@ module window {
interface [
Conditional=EVENTSOURCE,
+ CustomConstructor,
EventTarget,
NoStaticTables
] EventSource {
@@ -52,12 +53,12 @@ module window {
void close();
// EventTarget interface
- [Custom] void addEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- [Custom] void removeEventListener(in DOMString type,
+ [JSCCustom] void addEventListener(in DOMString type,
in EventListener listener,
in boolean useCapture);
+ [JSCCustom] void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
boolean dispatchEvent(in Event evt)
raises(EventException);
diff --git a/src/3rdparty/webkit/WebCore/page/FocusController.cpp b/src/3rdparty/webkit/WebCore/page/FocusController.cpp
index 5e78c7d..089fb8f 100644
--- a/src/3rdparty/webkit/WebCore/page/FocusController.cpp
+++ b/src/3rdparty/webkit/WebCore/page/FocusController.cpp
@@ -38,8 +38,8 @@
#include "EventNames.h"
#include "ExceptionCode.h"
#include "Frame.h"
-#include "FrameView.h"
#include "FrameTree.h"
+#include "FrameView.h"
#include "HTMLFrameOwnerElement.h"
#include "HTMLNames.h"
#include "KeyboardEvent.h"
@@ -49,18 +49,26 @@
#include "RenderWidget.h"
#include "SelectionController.h"
#include "Settings.h"
+#include "SpatialNavigation.h"
#include "Widget.h"
-#include <wtf/Platform.h>
namespace WebCore {
using namespace HTMLNames;
+using namespace std;
static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool focused)
{
// If we have a focused node we should dispatch blur on it before we blur the window.
// If we have a focused node we should dispatch focus on it after we focus the window.
// https://bugs.webkit.org/show_bug.cgi?id=27105
+
+ // Do not fire events while modal dialogs are up. See https://bugs.webkit.org/show_bug.cgi?id=33962
+ if (Page* page = document->page()) {
+ if (page->defersLoading())
+ return;
+ }
+
if (!focused && document->focusedNode())
document->focusedNode()->dispatchBlurEvent();
document->dispatchWindowEvent(Event::create(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false));
@@ -72,14 +80,17 @@ FocusController::FocusController(Page* page)
: m_page(page)
, m_isActive(false)
, m_isFocused(false)
+ , m_isChangingFocusedFrame(false)
{
}
void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
{
- if (m_focusedFrame == frame)
+ if (m_focusedFrame == frame || m_isChangingFocusedFrame)
return;
+ m_isChangingFocusedFrame = true;
+
RefPtr<Frame> oldFrame = m_focusedFrame;
RefPtr<Frame> newFrame = frame;
@@ -95,6 +106,8 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
newFrame->selection()->setFocused(true);
newFrame->document()->dispatchWindowEvent(Event::create(eventNames().focusEvent, false, false));
}
+
+ m_isChangingFocusedFrame = false;
}
Frame* FocusController::focusedOrMainFrame()
@@ -148,6 +161,24 @@ bool FocusController::setInitialFocus(FocusDirection direction, KeyboardEvent* e
bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* event, bool initialFocus)
{
+ switch (direction) {
+ case FocusDirectionForward:
+ case FocusDirectionBackward:
+ return advanceFocusInDocumentOrder(direction, event, initialFocus);
+ case FocusDirectionLeft:
+ case FocusDirectionRight:
+ case FocusDirectionUp:
+ case FocusDirectionDown:
+ return advanceFocusDirectionally(direction, event);
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return false;
+}
+
+bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, KeyboardEvent* event, bool initialFocus)
+{
Frame* frame = focusedOrMainFrame();
ASSERT(frame);
Document* document = frame->document();
@@ -252,6 +283,140 @@ bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* even
return true;
}
+bool FocusController::advanceFocusDirectionally(FocusDirection direction, KeyboardEvent* event)
+{
+ Frame* frame = focusedOrMainFrame();
+ ASSERT(frame);
+ Document* focusedDocument = frame->document();
+ if (!focusedDocument)
+ return false;
+
+ Node* focusedNode = focusedDocument->focusedNode();
+ if (!focusedNode) {
+ // Just move to the first focusable node.
+ FocusDirection tabDirection = (direction == FocusDirectionUp || direction == FocusDirectionLeft) ?
+ FocusDirectionForward : FocusDirectionBackward;
+ // 'initialFocus' is set to true so the chrome is not focused.
+ return advanceFocusInDocumentOrder(tabDirection, event, true);
+ }
+
+ // Move up in the chain of nested frames.
+ frame = frame->tree()->top();
+
+ FocusCandidate focusCandidate;
+ findFocusableNodeInDirection(frame->document(), focusedNode, direction, event, focusCandidate);
+
+ Node* node = focusCandidate.node;
+ if (!node || !node->isElementNode()) {
+ // FIXME: May need a way to focus a document here.
+ Frame* frame = focusedOrMainFrame();
+ scrollInDirection(frame, direction);
+ return false;
+ }
+
+ // In order to avoid crazy jump between links that are either far away from each other,
+ // or just not currently visible, lets do a scroll in the given direction and bail out
+ // if |node| element is not in the viewport.
+ if (hasOffscreenRect(node)) {
+ Frame* frame = node->document()->view()->frame();
+ scrollInDirection(frame, direction);
+ return true;
+ }
+
+ Document* newDocument = node->document();
+
+ if (newDocument != focusedDocument) {
+ // Focus is going away from the originally focused document, so clear the focused node.
+ focusedDocument->setFocusedNode(0);
+ }
+
+ if (newDocument)
+ setFocusedFrame(newDocument->frame());
+
+ Element* element = static_cast<Element*>(node);
+ ASSERT(element);
+
+ scrollIntoView(element);
+ element->focus(false);
+ return true;
+}
+
+static void updateFocusCandidateIfCloser(Node* focusedNode, Node* candidate, long long distance, FocusCandidate& closestFocusCandidate)
+{
+ // Bail out if |distance| is bigger than the current closest candidate.
+ if (distance >= closestFocusCandidate.distance)
+ return;
+
+ // If |focusedNode| and |candidate| are in the same document AND
+ // current |closestFocusCandidadte| is not in an {i}frame that is
+ // preferable to get focused.
+ if (focusedNode->document() == candidate->document()
+ && distance < closestFocusCandidate.parentDistance) {
+ closestFocusCandidate.node = candidate;
+ closestFocusCandidate.distance = distance;
+ closestFocusCandidate.parentDistance = maxDistance();
+ } else if (focusedNode->document() != candidate->document()) {
+ // If the |focusedNode| is in an inner document and the |candidate| is
+ // in a different document, we only consider to change focus if there is
+ // not another already good focusable candidate in the same document as
+ // |focusedNode|.
+ if (!((isInRootDocument(candidate) && !isInRootDocument(focusedNode))
+ && focusedNode->document() == closestFocusCandidate.document())) {
+ closestFocusCandidate.node = candidate;
+ closestFocusCandidate.distance = distance;
+ }
+ }
+}
+
+void FocusController::findFocusableNodeInDirection(Document* document, Node* focusedNode, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closestFocusCandidate)
+{
+ ASSERT(document);
+
+ // Walk all the child nodes and update focusCandidate if we find a nearer node.
+ for (Node* candidate = document->firstChild(); candidate; candidate = candidate->traverseNextNode()) {
+ // Inner documents case.
+ if (candidate->isFrameOwnerElement())
+ deepFindFocusableNodeInDirection(focusedNode, candidate, direction, event, closestFocusCandidate);
+ else if (candidate != focusedNode && candidate->isKeyboardFocusable(event)) {
+ long long distance = distanceInDirection(focusedNode, candidate,
+ direction, closestFocusCandidate);
+ updateFocusCandidateIfCloser(focusedNode, candidate, distance, closestFocusCandidate);
+ }
+ }
+}
+
+void FocusController::deepFindFocusableNodeInDirection(Node* focusedNode, Node* candidate, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closestFocusCandidate)
+{
+ HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(candidate);
+ if (!owner->contentFrame())
+ return;
+
+ Document* innerDocument = owner->contentFrame()->document();
+ if (!innerDocument)
+ return;
+
+ if (innerDocument == focusedNode->document())
+ findFocusableNodeInDirection(innerDocument, focusedNode, direction, event, closestFocusCandidate);
+ else {
+ // Check if the current {i}frame element itself is a good candidate
+ // to move focus to. If it is, then we traverse its inner nodes.
+ // Lets pass a copy of the best candidate, to not get fooled by a
+ // frame without focusable elements.
+ FocusCandidate focusCandidateCopy = closestFocusCandidate;
+ long long distance = distanceInDirection(focusedNode, candidate, direction, focusCandidateCopy);
+ if (distance < focusCandidateCopy.distance) {
+ focusCandidateCopy.parentAlignment = focusCandidateCopy.alignment;
+ focusCandidateCopy.parentDistance = distance;
+
+ findFocusableNodeInDirection(innerDocument, focusedNode, direction, event, focusCandidateCopy);
+
+ // If we really have an inner closer focus candidate node, take it.
+ if (closestFocusCandidate.node != focusCandidateCopy.node)
+ closestFocusCandidate = focusCandidateCopy;
+ }
+ }
+}
+
static bool relinquishesEditingFocus(Node *node)
{
ASSERT(node);
diff --git a/src/3rdparty/webkit/WebCore/page/FocusController.h b/src/3rdparty/webkit/WebCore/page/FocusController.h
index 33debf1..75591c7 100644
--- a/src/3rdparty/webkit/WebCore/page/FocusController.h
+++ b/src/3rdparty/webkit/WebCore/page/FocusController.h
@@ -28,40 +28,50 @@
#include "FocusDirection.h"
#include <wtf/Forward.h>
+#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
namespace WebCore {
- class Frame;
- class KeyboardEvent;
- class Node;
- class Page;
+class Document;
+class Frame;
+class KeyboardEvent;
+class Node;
+class Page;
+struct FocusCandidate;
- class FocusController {
- public:
- FocusController(Page*);
+class FocusController : public Noncopyable {
+public:
+ FocusController(Page*);
- void setFocusedFrame(PassRefPtr<Frame>);
- Frame* focusedFrame() const { return m_focusedFrame.get(); }
- Frame* focusedOrMainFrame();
+ void setFocusedFrame(PassRefPtr<Frame>);
+ Frame* focusedFrame() const { return m_focusedFrame.get(); }
+ Frame* focusedOrMainFrame();
- bool setInitialFocus(FocusDirection, KeyboardEvent*);
- bool advanceFocus(FocusDirection, KeyboardEvent*, bool initialFocus = false);
+ bool setInitialFocus(FocusDirection, KeyboardEvent*);
+ bool advanceFocus(FocusDirection, KeyboardEvent*, bool initialFocus = false);
- bool setFocusedNode(Node*, PassRefPtr<Frame>);
+ bool setFocusedNode(Node*, PassRefPtr<Frame>);
- void setActive(bool);
- bool isActive() const { return m_isActive; }
+ void setActive(bool);
+ bool isActive() const { return m_isActive; }
- void setFocused(bool);
- bool isFocused() const { return m_isFocused; }
+ void setFocused(bool);
+ bool isFocused() const { return m_isFocused; }
- private:
- Page* m_page;
- RefPtr<Frame> m_focusedFrame;
- bool m_isActive;
- bool m_isFocused;
- };
+private:
+ bool advanceFocusDirectionally(FocusDirection, KeyboardEvent*);
+ bool advanceFocusInDocumentOrder(FocusDirection, KeyboardEvent*, bool initialFocus);
+
+ void findFocusableNodeInDirection(Document*, Node*, FocusDirection, KeyboardEvent*, FocusCandidate&);
+ void deepFindFocusableNodeInDirection(Node*, Node*, FocusDirection, KeyboardEvent*, FocusCandidate&);
+
+ Page* m_page;
+ RefPtr<Frame> m_focusedFrame;
+ bool m_isActive;
+ bool m_isFocused;
+ bool m_isChangingFocusedFrame;
+};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/FocusDirection.h b/src/3rdparty/webkit/WebCore/page/FocusDirection.h
index 261c745..8a6d51f 100644
--- a/src/3rdparty/webkit/WebCore/page/FocusDirection.h
+++ b/src/3rdparty/webkit/WebCore/page/FocusDirection.h
@@ -28,8 +28,13 @@
namespace WebCore {
enum FocusDirection {
- FocusDirectionForward = 0,
- FocusDirectionBackward
+ FocusDirectionNone = 0,
+ FocusDirectionForward,
+ FocusDirectionBackward,
+ FocusDirectionUp,
+ FocusDirectionDown,
+ FocusDirectionLeft,
+ FocusDirectionRight
};
}
diff --git a/src/3rdparty/webkit/WebCore/page/Frame.cpp b/src/3rdparty/webkit/WebCore/page/Frame.cpp
index fab7e3f..614bbb9 100644
--- a/src/3rdparty/webkit/WebCore/page/Frame.cpp
+++ b/src/3rdparty/webkit/WebCore/page/Frame.cpp
@@ -36,6 +36,7 @@
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CachedCSSStyleSheet.h"
+#include "Chrome.h"
#include "DOMWindow.h"
#include "DocLoader.h"
#include "DocumentType.h"
@@ -74,6 +75,7 @@
#include "TextIterator.h"
#include "TextResourceDecoder.h"
#include "UserContentURLPattern.h"
+#include "XMLNSNames.h"
#include "XMLNames.h"
#include "htmlediting.h"
#include "markup.h"
@@ -102,6 +104,10 @@
#include "MathMLNames.h"
#endif
+#if ENABLE(TILED_BACKING_STORE)
+#include "TiledBackingStore.h"
+#endif
+
using namespace std;
namespace WebCore {
@@ -126,9 +132,7 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
, m_redirectScheduler(this)
, m_ownerElement(ownerElement)
, m_script(this)
- , m_selectionGranularity(CharacterGranularity)
, m_selectionController(this)
- , m_caretBlinkTimer(this, &Frame::caretBlinkTimerFired)
, m_editor(this)
, m_eventHandler(this)
, m_animationController(this)
@@ -136,8 +140,6 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
#if ENABLE(ORIENTATION_EVENTS)
, m_orientation(0)
#endif
- , m_caretVisible(false)
- , m_caretPaint(true)
, m_highlightTextMatches(false)
, m_inViewSourceMode(false)
, m_needsReapplyStyles(false)
@@ -165,11 +167,16 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
MathMLNames::init();
#endif
+ XMLNSNames::init();
XMLNames::init();
- if (!ownerElement)
+ if (!ownerElement) {
page->setMainFrame(this);
- else {
+#if ENABLE(TILED_BACKING_STORE)
+ // Top level frame only for now.
+ setTiledBackingStoreEnabled(page->settings()->tiledBackingStoreEnabled());
+#endif
+ } else {
page->incrementFrameCount();
// Make sure we will not end up with two frames referencing the same owner element.
ASSERT((!(ownerElement->m_contentFrame)) || (ownerElement->m_contentFrame->ownerElement() != ownerElement));
@@ -257,6 +264,11 @@ void Frame::setView(PassRefPtr<FrameView> view)
// Since this part may be getting reused as a result of being
// pulled from the back/forward cache, reset this flag.
loader()->resetMultipleFormSubmissionProtection();
+
+#if ENABLE(TILED_BACKING_STORE)
+ if (m_view && tiledBackingStore())
+ m_view->setPaintsEntireContents(true);
+#endif
}
ScriptController* Frame::script()
@@ -277,8 +289,7 @@ void Frame::setDocument(PassRefPtr<Document> newDoc)
}
m_doc = newDoc;
- if (m_doc && selection()->isFocusedAndActive())
- setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
+ selection()->updateSecureKeyboardEntryIfActive();
if (m_doc && !m_doc->attached())
m_doc->attach();
@@ -292,7 +303,7 @@ void Frame::sendOrientationChangeEvent(int orientation)
{
m_orientation = orientation;
if (Document* doc = document())
- doc->dispatchWindowEvent(eventNames().orientationchangeEvent, false, false);
+ doc->dispatchWindowEvent(Event::create(eventNames().orientationchangeEvent, false, false));
}
#endif // ENABLE(ORIENTATION_EVENTS)
@@ -358,12 +369,7 @@ Editor* Frame::editor() const
TextGranularity Frame::selectionGranularity() const
{
- return m_selectionGranularity;
-}
-
-void Frame::setSelectionGranularity(TextGranularity granularity)
-{
- m_selectionGranularity = granularity;
+ return m_selectionController.granularity();
}
SelectionController* Frame::dragCaretController() const
@@ -411,7 +417,7 @@ static RegularExpression* createRegExpForLabels(const Vector<String>& labels)
return new RegularExpression(pattern, TextCaseInsensitive);
}
-String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell)
+String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell, size_t* resultDistanceFromStartOfCell)
{
RenderObject* cellRenderer = cell->renderer();
@@ -425,23 +431,30 @@ String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellE
if (aboveCell) {
// search within the above cell we found for a match
+ size_t lengthSearched = 0;
for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) {
if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
// For each text chunk, run the regexp
String nodeString = n->nodeValue();
int pos = regExp->searchRev(nodeString);
- if (pos >= 0)
+ if (pos >= 0) {
+ if (resultDistanceFromStartOfCell)
+ *resultDistanceFromStartOfCell = lengthSearched;
return nodeString.substring(pos, regExp->matchedLength());
+ }
+ lengthSearched += nodeString.length();
}
}
}
}
}
// Any reason in practice to search all cells in that are above cell?
+ if (resultDistanceFromStartOfCell)
+ *resultDistanceFromStartOfCell = notFound;
return String();
}
-String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element)
+String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element, size_t* resultDistance, bool* resultIsInCellAbove)
{
OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
// We stop searching after we've seen this many chars
@@ -453,6 +466,11 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
HTMLTableCellElement* startingTableCell = 0;
bool searchedCellAbove = false;
+ if (resultDistance)
+ *resultDistance = notFound;
+ if (resultIsInCellAbove)
+ *resultIsInCellAbove = false;
+
// walk backwards in the node tree, until another element, or form, or end of tree
int unsigned lengthSearched = 0;
Node* n;
@@ -468,9 +486,12 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
} else if (n->hasTagName(tdTag) && !startingTableCell) {
startingTableCell = static_cast<HTMLTableCellElement*>(n);
} else if (n->hasTagName(trTag) && startingTableCell) {
- String result = searchForLabelsAboveCell(regExp.get(), startingTableCell);
- if (!result.isEmpty())
+ String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
+ if (!result.isEmpty()) {
+ if (resultIsInCellAbove)
+ *resultIsInCellAbove = true;
return result;
+ }
searchedCellAbove = true;
} else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
// For each text chunk, run the regexp
@@ -479,38 +500,48 @@ String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element
if (lengthSearched + nodeString.length() > maxCharsSearched)
nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
int pos = regExp->searchRev(nodeString);
- if (pos >= 0)
+ if (pos >= 0) {
+ if (resultDistance)
+ *resultDistance = lengthSearched;
return nodeString.substring(pos, regExp->matchedLength());
+ }
lengthSearched += nodeString.length();
}
}
// If we started in a cell, but bailed because we found the start of the form or the
// previous element, we still might need to search the row above us for a label.
- if (startingTableCell && !searchedCellAbove)
- return searchForLabelsAboveCell(regExp.get(), startingTableCell);
+ if (startingTableCell && !searchedCellAbove) {
+ String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
+ if (!result.isEmpty()) {
+ if (resultIsInCellAbove)
+ *resultIsInCellAbove = true;
+ return result;
+ }
+ }
return String();
}
-String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element)
+static String matchLabelsAgainstString(const Vector<String>& labels, const String& stringToMatch)
{
- String name = element->getAttribute(nameAttr);
- if (name.isEmpty())
+ if (stringToMatch.isEmpty())
return String();
- // Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
- replace(name, RegularExpression("\\d", TextCaseSensitive), " ");
- name.replace('_', ' ');
+ String mutableStringToMatch = stringToMatch;
+ // Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
+ replace(mutableStringToMatch, RegularExpression("\\d", TextCaseSensitive), " ");
+ mutableStringToMatch.replace('_', ' ');
+
OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
- // Use the largest match we can find in the whole name string
+ // Use the largest match we can find in the whole string
int pos;
int length;
int bestPos = -1;
int bestLength = -1;
int start = 0;
do {
- pos = regExp->match(name, start);
+ pos = regExp->match(mutableStringToMatch, start);
if (pos != -1) {
length = regExp->matchedLength();
if (length >= bestLength) {
@@ -520,11 +551,24 @@ String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* e
start = pos + 1;
}
} while (pos != -1);
-
+
if (bestPos != -1)
- return name.substring(bestPos, bestLength);
+ return mutableStringToMatch.substring(bestPos, bestLength);
return String();
}
+
+String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element)
+{
+ // Match against the name element, then against the id element if no match is found for the name element.
+ // See 7538330 for one popular site that benefits from the id element check.
+ // FIXME: This code is mirrored in FrameMac.mm. It would be nice to make the Mac code call the platform-agnostic
+ // code, which would require converting the NSArray of NSStrings to a Vector of Strings somewhere along the way.
+ String resultFromNameAttribute = matchLabelsAgainstString(labels, element->getAttribute(nameAttr));
+ if (!resultFromNameAttribute.isEmpty())
+ return resultFromNameAttribute;
+
+ return matchLabelsAgainstString(labels, element->getAttribute(idAttr));
+}
const VisibleSelection& Frame::mark() const
{
@@ -552,31 +596,6 @@ void Frame::notifyRendererOfSelectionChange(bool userTriggered)
toRenderTextControl(renderer)->selectionChanged(userTriggered);
}
-void Frame::invalidateSelection()
-{
- selection()->setNeedsLayout();
- selectionLayoutChanged();
-}
-
-void Frame::setCaretVisible(bool flag)
-{
- if (m_caretVisible == flag)
- return;
- clearCaretRectIfNeeded();
- m_caretVisible = flag;
- selectionLayoutChanged();
-}
-
-void Frame::clearCaretRectIfNeeded()
-{
-#if ENABLE(TEXT_CARET)
- if (m_caretPaint) {
- m_caretPaint = false;
- selection()->invalidateCaretRect();
- }
-#endif
-}
-
// Helper function that tells whether a particular node is an element that has an entire
// Frame and FrameView, a <frame>, <iframe>, or <object>.
static bool isFrameElement(const Node *n)
@@ -629,87 +648,6 @@ void Frame::setFocusedNodeIfNeeded()
page()->focusController()->setFocusedNode(0, this);
}
-void Frame::selectionLayoutChanged()
-{
- bool caretRectChanged = selection()->recomputeCaretRect();
-
-#if ENABLE(TEXT_CARET)
- bool caretBrowsing = settings() && settings()->caretBrowsingEnabled();
- bool shouldBlink = m_caretVisible
- && selection()->isCaret() && (selection()->isContentEditable() || caretBrowsing);
-
- // If the caret moved, stop the blink timer so we can restart with a
- // black caret in the new location.
- if (caretRectChanged || !shouldBlink)
- m_caretBlinkTimer.stop();
-
- // Start blinking with a black caret. Be sure not to restart if we're
- // already blinking in the right location.
- if (shouldBlink && !m_caretBlinkTimer.isActive()) {
- if (double blinkInterval = page()->theme()->caretBlinkInterval())
- m_caretBlinkTimer.startRepeating(blinkInterval);
-
- if (!m_caretPaint) {
- m_caretPaint = true;
- selection()->invalidateCaretRect();
- }
- }
-#else
- if (!caretRectChanged)
- return;
-#endif
-
- RenderView* view = contentRenderer();
- if (!view)
- return;
-
- VisibleSelection selection = this->selection()->selection();
-
- if (!selection.isRange())
- view->clearSelection();
- else {
- // Use the rightmost candidate for the start of the selection, and the leftmost candidate for the end of the selection.
- // Example: foo <a>bar</a>. Imagine that a line wrap occurs after 'foo', and that 'bar' is selected. If we pass [foo, 3]
- // as the start of the selection, the selection painting code will think that content on the line containing 'foo' is selected
- // and will fill the gap before 'bar'.
- Position startPos = selection.start();
- if (startPos.downstream().isCandidate())
- startPos = startPos.downstream();
- Position endPos = selection.end();
- if (endPos.upstream().isCandidate())
- endPos = endPos.upstream();
-
- // We can get into a state where the selection endpoints map to the same VisiblePosition when a selection is deleted
- // because we don't yet notify the SelectionController of text removal.
- if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
- RenderObject *startRenderer = startPos.node()->renderer();
- RenderObject *endRenderer = endPos.node()->renderer();
- view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset());
- }
- }
-}
-
-void Frame::caretBlinkTimerFired(Timer<Frame>*)
-{
-#if ENABLE(TEXT_CARET)
- ASSERT(m_caretVisible);
- ASSERT(selection()->isCaret());
- bool caretPaint = m_caretPaint;
- if (selection()->isCaretBlinkingSuspended() && caretPaint)
- return;
- m_caretPaint = !caretPaint;
- selection()->invalidateCaretRect();
-#endif
-}
-
-void Frame::paintCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
-{
-#if ENABLE(TEXT_CARET)
- if (m_caretPaint && m_caretVisible)
- selection()->paintCaret(p, tx, ty, clipRect);
-#endif
-}
-
void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
{
#if ENABLE(TEXT_CARET)
@@ -725,59 +663,51 @@ float Frame::zoomFactor() const
return m_zoomFactor;
}
-bool Frame::isZoomFactorTextOnly() const
+ZoomMode Frame::zoomMode() const
{
- return m_page->settings()->zoomsTextOnly();
+ return m_page->settings()->zoomMode();
}
bool Frame::shouldApplyTextZoom() const
{
- if (m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
- return false;
-#if ENABLE(SVG)
- if (m_doc->isSVGDocument())
- return false;
-#endif
- return true;
+ return m_zoomFactor != 1.0f && zoomMode() == ZoomTextOnly;
}
bool Frame::shouldApplyPageZoom() const
{
- if (m_zoomFactor == 1.0f || isZoomFactorTextOnly())
- return false;
-#if ENABLE(SVG)
- if (m_doc->isSVGDocument())
- return false;
-#endif
- return true;
+ return m_zoomFactor != 1.0f && zoomMode() == ZoomPage;
}
-void Frame::setZoomFactor(float percent, bool isTextOnly)
+void Frame::setZoomFactor(float percent, ZoomMode mode)
{
- if (m_zoomFactor == percent && isZoomFactorTextOnly() == isTextOnly)
+ if (m_zoomFactor == percent && zoomMode() == mode)
return;
#if ENABLE(SVG)
- // SVG doesn't care if the zoom factor is text only. It will always apply a
- // zoom to the whole SVG.
+ // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
+ // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
if (m_doc->isSVGDocument()) {
if (!static_cast<SVGDocument*>(m_doc.get())->zoomAndPanEnabled())
return;
- m_zoomFactor = percent;
- m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom.
if (m_doc->renderer())
- m_doc->renderer()->repaint();
- return;
+ m_doc->renderer()->setNeedsLayout(true);
}
#endif
+ if (mode == ZoomPage) {
+ // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
+ IntPoint scrollPosition = view()->scrollPosition();
+ float percentDifference = (percent / m_zoomFactor);
+ view()->setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference));
+ }
+
m_zoomFactor = percent;
- m_page->settings()->setZoomsTextOnly(isTextOnly);
+ m_page->settings()->setZoomMode(mode);
m_doc->recalcStyle(Node::Force);
for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
- child->setZoomFactor(m_zoomFactor, isTextOnly);
+ child->setZoomFactor(m_zoomFactor, mode);
if (m_doc->renderer() && m_doc->renderer()->needsLayout() && view()->didFirstLayout())
view()->layout();
@@ -786,7 +716,8 @@ void Frame::setZoomFactor(float percent, bool isTextOnly)
void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
{
m_doc->setPrinting(printing);
- view()->setMediaType(printing ? "print" : "screen");
+ view()->adjustMediaTypeForPrinting(printing);
+
m_doc->updateStyleSelector();
view()->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize);
@@ -870,10 +801,10 @@ void Frame::injectUserScripts(UserScriptInjectionTime injectionTime)
return;
UserScriptMap::const_iterator end = userScripts->end();
for (UserScriptMap::const_iterator it = userScripts->begin(); it != end; ++it)
- injectUserScriptsForWorld(it->first, *it->second, injectionTime);
+ injectUserScriptsForWorld(it->first.get(), *it->second, injectionTime);
}
-void Frame::injectUserScriptsForWorld(unsigned worldID, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime)
+void Frame::injectUserScriptsForWorld(DOMWrapperWorld* world, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime)
{
if (userScripts.isEmpty())
return;
@@ -887,9 +818,8 @@ void Frame::injectUserScriptsForWorld(unsigned worldID, const UserScriptVector&
for (unsigned i = 0; i < count; ++i) {
UserScript* script = userScripts[i].get();
if (script->injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(doc->url(), script->whitelist(), script->blacklist()))
- sourceCode.append(ScriptSourceCode(script->source(), script->url()));
+ m_script.evaluateInWorld(ScriptSourceCode(script->source(), script->url()), world);
}
- script()->evaluateInIsolatedWorld(worldID, sourceCode);
}
bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const
@@ -915,20 +845,6 @@ bool Frame::isContentEditable() const
return m_doc->inDesignMode();
}
-#if !PLATFORM(MAC)
-
-void Frame::setUseSecureKeyboardEntry(bool)
-{
-}
-
-#endif
-
-void Frame::updateSecureKeyboardEntryIfActive()
-{
- if (selection()->isFocusedAndActive())
- setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
-}
-
CSSMutableStyleDeclaration *Frame::typingStyle() const
{
return m_typingStyle.get();
@@ -1240,7 +1156,7 @@ FloatRect Frame::selectionBounds(bool clipToVisibleContent) const
return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
}
-void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleContent) const
+void Frame::selectionTextRects(Vector<FloatRect>& rects, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent) const
{
RenderView* root = contentRenderer();
if (!root)
@@ -1248,19 +1164,36 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte
RefPtr<Range> selectedRange = selection()->toNormalizedRange();
- Vector<IntRect> intRects;
- selectedRange->textRects(intRects, true);
-
- unsigned size = intRects.size();
FloatRect visibleContentRect = m_view->visibleContentRect();
- for (unsigned i = 0; i < size; ++i)
- if (clipToVisibleContent)
- rects.append(intersection(intRects[i], visibleContentRect));
- else
- rects.append(intRects[i]);
+
+ // FIMXE: we are appending empty rects to the list for those that fall outside visibleContentRect.
+ // We may not want to do that.
+ if (respectTransforms) {
+ Vector<FloatQuad> quads;
+ selectedRange->textQuads(quads, true);
+
+ unsigned size = quads.size();
+ for (unsigned i = 0; i < size; ++i) {
+ IntRect currRect = quads[i].enclosingBoundingBox();
+ if (clipToVisibleContent)
+ rects.append(intersection(currRect, visibleContentRect));
+ else
+ rects.append(currRect);
+ }
+ } else {
+ Vector<IntRect> intRects;
+ selectedRange->textRects(intRects, true);
+
+ unsigned size = intRects.size();
+ for (unsigned i = 0; i < size; ++i) {
+ if (clipToVisibleContent)
+ rects.append(intersection(intRects[i], visibleContentRect));
+ else
+ rects.append(intRects[i]);
+ }
+ }
}
-
// Scans logically forward from "start", including any child frames
static HTMLFormElement *scanForForm(Node *start)
{
@@ -1523,12 +1456,6 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
continue;
}
- // A non-collapsed result range can in some funky whitespace cases still not
- // advance the range's start position (4509328). Break to avoid infinite loop.
- VisiblePosition newStart = endVisiblePosition(resultRange.get(), DOWNSTREAM);
- if (newStart == startVisiblePosition(searchRange.get(), DOWNSTREAM))
- break;
-
// Only treat the result as a match if it is visible
if (editor()->insideVisibleArea(resultRange.get())) {
++matchCount;
@@ -1539,7 +1466,12 @@ unsigned Frame::markAllMatchesForText(const String& target, bool caseFlag, unsig
if (limit > 0 && matchCount >= limit)
break;
- setStart(searchRange.get(), newStart);
+ // Set the new start for the search range to be the end of the previous
+ // result range. There is no need to use a VisiblePosition here,
+ // since findPlainText will use a TextIterator to go over the visible
+ // text nodes.
+ searchRange->setStart(resultRange->endContainer(exception), resultRange->endOffset(exception), exception);
+
Node* shadowTreeRoot = searchRange->shadowTreeRootNode();
if (searchRange->collapsed(exception) && shadowTreeRoot)
searchRange->setEnd(shadowTreeRoot, shadowTreeRoot->childNodeCount(), exception);
@@ -1646,6 +1578,54 @@ void Frame::disconnectOwnerElement()
m_ownerElement = 0;
}
+// The frame is moved in DOM, potentially to another page.
+void Frame::transferChildFrameToNewDocument()
+{
+ ASSERT(m_ownerElement);
+ Frame* newParent = m_ownerElement->document()->frame();
+ bool didTransfer = false;
+
+ // Switch page.
+ Page* newPage = newParent ? newParent->page() : 0;
+ if (m_page != newPage) {
+ if (page()->focusController()->focusedFrame() == this)
+ page()->focusController()->setFocusedFrame(0);
+
+ if (m_page)
+ m_page->decrementFrameCount();
+
+ m_page = newPage;
+
+ if (newPage)
+ newPage->incrementFrameCount();
+
+ didTransfer = true;
+ }
+
+ // Update the frame tree.
+ Frame* oldParent = tree()->parent();
+ if (oldParent != newParent) {
+ if (oldParent)
+ oldParent->tree()->removeChild(this);
+ if (newParent) {
+ newParent->tree()->appendChild(this);
+ m_ownerElement->setName();
+ }
+ didTransfer = true;
+ }
+
+ // Avoid unnecessary calls to client and frame subtree if the frame ended
+ // up on the same page and under the same parent frame.
+ if (didTransfer) {
+ // Let external clients update themselves.
+ loader()->client()->didTransferChildFrameToNewDocument();
+
+ // Do the same for all the children.
+ for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
+ child->transferChildFrameToNewDocument();
+ }
+}
+
String Frame::documentTypeString() const
{
if (DocumentType* doctype = document()->doctype())
@@ -1827,4 +1807,51 @@ void Frame::createView(const IntSize& viewportSize,
view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
}
+#if ENABLE(TILED_BACKING_STORE)
+void Frame::setTiledBackingStoreEnabled(bool enabled)
+{
+ if (!enabled) {
+ m_tiledBackingStore.clear();
+ return;
+ }
+ if (m_tiledBackingStore)
+ return;
+ m_tiledBackingStore.set(new TiledBackingStore(this));
+ if (m_view)
+ m_view->setPaintsEntireContents(true);
+}
+
+void Frame::tiledBackingStorePaintBegin()
+{
+ if (!m_view)
+ return;
+ m_view->layoutIfNeededRecursive();
+ m_view->flushDeferredRepaints();
+}
+
+void Frame::tiledBackingStorePaint(GraphicsContext* context, const IntRect& rect)
+{
+ if (!m_view)
+ return;
+ m_view->paintContents(context, rect);
+}
+
+void Frame::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea)
+{
+ if (!m_page || !m_view)
+ return;
+ unsigned size = paintedArea.size();
+ // Request repaint from the system
+ for (int n = 0; n < size; ++n)
+ m_page->chrome()->invalidateContentsAndWindow(m_view->contentsToWindow(paintedArea[n]), false);
+}
+
+IntRect Frame::tiledBackingStoreContentsRect()
+{
+ if (!m_view)
+ return IntRect();
+ return IntRect(IntPoint(), m_view->contentsSize());
+}
+#endif
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/Frame.h b/src/3rdparty/webkit/WebCore/page/Frame.h
index 6208bbd..65bdeb0 100644
--- a/src/3rdparty/webkit/WebCore/page/Frame.h
+++ b/src/3rdparty/webkit/WebCore/page/Frame.h
@@ -29,24 +29,25 @@
#define Frame_h
#include "AnimationController.h"
-#include "Document.h"
#include "DragImage.h"
-#include "EditAction.h"
#include "Editor.h"
#include "EventHandler.h"
#include "FrameLoader.h"
#include "FrameTree.h"
-#include "Range.h"
#include "ScriptController.h"
#include "ScrollBehavior.h"
#include "SelectionController.h"
-#include "TextGranularity.h"
#include "UserScriptTypes.h"
+#include "ZoomMode.h"
#if PLATFORM(WIN)
#include "FrameWin.h"
#endif
+#if ENABLE(TILED_BACKING_STORE)
+#include "TiledBackingStoreClient.h"
+#endif
+
#if PLATFORM(MAC)
#ifndef __OBJC__
class NSArray;
@@ -64,26 +65,16 @@ typedef struct HBITMAP__* HBITMAP;
namespace WebCore {
class CSSMutableStyleDeclaration;
- class Editor;
- class EventHandler;
- class FrameLoader;
- class RedirectScheduler;
- class FrameLoaderClient;
- class FrameTree;
- class FrameView;
- class HTMLFrameOwnerElement;
class HTMLTableCellElement;
class RegularExpression;
class RenderPart;
- class ScriptController;
- class SelectionController;
- class Settings;
- class VisibleSelection;
- class Widget;
-
- template <typename T> class Timer;
+ class TiledBackingStore;
- class Frame : public RefCounted<Frame> {
+ class Frame : public RefCounted<Frame>
+#if ENABLE(TILED_BACKING_STORE)
+ , public TiledBackingStoreClient
+#endif
+ {
public:
static PassRefPtr<Frame> create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
{
@@ -96,6 +87,8 @@ namespace WebCore {
Page* page() const;
void detachFromPage();
+ void transferChildFrameToNewDocument();
+
HTMLFrameOwnerElement* ownerElement() const;
void pageDestroyed();
@@ -131,7 +124,7 @@ namespace WebCore {
void injectUserScripts(UserScriptInjectionTime);
private:
- void injectUserScriptsForWorld(unsigned worldID, const UserScriptVector&, UserScriptInjectionTime);
+ void injectUserScriptsForWorld(DOMWrapperWorld*, const UserScriptVector&, UserScriptInjectionTime);
private:
Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
@@ -181,15 +174,20 @@ namespace WebCore {
return document() ? document()->displayStringModifiedByEncoding(str) : str;
}
+#if ENABLE(TILED_BACKING_STORE)
+ TiledBackingStore* tiledBackingStore() const { return m_tiledBackingStore.get(); }
+ void setTiledBackingStoreEnabled(bool);
+#endif
+
private:
void lifeSupportTimerFired(Timer<Frame>*);
// === to be moved into FrameView
public:
- void setZoomFactor(float scale, bool isTextOnly);
+ void setZoomFactor(float scale, ZoomMode);
float zoomFactor() const;
- bool isZoomFactorTextOnly() const;
+ ZoomMode zoomMode() const;
bool shouldApplyTextZoom() const;
bool shouldApplyPageZoom() const;
float pageZoomFactor() const { return shouldApplyPageZoom() ? zoomFactor() : 1.0f; }
@@ -250,59 +248,54 @@ namespace WebCore {
public:
TextGranularity selectionGranularity() const;
- void setSelectionGranularity(TextGranularity);
bool shouldChangeSelection(const VisibleSelection&) const;
bool shouldDeleteSelection(const VisibleSelection&) const;
- void clearCaretRectIfNeeded();
void setFocusedNodeIfNeeded();
- void selectionLayoutChanged();
void notifyRendererOfSelectionChange(bool userTriggered);
- void invalidateSelection();
-
- void setCaretVisible(bool = true);
- void paintCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const;
void paintDragCaret(GraphicsContext*, int tx, int ty, const IntRect& clipRect) const;
bool isContentEditable() const; // if true, everything in frame is editable
- void updateSecureKeyboardEntryIfActive();
-
CSSMutableStyleDeclaration* typingStyle() const;
void setTypingStyle(CSSMutableStyleDeclaration*);
void clearTypingStyle();
FloatRect selectionBounds(bool clipToVisibleContent = true) const;
- void selectionTextRects(Vector<FloatRect>&, bool clipToVisibleContent = true) const;
+ enum SelectionRectRespectTransforms { RespectTransforms = true, IgnoreTransforms = false };
+ void selectionTextRects(Vector<FloatRect>&, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent = true) const;
HTMLFormElement* currentForm() const;
void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);
void setSelectionFromNone();
- void setUseSecureKeyboardEntry(bool);
-
- private:
- void caretBlinkTimerFired(Timer<Frame>*);
-
- public:
SelectionController* dragCaretController() const;
- String searchForLabelsAboveCell(RegularExpression*, HTMLTableCellElement*);
- String searchForLabelsBeforeElement(const Vector<String>& labels, Element*);
+ String searchForLabelsAboveCell(RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell);
+ String searchForLabelsBeforeElement(const Vector<String>& labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove);
String matchLabelsAgainstElement(const Vector<String>& labels, Element*);
VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
Document* documentAtPoint(const IntPoint& windowPoint);
+
+ private:
+#if ENABLE(TILED_BACKING_STORE)
+ // TiledBackingStoreClient interface
+ virtual void tiledBackingStorePaintBegin();
+ virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&);
+ virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea);
+ virtual IntRect tiledBackingStoreContentsRect();
+#endif
#if PLATFORM(MAC)
// === undecided, would like to consider moving to another class
public:
- NSString* searchForNSLabelsAboveCell(RegularExpression*, HTMLTableCellElement*);
- NSString* searchForLabelsBeforeElement(NSArray* labels, Element*);
+ NSString* searchForNSLabelsAboveCell(RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell);
+ NSString* searchForLabelsBeforeElement(NSArray* labels, Element*, size_t* resultDistance, bool* resultIsInCellAbove);
NSString* matchLabelsAgainstElement(NSArray* labels, Element*);
#if ENABLE(DASHBOARD_SUPPORT)
@@ -352,11 +345,8 @@ namespace WebCore {
float m_zoomFactor;
- TextGranularity m_selectionGranularity;
-
mutable SelectionController m_selectionController;
mutable VisibleSelection m_mark;
- Timer<Frame> m_caretBlinkTimer;
mutable Editor m_editor;
mutable EventHandler m_eventHandler;
mutable AnimationController m_animationController;
@@ -368,15 +358,16 @@ namespace WebCore {
#if ENABLE(ORIENTATION_EVENTS)
int m_orientation;
#endif
-
- bool m_caretVisible;
- bool m_caretPaint;
bool m_highlightTextMatches;
bool m_inViewSourceMode;
bool m_needsReapplyStyles;
bool m_isDisconnected;
bool m_excludeFromTextSearch;
+
+#if ENABLE(TILED_BACKING_STORE)
+ OwnPtr<TiledBackingStore> m_tiledBackingStore;
+#endif
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/FrameTree.cpp b/src/3rdparty/webkit/WebCore/page/FrameTree.cpp
index 41caa9c..d6170e1 100644
--- a/src/3rdparty/webkit/WebCore/page/FrameTree.cpp
+++ b/src/3rdparty/webkit/WebCore/page/FrameTree.cpp
@@ -25,7 +25,6 @@
#include "Page.h"
#include "PageGroup.h"
#include <stdarg.h>
-#include <wtf/Platform.h>
#include <wtf/StringExtras.h>
#include <wtf/Vector.h>
diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp
index 4c3a0ab..45764de 100644
--- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp
+++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp
@@ -29,6 +29,7 @@
#include "AXObjectCache.h"
#include "CSSStyleSelector.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "DocLoader.h"
#include "EventHandler.h"
@@ -45,8 +46,8 @@
#include "HTMLNames.h"
#include "InspectorTimelineAgent.h"
#include "OverflowEvent.h"
+#include "RenderEmbeddedObject.h"
#include "RenderPart.h"
-#include "RenderPartObject.h"
#include "RenderScrollbar.h"
#include "RenderScrollbarPart.h"
#include "RenderTheme.h"
@@ -69,6 +70,9 @@
#include "SVGViewSpec.h"
#endif
+#if ENABLE(TILED_BACKING_STORE)
+#include "TiledBackingStore.h"
+#endif
namespace WebCore {
@@ -98,13 +102,14 @@ static const double deferredRepaintDelayIncrementDuringLoading = 0;
// The maximum number of updateWidgets iterations that should be done before returning.
static const unsigned maxUpdateWidgetsIterations = 2;
-struct ScheduledEvent {
+struct ScheduledEvent : Noncopyable {
RefPtr<Event> m_event;
RefPtr<Node> m_eventTarget;
};
FrameView::FrameView(Frame* frame)
: m_frame(frame)
+ , m_canHaveScrollbars(true)
, m_slowRepaintObjectCount(0)
, m_fixedObjectCount(0)
, m_layoutTimer(this, &FrameView::layoutTimerFired)
@@ -198,7 +203,7 @@ void FrameView::reset()
m_deferredRepaintDelay = initialDeferredRepaintDelayDuringLoading;
m_deferredRepaintTimer.stop();
m_lastPaintTime = 0;
- m_paintRestriction = PaintRestrictionNone;
+ m_paintBehavior = PaintBehaviorNormal;
m_isPainting = false;
m_isVisuallyNonEmpty = false;
m_firstVisuallyNonEmptyLayoutCallbackPending = true;
@@ -220,7 +225,10 @@ void FrameView::resetScrollbars()
// Reset the document's scrollbars back to our defaults before we yield the floor.
m_firstLayout = true;
setScrollbarsSuppressed(true);
- setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
+ if (m_canHaveScrollbars)
+ setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
+ else
+ setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff);
setScrollbarsSuppressed(false);
}
@@ -288,7 +296,7 @@ void FrameView::invalidateRect(const IntRect& rect)
{
if (!parent()) {
if (hostWindow())
- hostWindow()->repaint(rect, true);
+ hostWindow()->invalidateContentsAndWindow(rect, false /*immediate*/);
return;
}
@@ -317,6 +325,40 @@ void FrameView::setMarginHeight(int h)
m_margins.setHeight(h);
}
+bool FrameView::avoidScrollbarCreation()
+{
+ ASSERT(m_frame);
+
+ // with frame flattening no subframe can have scrollbars
+ // but we also cannot turn scrollbars of as we determine
+ // our flattening policy using that.
+
+ if (!m_frame->ownerElement())
+ return false;
+
+ if (!m_frame->settings() || m_frame->settings()->frameFlatteningEnabled())
+ return true;
+
+ return false;
+}
+
+void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
+{
+ m_canHaveScrollbars = canHaveScrollbars;
+ ScrollView::setCanHaveScrollbars(canHaveScrollbars);
+}
+
+void FrameView::updateCanHaveScrollbars()
+{
+ ScrollbarMode hMode;
+ ScrollbarMode vMode;
+ scrollbarModes(hMode, vMode);
+ if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
+ m_canHaveScrollbars = false;
+ else
+ m_canHaveScrollbars = true;
+}
+
PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
{
// FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles).
@@ -325,7 +367,7 @@ PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientatio
// Try the <body> element first as a scrollbar source.
Element* body = doc ? doc->body() : 0;
if (body && body->renderer() && body->renderer()->style()->hasPseudoStyle(SCROLLBAR))
- return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderBox());
+ return RenderScrollbar::createCustomScrollbar(this, orientation, body->renderer()->enclosingBox());
// If the <body> didn't have a custom style, then the root element might.
Element* docElement = doc ? doc->documentElement() : 0;
@@ -343,6 +385,9 @@ PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientatio
void FrameView::setContentsSize(const IntSize& size)
{
+ if (size == contentsSize())
+ return;
+
m_deferSetNeedsLayouts++;
ScrollView::setContentsSize(size);
@@ -352,7 +397,7 @@ void FrameView::setContentsSize(const IntSize& size)
return;
page->chrome()->contentsSizeChanged(frame(), size); //notify only
-
+
m_deferSetNeedsLayouts--;
if (!m_deferSetNeedsLayouts)
@@ -365,6 +410,7 @@ void FrameView::adjustViewSize()
RenderView* root = m_frame->contentRenderer();
if (!root)
return;
+
setContentsSize(IntSize(root->rightLayoutOverflow(), root->bottomLayoutOverflow()));
}
@@ -415,12 +461,12 @@ void FrameView::updateCompositingLayers()
return;
// This call will make sure the cached hasAcceleratedCompositing is updated from the pref
- view->compositor()->cacheAcceleratedCompositingEnabledFlag();
+ view->compositor()->cacheAcceleratedCompositingFlags();
if (!view->usesCompositing())
return;
- view->compositor()->updateCompositingLayers();
+ view->compositor()->updateCompositingLayers(CompositingUpdateAfterLayoutOrStyleChange);
}
void FrameView::setNeedsOneShotDrawingSynchronization()
@@ -458,8 +504,22 @@ bool FrameView::syncCompositingStateRecursive()
}
}
return allSubframesSynced;
-#endif // USE(ACCELERATED_COMPOSITING)
+#else // USE(ACCELERATED_COMPOSITING)
+ return true;
+#endif
+}
+
+bool FrameView::isSoftwareRenderable() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ RenderView* view = m_frame->contentRenderer();
+ if (!view)
+ return true;
+
+ return !view->compositor()->has3DContent();
+#else
return true;
+#endif
}
void FrameView::didMoveOnscreen()
@@ -505,9 +565,8 @@ void FrameView::layout(bool allowSubtree)
if (isPainting())
return;
-#if ENABLE(INSPECTOR)
- InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
- if (timelineAgent)
+#if ENABLE(INSPECTOR)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
timelineAgent->willLayout();
#endif
@@ -564,27 +623,42 @@ void FrameView::layout(bool allowSubtree)
ScrollbarMode hMode;
ScrollbarMode vMode;
- scrollbarModes(hMode, vMode);
+ if (m_canHaveScrollbars) {
+ hMode = ScrollbarAuto;
+ vMode = ScrollbarAuto;
+ } else {
+ hMode = ScrollbarAlwaysOff;
+ vMode = ScrollbarAlwaysOff;
+ }
if (!subtree) {
- RenderObject* rootRenderer = document->documentElement() ? document->documentElement()->renderer() : 0;
+ Node* documentElement = document->documentElement();
+ RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
Node* body = document->body();
if (body && body->renderer()) {
- if (body->hasTagName(framesetTag)) {
+ if (body->hasTagName(framesetTag) && !m_frame->settings()->frameFlatteningEnabled()) {
body->renderer()->setChildNeedsLayout(true);
vMode = ScrollbarAlwaysOff;
hMode = ScrollbarAlwaysOff;
} else if (body->hasTagName(bodyTag)) {
- if (!m_firstLayout && m_size.height() != layoutHeight()
- && toRenderBox(body->renderer())->stretchesToViewHeight())
+ if (!m_firstLayout && m_size.height() != layoutHeight() && body->renderer()->enclosingBox()->stretchesToViewHeight())
body->renderer()->setChildNeedsLayout(true);
// It's sufficient to just check the X overflow,
// since it's illegal to have visible in only one direction.
RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && document->documentElement()->hasTagName(htmlTag) ? body->renderer() : rootRenderer;
applyOverflowToViewport(o, hMode, vMode);
}
- } else if (rootRenderer)
+ } else if (rootRenderer) {
+#if ENABLE(SVG)
+ if (documentElement->isSVGElement()) {
+ if (!m_firstLayout && (m_size.width() != layoutWidth() || m_size.height() != layoutHeight()))
+ rootRenderer->setChildNeedsLayout(true);
+ } else
+ applyOverflowToViewport(rootRenderer, hMode, vMode);
+#else
applyOverflowToViewport(rootRenderer, hMode, vMode);
+#endif
+ }
#ifdef INSTRUMENT_LAYOUT_SCHEDULING
if (m_firstLayout && !document->ownerElement())
printf("Elapsed time before first layout: %d\n", document->elapsedTime());
@@ -629,8 +703,14 @@ void FrameView::layout(bool allowSubtree)
pauseScheduledEvents();
- if (subtree)
- root->view()->pushLayoutState(root);
+ bool disableLayoutState = false;
+ if (subtree) {
+ RenderView* view = root->view();
+ disableLayoutState = view->shouldDisableLayoutStateForSubtree(root);
+ view->pushLayoutState(root);
+ if (disableLayoutState)
+ view->disableLayoutState();
+ }
m_midLayout = true;
beginDeferredRepaints();
@@ -638,11 +718,16 @@ void FrameView::layout(bool allowSubtree)
endDeferredRepaints();
m_midLayout = false;
- if (subtree)
- root->view()->popLayoutState();
+ if (subtree) {
+ RenderView* view = root->view();
+ view->popLayoutState();
+ if (disableLayoutState)
+ view->enableLayoutState();
+ }
m_layoutRoot = 0;
- m_frame->invalidateSelection();
+ m_frame->selection()->setNeedsLayout();
+ m_frame->selection()->updateAppearance();
m_layoutSchedulingEnabled = true;
@@ -697,22 +782,22 @@ void FrameView::layout(bool allowSubtree)
}
#if ENABLE(INSPECTOR)
- if (timelineAgent)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
timelineAgent->didLayout();
#endif
m_nestedLayoutCount--;
}
-void FrameView::addWidgetToUpdate(RenderPartObject* object)
+void FrameView::addWidgetToUpdate(RenderEmbeddedObject* object)
{
if (!m_widgetUpdateSet)
- m_widgetUpdateSet.set(new HashSet<RenderPartObject*>);
+ m_widgetUpdateSet.set(new RenderEmbeddedObjectSet);
m_widgetUpdateSet->add(object);
}
-void FrameView::removeWidgetToUpdate(RenderPartObject* object)
+void FrameView::removeWidgetToUpdate(RenderEmbeddedObject* object)
{
if (!m_widgetUpdateSet)
return;
@@ -734,11 +819,29 @@ String FrameView::mediaType() const
return m_mediaType;
}
+void FrameView::adjustMediaTypeForPrinting(bool printing)
+{
+ if (printing) {
+ if (m_mediaTypeWhenNotPrinting.isNull())
+ m_mediaTypeWhenNotPrinting = mediaType();
+ setMediaType("print");
+ } else {
+ if (!m_mediaTypeWhenNotPrinting.isNull())
+ setMediaType(m_mediaTypeWhenNotPrinting);
+ m_mediaTypeWhenNotPrinting = String();
+ }
+}
+
bool FrameView::useSlowRepaints() const
{
return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque;
}
+bool FrameView::useSlowRepaintsIfNotOverlapped() const
+{
+ return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque;
+}
+
void FrameView::setUseSlowRepaints()
{
m_useSlowRepaints = true;
@@ -770,12 +873,12 @@ void FrameView::addFixedObject()
void FrameView::removeFixedObject()
{
ASSERT(m_fixedObjectCount > 0);
- m_fixedObjectCount--;
+ --m_fixedObjectCount;
if (!m_fixedObjectCount)
setCanBlitOnScroll(!useSlowRepaints());
}
-void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
+bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
{
const size_t fixedObjectThreshold = 5;
@@ -785,7 +888,7 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
if (!positionedObjects || positionedObjects->isEmpty()) {
hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
- return;
+ return true;
}
// Get the rects of the fixed objects visible in the rectToScroll
@@ -814,7 +917,7 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
// 1) scroll
hostWindow()->scroll(scrollDelta, rectToScroll, clipRect);
- // 2) update the area of fixed objets that has been invalidated
+ // 2) update the area of fixed objects that has been invalidated
size_t fixObjectsCount = subRectToUpdate.size();
for (size_t i = 0; i < fixObjectsCount; ++i) {
IntRect updateRect = subRectToUpdate[i];
@@ -822,14 +925,13 @@ void FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
scrolledRect.move(scrollDelta);
updateRect.unite(scrolledRect);
updateRect.intersect(rectToScroll);
- hostWindow()->repaint(updateRect, true, false, true);
+ hostWindow()->invalidateContentsAndWindow(updateRect, false);
}
- } else {
- // the number of fixed objects exceed the threshold, so we repaint everything.
- IntRect updateRect = clipRect;
- updateRect.intersect(rectToScroll);
- hostWindow()->repaint(updateRect, true, false, true);
+ return true;
}
+
+ // the number of fixed objects exceed the threshold, we cannot use the fast path
+ return false;
}
void FrameView::setIsOverlapped(bool isOverlapped)
@@ -959,16 +1061,18 @@ void FrameView::scrollPositionChanged()
{
frame()->eventHandler()->sendScrollEvent();
+ // For fixed position elements, update widget positions and compositing layers after scrolling,
+ // but only if we're not inside of layout.
+ // FIXME: we could skip this if we knew the page had no fixed position elements.
+ if (!m_nestedLayoutCount) {
+ if (RenderView* root = m_frame->contentRenderer()) {
+ root->updateWidgetPositions();
#if USE(ACCELERATED_COMPOSITING)
- // We need to update layer positions after scrolling to account for position:fixed layers.
- Document* document = m_frame->document();
- if (!document)
- return;
-
- RenderLayer* layer = document->renderer() ? document->renderer()->enclosingLayer() : 0;
- if (layer)
- layer->updateLayerPositions(RenderLayer::UpdateCompositingLayers);
+ if (root->usesCompositing())
+ root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
#endif
+ }
+ }
}
HostWindow* FrameView::hostWindow() const
@@ -987,9 +1091,10 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
double delay = adjustedDeferredRepaintDelay();
if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) {
- IntRect visibleContent = visibleContentRect();
- visibleContent.intersect(r);
- if (visibleContent.isEmpty())
+ IntRect paintRect = r;
+ if (!paintsEntireContents())
+ paintRect.intersect(visibleContentRect());
+ if (paintRect.isEmpty())
return;
if (m_repaintCount == cRepaintRectUnionThreshold) {
IntRect unionedRect;
@@ -999,9 +1104,9 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
m_repaintRects.append(unionedRect);
}
if (m_repaintCount < cRepaintRectUnionThreshold)
- m_repaintRects.append(visibleContent);
+ m_repaintRects.append(paintRect);
else
- m_repaintRects[0].unite(visibleContent);
+ m_repaintRects[0].unite(paintRect);
m_repaintCount++;
if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive())
@@ -1012,6 +1117,12 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
if (!immediate && isOffscreen() && !shouldUpdateWhileOffscreen())
return;
+#if ENABLE(TILED_BACKING_STORE)
+ if (frame()->tiledBackingStore()) {
+ frame()->tiledBackingStore()->invalidate(r);
+ return;
+ }
+#endif
ScrollView::repaintContentRectangle(r, immediate);
}
@@ -1083,8 +1194,15 @@ void FrameView::doDeferredRepaints()
return;
}
unsigned size = m_repaintRects.size();
- for (unsigned i = 0; i < size; i++)
+ for (unsigned i = 0; i < size; i++) {
+#if ENABLE(TILED_BACKING_STORE)
+ if (frame()->tiledBackingStore()) {
+ frame()->tiledBackingStore()->invalidate(m_repaintRects[i]);
+ continue;
+ }
+#endif
ScrollView::repaintContentRectangle(m_repaintRects[i], false);
+ }
m_repaintRects.clear();
m_repaintCount = 0;
@@ -1154,6 +1272,13 @@ void FrameView::scheduleRelayout()
if (!m_frame->document()->shouldScheduleLayout())
return;
+ // When frame flattening is enabled, the contents of the frame affects layout of the parent frames.
+ // Also invalidate parent frame starting from the owner element of this frame.
+ if (m_frame->settings()->frameFlatteningEnabled() && m_frame->ownerRenderer()) {
+ if (m_frame->ownerElement()->hasTagName(iframeTag) || m_frame->ownerElement()->hasTagName(frameTag))
+ m_frame->ownerRenderer()->setNeedsLayout(true, true);
+ }
+
int delay = m_frame->document()->minimumLayoutDelay();
if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
unscheduleRelayout();
@@ -1363,11 +1488,11 @@ bool FrameView::updateWidgets()
if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
return true;
- Vector<RenderPartObject*> objectVector;
+ Vector<RenderEmbeddedObject*> objectVector;
copyToVector(*m_widgetUpdateSet, objectVector);
size_t size = objectVector.size();
for (size_t i = 0; i < size; ++i) {
- RenderPartObject* object = objectVector[i];
+ RenderEmbeddedObject* object = objectVector[i];
object->updateWidget(false);
// updateWidget() can destroy the RenderPartObject, so we need to make sure it's
@@ -1519,6 +1644,7 @@ void FrameView::valueChanged(Scrollbar* bar)
ScrollView::valueChanged(bar);
if (offset != scrollOffset())
frame()->eventHandler()->sendScrollEvent();
+ frame()->loader()->client()->didChangeScrollOffset();
}
void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
@@ -1683,9 +1809,8 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
return;
#if ENABLE(INSPECTOR)
- InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
- if (timelineAgent)
- timelineAgent->willPaint();
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
+ timelineAgent->willPaint(rect);
#endif
Document* document = frame()->document();
@@ -1698,7 +1823,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
fillWithRed = false; // Subframe, don't fill with red.
else if (isTransparent())
fillWithRed = false; // Transparent, don't fill with red.
- else if (m_paintRestriction == PaintRestrictionSelectionOnly || m_paintRestriction == PaintRestrictionSelectionOnlyBlackText)
+ else if (m_paintBehavior & PaintBehaviorSelectionOnly)
fillWithRed = false; // Selections are transparent, don't fill with red.
else if (m_nodeToDraw)
fillWithRed = false; // Element images are transparent, don't fill with red.
@@ -1706,7 +1831,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
fillWithRed = true;
if (fillWithRed)
- p->fillRect(rect, Color(0xFF, 0, 0));
+ p->fillRect(rect, Color(0xFF, 0, 0), DeviceColorSpace);
#endif
bool isTopLevelPainter = !sCurrentPaintTimeStamp;
@@ -1736,9 +1861,15 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
// m_nodeToDraw is used to draw only one element (and its descendants)
RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
- if (m_paintRestriction == PaintRestrictionNone)
+
+ PaintBehavior paintBehavior = m_paintBehavior;
+ if (paintBehavior == PaintBehaviorNormal)
document->invalidateRenderedRectsForMarkersInRect(rect);
- contentRenderer->layer()->paint(p, rect, m_paintRestriction, eltRenderer);
+
+ if (document->printing())
+ paintBehavior |= PaintBehaviorFlattenCompositingLayers;
+
+ contentRenderer->layer()->paint(p, rect, paintBehavior, eltRenderer);
m_isPainting = false;
m_lastPaintTime = currentTime();
@@ -1753,16 +1884,21 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
sCurrentPaintTimeStamp = 0;
#if ENABLE(INSPECTOR)
- if (timelineAgent)
+ if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent())
timelineAgent->didPaint();
#endif
}
-void FrameView::setPaintRestriction(PaintRestriction pr)
+void FrameView::setPaintBehavior(PaintBehavior behavior)
{
- m_paintRestriction = pr;
+ m_paintBehavior = behavior;
}
-
+
+PaintBehavior FrameView::paintBehavior() const
+{
+ return m_paintBehavior;
+}
+
bool FrameView::isPainting() const
{
return m_isPainting;
diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.h b/src/3rdparty/webkit/WebCore/page/FrameView.h
index 5243c02..7371d13 100644
--- a/src/3rdparty/webkit/WebCore/page/FrameView.h
+++ b/src/3rdparty/webkit/WebCore/page/FrameView.h
@@ -45,7 +45,7 @@ class Node;
class PlatformMouseEvent;
class RenderLayer;
class RenderObject;
-class RenderPartObject;
+class RenderEmbeddedObject;
class ScheduledEvent;
class String;
@@ -72,8 +72,13 @@ public:
void setMarginWidth(int);
void setMarginHeight(int);
+ virtual void setCanHaveScrollbars(bool);
+ void updateCanHaveScrollbars();
+
virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
+ virtual bool avoidScrollbarCreation();
+
virtual void setContentsSize(const IntSize&);
void layout(bool allowSubtree = true);
@@ -87,7 +92,6 @@ public:
RenderObject* layoutRoot(bool onlyDuringLayout = false) const;
int layoutCount() const { return m_layoutCount; }
- // These two helper functions just pass through to the RenderView.
bool needsLayout() const;
void setNeedsLayout();
@@ -104,6 +108,10 @@ public:
// Returns true if the sync was completed.
bool syncCompositingStateRecursive();
+ // Returns true when a paint with the PaintBehaviorFlattenCompositingLayers flag set gives
+ // a faithful representation of the content.
+ bool isSoftwareRenderable() const;
+
void didMoveOnscreen();
void willMoveOffscreen();
@@ -135,6 +143,7 @@ public:
String mediaType() const;
void setMediaType(const String&);
+ void adjustMediaTypeForPrinting(bool printing);
void setUseSlowRepaints();
void setIsOverlapped(bool);
@@ -166,11 +175,12 @@ public:
bool wasScrolledByUser() const;
void setWasScrolledByUser(bool);
- void addWidgetToUpdate(RenderPartObject*);
- void removeWidgetToUpdate(RenderPartObject*);
+ void addWidgetToUpdate(RenderEmbeddedObject*);
+ void removeWidgetToUpdate(RenderEmbeddedObject*);
virtual void paintContents(GraphicsContext*, const IntRect& damageRect);
- void setPaintRestriction(PaintRestriction);
+ void setPaintBehavior(PaintBehavior);
+ PaintBehavior paintBehavior() const;
bool isPainting() const;
void setNodeToDraw(Node*);
@@ -200,7 +210,7 @@ public:
void invalidateScrollCorner();
protected:
- virtual void scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
+ virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
private:
FrameView(Frame*);
@@ -212,6 +222,7 @@ private:
friend class RenderWidget;
bool useSlowRepaints() const;
+ bool useSlowRepaintsIfNotOverlapped() const;
void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
@@ -258,11 +269,14 @@ private:
IntSize m_size;
IntSize m_margins;
- OwnPtr<HashSet<RenderPartObject*> > m_widgetUpdateSet;
+
+ typedef HashSet<RenderEmbeddedObject*> RenderEmbeddedObjectSet;
+ OwnPtr<RenderEmbeddedObjectSet> m_widgetUpdateSet;
RefPtr<Frame> m_frame;
bool m_doFullRepaint;
+ bool m_canHaveScrollbars;
bool m_useSlowRepaints;
bool m_isOverlapped;
bool m_contentIsOpaque;
@@ -289,7 +303,8 @@ private:
float m_lastZoomFactor;
String m_mediaType;
-
+ String m_mediaTypeWhenNotPrinting;
+
unsigned m_enqueueEvents;
Vector<ScheduledEvent*> m_scheduledEvents;
@@ -314,7 +329,7 @@ private:
bool m_setNeedsLayoutWasDeferred;
RefPtr<Node> m_nodeToDraw;
- PaintRestriction m_paintRestriction;
+ PaintBehavior m_paintBehavior;
bool m_isPainting;
bool m_isVisuallyNonEmpty;
diff --git a/src/3rdparty/webkit/WebCore/page/Geolocation.cpp b/src/3rdparty/webkit/WebCore/page/Geolocation.cpp
index de4a9a1..86f6777 100644
--- a/src/3rdparty/webkit/WebCore/page/Geolocation.cpp
+++ b/src/3rdparty/webkit/WebCore/page/Geolocation.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
* Copyright (C) 2009 Torch Mobile, Inc.
+ * 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
@@ -27,14 +28,54 @@
#include "config.h"
#include "Geolocation.h"
+#if ENABLE(GEOLOCATION)
+
#include "Chrome.h"
-#include "Document.h"
#include "Frame.h"
#include "Page.h"
+#include <wtf/CurrentTime.h>
+
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+#include "Coordinates.h"
+#include "GeolocationController.h"
+#include "GeolocationError.h"
+#include "GeolocationPosition.h"
+#include "PositionError.h"
+#endif
namespace WebCore {
static const char permissionDeniedErrorMessage[] = "User denied Geolocation";
+static const char failedToStartServiceErrorMessage[] = "Failed to start Geolocation service";
+
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+
+static PassRefPtr<Geoposition> createGeoposition(GeolocationPosition* position)
+{
+ if (!position)
+ return 0;
+
+ 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)
@@ -42,6 +83,7 @@ Geolocation::GeoNotifier::GeoNotifier(Geolocation* geolocation, PassRefPtr<Posit
, m_errorCallback(errorCallback)
, m_options(options)
, m_timer(this, &Geolocation::GeoNotifier::timerFired)
+ , m_useCachedPosition(false)
{
ASSERT(m_geolocation);
ASSERT(m_successCallback);
@@ -58,11 +100,22 @@ void Geolocation::GeoNotifier::setFatalError(PassRefPtr<PositionError> error)
m_timer.startOneShot(0);
}
+void Geolocation::GeoNotifier::setUseCachedPosition()
+{
+ m_useCachedPosition = true;
+ m_timer.startOneShot(0);
+}
+
bool Geolocation::GeoNotifier::hasZeroTimeout() const
{
return m_options->hasTimeout() && m_options->timeout() == 0;
}
+void Geolocation::GeoNotifier::runSuccessCallback(Geoposition* position)
+{
+ m_successCallback->handleEvent(position);
+}
+
void Geolocation::GeoNotifier::startTimerIfNeeded()
{
if (m_options->hasTimeout())
@@ -73,6 +126,10 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
{
m_timer.stop();
+ // Protect this GeoNotifier object, since it
+ // could be deleted by a call to clearWatch in a callback.
+ RefPtr<GeoNotifier> protect(this);
+
if (m_fatalError) {
if (m_errorCallback)
m_errorCallback->handleEvent(m_fatalError.get());
@@ -81,6 +138,14 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
return;
}
+ if (m_useCachedPosition) {
+ // Clear the cached position flag in case this is a watch request, which
+ // will continue to run.
+ m_useCachedPosition = false;
+ m_geolocation->requestUsesCachedPosition(this);
+ return;
+ }
+
if (m_errorCallback) {
RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timeout expired");
m_errorCallback->handleEvent(error.get());
@@ -88,10 +153,12 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
m_geolocation->requestTimedOut(this);
}
-void Geolocation::Watchers::set(int id, PassRefPtr<GeoNotifier> notifier)
+void Geolocation::Watchers::set(int id, PassRefPtr<GeoNotifier> prpNotifier)
{
- m_idToNotifierMap.set(id, notifier);
- m_notifierToIdMap.set(notifier, id);
+ RefPtr<GeoNotifier> notifier = prpNotifier;
+
+ m_idToNotifierMap.set(id, notifier.get());
+ m_notifierToIdMap.set(notifier.release(), id);
}
void Geolocation::Watchers::remove(int id)
@@ -112,6 +179,11 @@ void Geolocation::Watchers::remove(GeoNotifier* notifier)
m_notifierToIdMap.remove(iter);
}
+bool Geolocation::Watchers::contains(GeoNotifier* notifier) const
+{
+ return m_notifierToIdMap.contains(notifier);
+}
+
void Geolocation::Watchers::clear()
{
m_idToNotifierMap.clear();
@@ -130,9 +202,12 @@ void Geolocation::Watchers::getNotifiersVector(Vector<RefPtr<GeoNotifier> >& cop
Geolocation::Geolocation(Frame* frame)
: m_frame(frame)
+#if !ENABLE(CLIENT_BASED_GEOLOCATION)
, m_service(GeolocationService::create(this))
+#endif
, m_allowGeolocation(Unknown)
, m_shouldClearCache(false)
+ , m_positionCache(new GeolocationPositionCache)
{
if (!m_frame)
return;
@@ -140,19 +215,46 @@ Geolocation::Geolocation(Frame* frame)
m_frame->document()->setUsingGeolocation(true);
}
+Geolocation::~Geolocation()
+{
+}
+
void Geolocation::disconnectFrame()
{
- m_service->stopUpdating();
- if (m_frame && m_frame->document())
- m_frame->document()->setUsingGeolocation(false);
+ stopUpdating();
+ if (m_frame) {
+ if (m_frame->document())
+ m_frame->document()->setUsingGeolocation(false);
+ if (m_frame->page() && m_allowGeolocation == InProgress)
+ m_frame->page()->chrome()->cancelGeolocationPermissionRequestForFrame(m_frame);
+ }
m_frame = 0;
}
+Geoposition* Geolocation::lastPosition()
+{
+ ASSERT(isAllowed());
+
+#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);
- if (!notifier)
- return;
+ ASSERT(notifier);
m_oneShots.add(notifier);
}
@@ -160,8 +262,7 @@ void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallbac
int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
{
RefPtr<GeoNotifier> notifier = startRequest(successCallback, errorCallback, options);
- if (!notifier)
- return 0;
+ ASSERT(notifier);
static int nextAvailableWatchId = 1;
// In case of overflow, make sure the ID remains positive, but reuse the ID values.
@@ -179,17 +280,16 @@ PassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<Positi
// the permission state can not change again in the lifetime of this page.
if (isDenied())
notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
- else {
- if (notifier->hasZeroTimeout() || m_service->startUpdating(notifier->m_options.get()))
+ else if (haveSuitableCachedPosition(notifier->m_options.get()))
+ notifier->setUseCachedPosition();
+ else if (notifier->hasZeroTimeout() || startUpdating(notifier.get())) {
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ // Only start timer if we're not waiting for user permission.
+ if (!m_startRequestPermissionNotifier)
+#endif
notifier->startTimerIfNeeded();
- else {
- if (notifier->m_errorCallback) {
- RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "Unable to Start");
- notifier->m_errorCallback->handleEvent(error.get());
- }
- return 0;
- }
- }
+ } else
+ notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage));
return notifier.release();
}
@@ -201,49 +301,129 @@ void Geolocation::fatalErrorOccurred(Geolocation::GeoNotifier* notifier)
m_watchers.remove(notifier);
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
}
-void Geolocation::requestTimedOut(GeoNotifier* notifier)
+void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier)
{
- // If this is a one-shot request, stop it.
- m_oneShots.remove(notifier);
+ // This is called asynchronously, so the permissions could have been denied
+ // since we last checked in startRequest.
+ if (isDenied()) {
+ notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
+ return;
+ }
+
+ m_requestsAwaitingCachedPosition.add(notifier);
+
+ // If permissions are allowed, make the callback
+ if (isAllowed()) {
+ makeCachedPositionCallbacks();
+ return;
+ }
+
+ // Request permissions, which may be synchronous or asynchronous.
+ requestPermission();
+}
+
+void Geolocation::makeCachedPositionCallbacks()
+{
+ // All modifications to m_requestsAwaitingCachedPosition are done
+ // asynchronously, so we don't need to worry about it being modified from
+ // the callbacks.
+ GeoNotifierSet::const_iterator end = m_requestsAwaitingCachedPosition.end();
+ for (GeoNotifierSet::const_iterator iter = m_requestsAwaitingCachedPosition.begin(); iter != end; ++iter) {
+ GeoNotifier* notifier = iter->get();
+ notifier->runSuccessCallback(m_positionCache->cachedPosition());
+
+ // If this is a one-shot request, stop it. Otherwise, if the watch still
+ // exists, start the service to get updates.
+ if (m_oneShots.contains(notifier))
+ m_oneShots.remove(notifier);
+ else if (m_watchers.contains(notifier)) {
+ if (notifier->hasZeroTimeout() || startUpdating(notifier))
+ notifier->startTimerIfNeeded();
+ else
+ notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage));
+ }
+ }
+
+ m_requestsAwaitingCachedPosition.clear();
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
}
-void Geolocation::clearWatch(int watchId)
+void Geolocation::requestTimedOut(GeoNotifier* notifier)
{
- m_watchers.remove(watchId);
-
+ // If this is a one-shot request, stop it.
+ m_oneShots.remove(notifier);
+
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
}
-void Geolocation::suspend()
+bool Geolocation::haveSuitableCachedPosition(PositionOptions* options)
{
- if (hasListeners())
- m_service->suspend();
+ if (!m_positionCache->cachedPosition())
+ return false;
+ if (!options->hasMaximumAge())
+ return true;
+ if (!options->maximumAge())
+ return false;
+ DOMTimeStamp currentTimeMillis = currentTime() * 1000.0;
+ return m_positionCache->cachedPosition()->timestamp() > currentTimeMillis - options->maximumAge();
}
-void Geolocation::resume()
+void Geolocation::clearWatch(int watchId)
{
- if (hasListeners())
- m_service->resume();
+ m_watchers.remove(watchId);
+
+ if (!hasListeners())
+ stopUpdating();
}
void Geolocation::setIsAllowed(bool allowed)
{
+ // This may be due to either a new position from the service, or a cached
+ // position.
m_allowGeolocation = allowed ? Yes : No;
- if (isAllowed())
- makeSuccessCallbacks();
- else {
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ if (m_startRequestPermissionNotifier) {
+ if (isAllowed()) {
+ // Permission request was made during the startUpdating process
+ m_startRequestPermissionNotifier->startTimerIfNeeded();
+ m_startRequestPermissionNotifier = 0;
+ if (!m_frame)
+ return;
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+ page->geolocationController()->addObserver(this);
+ } else {
+ m_startRequestPermissionNotifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
+ m_oneShots.add(m_startRequestPermissionNotifier);
+ m_startRequestPermissionNotifier = 0;
+ }
+ return;
+ }
+#endif
+
+ if (!isAllowed()) {
RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage);
error->setIsFatal(true);
handleError(error.get());
+ m_requestsAwaitingCachedPosition.clear();
+ return;
}
+
+ // If the service has a last position, use it to call back for all requests.
+ // If any of the requests are waiting for permission for a cached position,
+ // the position from the service will be at least as fresh.
+ if (lastPosition())
+ makeSuccessCallbacks();
+ else
+ makeCachedPositionCallbacks();
}
void Geolocation::sendError(Vector<RefPtr<GeoNotifier> >& notifiers, PositionError* error)
@@ -320,7 +500,7 @@ void Geolocation::handleError(PositionError* error)
sendError(watchersCopy, error);
if (!hasListeners())
- m_service->stopUpdating();
+ stopUpdating();
}
void Geolocation::requestPermission()
@@ -341,10 +521,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_positionCache->setCachedPosition(m_currentPosition.get());
// Stop all currently running timers.
stopTimers();
@@ -363,7 +544,7 @@ void Geolocation::geolocationServicePositionChanged(GeolocationService* service)
void Geolocation::makeSuccessCallbacks()
{
- ASSERT(m_service->lastPosition());
+ ASSERT(m_currentPosition);
ASSERT(isAllowed());
Vector<RefPtr<GeoNotifier> > oneShotsCopy;
@@ -377,18 +558,104 @@ 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(GeoNotifier* notifier)
+{
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ // FIXME: Pass options to client.
+
+ if (!isAllowed()) {
+ m_startRequestPermissionNotifier = notifier;
+ requestPermission();
+ return true;
+ }
+
+ 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(notifier->m_options.get());
+#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
+
+}
+
} // namespace WebCore
+
+#else
+
+namespace WebCore {
+
+void Geolocation::disconnectFrame() {}
+
+Geolocation::Geolocation(Frame*) {}
+
+Geolocation::~Geolocation() {}
+
+void Geolocation::setIsAllowed(bool) {}
+
+}
+
+#endif // ENABLE(GEOLOCATION)
diff --git a/src/3rdparty/webkit/WebCore/page/Geolocation.h b/src/3rdparty/webkit/WebCore/page/Geolocation.h
index 4827664..29f3214 100644
--- a/src/3rdparty/webkit/WebCore/page/Geolocation.h
+++ b/src/3rdparty/webkit/WebCore/page/Geolocation.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008, 2009 Apple Inc. All Rights Reserved.
+ * 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
@@ -26,51 +27,56 @@
#ifndef Geolocation_h
#define Geolocation_h
+#include "GeolocationPositionCache.h"
#include "GeolocationService.h"
+#include "Geoposition.h"
#include "PositionCallback.h"
#include "PositionError.h"
#include "PositionErrorCallback.h"
#include "PositionOptions.h"
#include "Timer.h"
-#include <wtf/Platform.h>
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
namespace WebCore {
class Frame;
-class Geoposition;
-class Geolocation : public RefCounted<Geolocation>, public GeolocationServiceClient {
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+class GeolocationPosition;
+class GeolocationError;
+#endif
+
+class Geolocation : public RefCounted<Geolocation>
+#if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
+ , public GeolocationServiceClient
+#endif
+{
public:
static PassRefPtr<Geolocation> create(Frame* frame) { return adoptRef(new Geolocation(frame)); }
- virtual ~Geolocation() {}
+ ~Geolocation();
void disconnectFrame();
- Geoposition* lastPosition() const { return m_service->lastPosition(); }
-
void getCurrentPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
int watchPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
void clearWatch(int watchId);
- void suspend();
- void resume();
-
void setIsAllowed(bool);
+ Frame* frame() const { return m_frame; }
+
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+ void setPosition(GeolocationPosition*);
+ void setError(GeolocationError*);
+#else
+ GeolocationService* getGeolocationService() const { return m_service.get(); }
+#endif
+
+private:
+ Geoposition* lastPosition();
+
bool isAllowed() const { return m_allowGeolocation == Yes; }
bool isDenied() const { return m_allowGeolocation == No; }
- void setShouldClearCache(bool shouldClearCache) { m_shouldClearCache = shouldClearCache; }
- bool shouldClearCache() const { return m_shouldClearCache; }
-
-private:
Geolocation(Frame*);
class GeoNotifier : public RefCounted<GeoNotifier> {
@@ -79,6 +85,8 @@ private:
void setFatalError(PassRefPtr<PositionError>);
bool hasZeroTimeout() const;
+ void setUseCachedPosition();
+ void runSuccessCallback(Geoposition*);
void startTimerIfNeeded();
void timerFired(Timer<GeoNotifier>*);
@@ -88,6 +96,7 @@ private:
RefPtr<PositionOptions> m_options;
Timer<GeoNotifier> m_timer;
RefPtr<PositionError> m_fatalError;
+ bool m_useCachedPosition;
private:
GeoNotifier(Geolocation*, PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
@@ -98,6 +107,7 @@ private:
void set(int id, PassRefPtr<GeoNotifier>);
void remove(int id);
void remove(GeoNotifier*);
+ bool contains(GeoNotifier*) const;
void clear();
bool isEmpty() const;
void getNotifiersVector(Vector<RefPtr<GeoNotifier> >&) const;
@@ -118,26 +128,41 @@ private:
void stopTimersForWatchers();
void stopTimers();
+ void positionChanged(PassRefPtr<Geoposition>);
void makeSuccessCallbacks();
void handleError(PositionError*);
void requestPermission();
+ bool startUpdating(GeoNotifier*);
+ void stopUpdating();
+
+#if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
// GeolocationServiceClient
virtual void geolocationServicePositionChanged(GeolocationService*);
virtual void geolocationServiceErrorOccurred(GeolocationService*);
+#endif
PassRefPtr<GeoNotifier> startRequest(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
void fatalErrorOccurred(GeoNotifier*);
void requestTimedOut(GeoNotifier*);
+ void requestUsesCachedPosition(GeoNotifier*);
+ bool haveSuitableCachedPosition(PositionOptions*);
+ void makeCachedPositionCallbacks();
typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
GeoNotifierSet m_oneShots;
Watchers m_watchers;
Frame* m_frame;
+#if !ENABLE(CLIENT_BASED_GEOLOCATION)
OwnPtr<GeolocationService> m_service;
+#else
+ RefPtr<GeoNotifier> m_startRequestPermissionNotifier;
+#endif
+ RefPtr<Geoposition> m_lastPosition;
+ RefPtr<Geoposition> m_currentPosition;
enum {
Unknown,
@@ -146,6 +171,11 @@ private:
No
} m_allowGeolocation;
bool m_shouldClearCache;
+
+#if ENABLE(GEOLOCATION)
+ OwnPtr<GeolocationPositionCache> m_positionCache;
+#endif
+ GeoNotifierSet m_requestsAwaitingCachedPosition;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/Geolocation.idl b/src/3rdparty/webkit/WebCore/page/Geolocation.idl
index e125118..aa5b59f 100644
--- a/src/3rdparty/webkit/WebCore/page/Geolocation.idl
+++ b/src/3rdparty/webkit/WebCore/page/Geolocation.idl
@@ -25,9 +25,7 @@
module core {
- interface Geolocation {
- readonly attribute Geoposition lastPosition;
-
+ interface [Conditional=GEOLOCATION, OmitConstructor] Geolocation {
[Custom] void getCurrentPosition(in PositionCallback successCallback, in PositionErrorCallback errorCallback, in PositionOptions options);
[Custom] long watchPosition(in PositionCallback successCallback, in PositionErrorCallback errorCallback, in PositionOptions options);
diff --git a/src/3rdparty/webkit/WebCore/page/GeolocationController.cpp b/src/3rdparty/webkit/WebCore/page/GeolocationController.cpp
new file mode 100644
index 0000000..fd18b45
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/GeolocationController.cpp
@@ -0,0 +1,93 @@
+/*
+ * 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()
+{
+ if (m_client)
+ m_client->geolocationDestroyed();
+}
+
+void GeolocationController::addObserver(Geolocation* observer)
+{
+ ASSERT(!m_observers.contains(observer));
+
+ bool wasEmpty = m_observers.isEmpty();
+ m_observers.add(observer);
+ if (wasEmpty && m_client)
+ m_client->startUpdating();
+}
+
+void GeolocationController::removeObserver(Geolocation* observer)
+{
+ if (!m_observers.contains(observer))
+ return;
+
+ m_observers.remove(observer);
+ if (m_observers.isEmpty() && m_client)
+ m_client->stopUpdating();
+}
+
+void GeolocationController::positionChanged(GeolocationPosition* position)
+{
+ Vector<RefPtr<Geolocation> > observersVector;
+ copyToVector(m_observers, observersVector);
+ for (size_t i = 0; i < observersVector.size(); ++i)
+ observersVector[i]->setPosition(position);
+}
+
+void GeolocationController::errorOccurred(GeolocationError* error)
+{
+ Vector<RefPtr<Geolocation> > observersVector;
+ copyToVector(m_observers, observersVector);
+ for (size_t i = 0; i < observersVector.size(); ++i)
+ observersVector[i]->setError(error);
+}
+
+GeolocationPosition* GeolocationController::lastPosition()
+{
+ if (!m_client)
+ return 0;
+
+ return m_client->lastPosition();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(CLIENT_BASED_GEOLOCATION)
diff --git a/src/3rdparty/webkit/WebCore/page/GeolocationController.h b/src/3rdparty/webkit/WebCore/page/GeolocationController.h
new file mode 100644
index 0000000..80f9ca8
--- /dev/null
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/page/GeolocationControllerClient.h b/src/3rdparty/webkit/WebCore/page/GeolocationControllerClient.h
new file mode 100644
index 0000000..cc0e1e4
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/GeolocationControllerClient.h
@@ -0,0 +1,47 @@
+/*
+ * 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 geolocationDestroyed() = 0;
+
+ virtual void startUpdating() = 0;
+ virtual void stopUpdating() = 0;
+ virtual GeolocationPosition* lastPosition() = 0;
+
+protected:
+ virtual ~GeolocationControllerClient() { }
+};
+
+} // namespace WebCore
+
+#endif // GeolocationControllerClient_h
diff --git a/src/3rdparty/webkit/WebCore/page/GeolocationError.h b/src/3rdparty/webkit/WebCore/page/GeolocationError.h
new file mode 100644
index 0000000..2a3bad4
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/GeolocationError.h
@@ -0,0 +1,65 @@
+/*
+ * 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/RefCounted.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)
+ : m_code(code)
+ , m_message(message)
+ {
+ }
+
+ ErrorCode m_code;
+ String m_message;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(CLIENT_BASED_GEOLOCATION)
+
+#endif // GeolocationError_h
diff --git a/src/3rdparty/webkit/WebCore/page/GeolocationPosition.h b/src/3rdparty/webkit/WebCore/page/GeolocationPosition.h
new file mode 100644
index 0000000..9f25b11
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/GeolocationPosition.h
@@ -0,0 +1,111 @@
+/*
+ * 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/RefCounted.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/src/3rdparty/webkit/WebCore/page/GeolocationPositionCache.cpp b/src/3rdparty/webkit/WebCore/page/GeolocationPositionCache.cpp
new file mode 100644
index 0000000..06159f4
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/GeolocationPositionCache.cpp
@@ -0,0 +1,178 @@
+/*
+ * 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 "GeolocationPositionCache.h"
+
+#if ENABLE(GEOLOCATION)
+
+#include "Geoposition.h"
+#include "SQLValue.h"
+#include "SQLiteDatabase.h"
+#include "SQLiteFileSystem.h"
+#include "SQLiteStatement.h"
+#include "SQLiteTransaction.h"
+
+namespace WebCore {
+
+static const char* databaseName = "CachedGeoposition.db";
+
+int GeolocationPositionCache::s_instances = 0;
+RefPtr<Geoposition>* GeolocationPositionCache::s_cachedPosition;
+String* GeolocationPositionCache::s_databaseFile = 0;
+
+GeolocationPositionCache::GeolocationPositionCache()
+{
+ if (!(s_instances++)) {
+ s_cachedPosition = new RefPtr<Geoposition>;
+ *s_cachedPosition = readFromDB();
+ }
+}
+
+GeolocationPositionCache::~GeolocationPositionCache()
+{
+ if (!(--s_instances)) {
+ if (*s_cachedPosition)
+ writeToDB(s_cachedPosition->get());
+ delete s_cachedPosition;
+ }
+}
+
+void GeolocationPositionCache::setCachedPosition(Geoposition* cachedPosition)
+{
+ *s_cachedPosition = cachedPosition;
+}
+
+Geoposition* GeolocationPositionCache::cachedPosition()
+{
+ return s_cachedPosition->get();
+}
+
+void GeolocationPositionCache::setDatabasePath(const String& databasePath)
+{
+ if (!s_databaseFile)
+ s_databaseFile = new String;
+ *s_databaseFile = SQLiteFileSystem::appendDatabaseFileNameToPath(databasePath, databaseName);
+ // If we don't have have a cached position, attempt to read one from the
+ // DB at the new path.
+ if (s_instances && !(*s_cachedPosition))
+ *s_cachedPosition = readFromDB();
+}
+
+PassRefPtr<Geoposition> GeolocationPositionCache::readFromDB()
+{
+ SQLiteDatabase database;
+ if (!s_databaseFile || !database.open(*s_databaseFile))
+ return 0;
+
+ // Create the table here, such that even if we've just created the
+ // DB, the commands below should succeed.
+ if (!database.executeCommand("CREATE TABLE IF NOT EXISTS CachedPosition ("
+ "latitude REAL NOT NULL, "
+ "longitude REAL NOT NULL, "
+ "altitude REAL, "
+ "accuracy REAL NOT NULL, "
+ "altitudeAccuracy REAL, "
+ "heading REAL, "
+ "speed REAL, "
+ "timestamp INTEGER NOT NULL)"))
+ return 0;
+
+ SQLiteStatement statement(database, "SELECT * FROM CachedPosition");
+ if (statement.prepare() != SQLResultOk)
+ return 0;
+
+ if (statement.step() != SQLResultRow)
+ return 0;
+
+ bool providesAltitude = statement.getColumnValue(2).type() != SQLValue::NullValue;
+ bool providesAltitudeAccuracy = statement.getColumnValue(4).type() != SQLValue::NullValue;
+ bool providesHeading = statement.getColumnValue(5).type() != SQLValue::NullValue;
+ bool providesSpeed = statement.getColumnValue(6).type() != SQLValue::NullValue;
+ RefPtr<Coordinates> coordinates = Coordinates::create(statement.getColumnDouble(0), // latitude
+ statement.getColumnDouble(1), // longitude
+ providesAltitude, statement.getColumnDouble(2), // altitude
+ statement.getColumnDouble(3), // accuracy
+ providesAltitudeAccuracy, statement.getColumnDouble(4), // altitudeAccuracy
+ providesHeading, statement.getColumnDouble(5), // heading
+ providesSpeed, statement.getColumnDouble(6)); // speed
+ return Geoposition::create(coordinates.release(), statement.getColumnInt64(7)); // timestamp
+}
+
+void GeolocationPositionCache::writeToDB(const Geoposition* position)
+{
+ ASSERT(position);
+
+ SQLiteDatabase database;
+ if (!s_databaseFile || !database.open(*s_databaseFile))
+ return;
+
+ SQLiteTransaction transaction(database);
+
+ if (!database.executeCommand("DELETE FROM CachedPosition"))
+ return;
+
+ SQLiteStatement statement(database, "INSERT INTO CachedPosition ("
+ "latitude, "
+ "longitude, "
+ "altitude, "
+ "accuracy, "
+ "altitudeAccuracy, "
+ "heading, "
+ "speed, "
+ "timestamp) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
+ if (statement.prepare() != SQLResultOk)
+ return;
+
+ statement.bindDouble(1, position->coords()->latitude());
+ statement.bindDouble(2, position->coords()->longitude());
+ if (position->coords()->canProvideAltitude())
+ statement.bindDouble(3, position->coords()->altitude());
+ else
+ statement.bindNull(3);
+ statement.bindDouble(4, position->coords()->accuracy());
+ if (position->coords()->canProvideAltitudeAccuracy())
+ statement.bindDouble(5, position->coords()->altitudeAccuracy());
+ else
+ statement.bindNull(5);
+ if (position->coords()->canProvideHeading())
+ statement.bindDouble(6, position->coords()->heading());
+ else
+ statement.bindNull(6);
+ if (position->coords()->canProvideSpeed())
+ statement.bindDouble(7, position->coords()->speed());
+ else
+ statement.bindNull(7);
+ statement.bindInt64(8, position->timestamp());
+ if (!statement.executeCommand())
+ return;
+
+ transaction.commit();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(GEOLOCATION)
diff --git a/src/3rdparty/webkit/WebCore/page/GeolocationPositionCache.h b/src/3rdparty/webkit/WebCore/page/GeolocationPositionCache.h
new file mode 100644
index 0000000..c7f7e49
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/GeolocationPositionCache.h
@@ -0,0 +1,58 @@
+/*
+ * 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 GeolocationPositionCache_h
+#define GeolocationPositionCache_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+
+namespace WebCore {
+
+class Geoposition;
+class String;
+
+class GeolocationPositionCache {
+ public:
+ GeolocationPositionCache();
+ ~GeolocationPositionCache();
+
+ void setCachedPosition(Geoposition*);
+ Geoposition* cachedPosition();
+ static void setDatabasePath(const String&);
+
+ private:
+ static PassRefPtr<Geoposition> readFromDB();
+ static void writeToDB(const Geoposition*);
+
+ static int s_instances;
+ static RefPtr<Geoposition>* s_cachedPosition;
+ static String* s_databaseFile;
+};
+
+} // namespace WebCore
+
+#endif // GeolocationPositionCache_h
diff --git a/src/3rdparty/webkit/WebCore/page/Geoposition.h b/src/3rdparty/webkit/WebCore/page/Geoposition.h
index f3c703b..8b215b1 100644
--- a/src/3rdparty/webkit/WebCore/page/Geoposition.h
+++ b/src/3rdparty/webkit/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/src/3rdparty/webkit/WebCore/page/Geoposition.idl b/src/3rdparty/webkit/WebCore/page/Geoposition.idl
index 3ec8b0b..41a2262 100644
--- a/src/3rdparty/webkit/WebCore/page/Geoposition.idl
+++ b/src/3rdparty/webkit/WebCore/page/Geoposition.idl
@@ -25,7 +25,7 @@
module core {
- interface Geoposition {
+ interface [Conditional=GEOLOCATION, OmitConstructor] Geoposition {
readonly attribute Coordinates coords;
readonly attribute DOMTimeStamp timestamp;
};
diff --git a/src/3rdparty/webkit/WebCore/page/HaltablePlugin.h b/src/3rdparty/webkit/WebCore/page/HaltablePlugin.h
index a5fe0f4..0f4aa41 100644
--- a/src/3rdparty/webkit/WebCore/page/HaltablePlugin.h
+++ b/src/3rdparty/webkit/WebCore/page/HaltablePlugin.h
@@ -37,6 +37,8 @@ public:
virtual void halt() = 0;
virtual void restart() = 0;
virtual Node* node() const = 0;
+ virtual bool isWindowed() const = 0;
+ virtual String pluginName() const = 0;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/History.cpp b/src/3rdparty/webkit/WebCore/page/History.cpp
index 9a27f1c..78e8ea6 100644
--- a/src/3rdparty/webkit/WebCore/page/History.cpp
+++ b/src/3rdparty/webkit/WebCore/page/History.cpp
@@ -26,8 +26,12 @@
#include "config.h"
#include "History.h"
+#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
+#include "FrameLoaderClient.h"
+#include "HistoryItem.h"
+#include "Page.h"
namespace WebCore {
@@ -76,4 +80,45 @@ void History::go(int distance)
m_frame->redirectScheduler()->scheduleHistoryNavigation(distance);
}
+KURL History::urlForState(const String& urlString)
+{
+ KURL baseURL = m_frame->loader()->baseURL();
+ if (urlString.isEmpty())
+ return baseURL;
+
+ KURL absoluteURL(baseURL, urlString);
+ if (!absoluteURL.isValid())
+ return KURL();
+
+ if (absoluteURL.string().left(absoluteURL.pathStart()) != baseURL.string().left(baseURL.pathStart()))
+ return KURL();
+
+ return absoluteURL;
+}
+
+void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const String& title, const String& urlString, StateObjectType stateObjectType, ExceptionCode& ec)
+{
+ if (!m_frame || !m_frame->page())
+ return;
+
+ KURL fullURL = urlForState(urlString);
+ if (!fullURL.isValid()) {
+ ec = SECURITY_ERR;
+ return;
+ }
+
+ if (stateObjectType == StateObjectPush)
+ m_frame->loader()->history()->pushState(data, title, fullURL.string());
+ else if (stateObjectType == StateObjectReplace)
+ m_frame->loader()->history()->replaceState(data, title, fullURL.string());
+
+ if (!urlString.isEmpty())
+ m_frame->document()->updateURLForPushOrReplaceState(fullURL);
+
+ if (stateObjectType == StateObjectPush)
+ m_frame->loader()->client()->dispatchDidPushStateWithinPage();
+ else if (stateObjectType == StateObjectReplace)
+ m_frame->loader()->client()->dispatchDidReplaceStateWithinPage();
+}
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/History.h b/src/3rdparty/webkit/WebCore/page/History.h
index f0df2de..66a6a03 100644
--- a/src/3rdparty/webkit/WebCore/page/History.h
+++ b/src/3rdparty/webkit/WebCore/page/History.h
@@ -26,30 +26,42 @@
#ifndef History_h
#define History_h
+#include "KURL.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
- class Frame;
+class Frame;
+class SerializedScriptValue;
+class String;
+typedef int ExceptionCode;
- class History : public RefCounted<History> {
- public:
- static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); }
-
- Frame* frame() const;
- void disconnectFrame();
+class History : public RefCounted<History> {
+public:
+ static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); }
+
+ Frame* frame() const;
+ void disconnectFrame();
- unsigned length() const;
- void back();
- void forward();
- void go(int distance);
+ unsigned length() const;
+ void back();
+ void forward();
+ void go(int distance);
- private:
- History(Frame*);
-
- Frame* m_frame;
+ enum StateObjectType {
+ StateObjectPush,
+ StateObjectReplace
};
+ void stateObjectAdded(PassRefPtr<SerializedScriptValue>, const String& title, const String& url, StateObjectType, ExceptionCode&);
+
+private:
+ History(Frame*);
+
+ KURL urlForState(const String& url);
+
+ Frame* m_frame;
+};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/History.idl b/src/3rdparty/webkit/WebCore/page/History.idl
index 914d441..d1be5ae 100644
--- a/src/3rdparty/webkit/WebCore/page/History.idl
+++ b/src/3rdparty/webkit/WebCore/page/History.idl
@@ -32,13 +32,19 @@ module window {
DelegatingGetOwnPropertySlot,
DelegatingPutFunction,
CustomDeleteProperty,
- CustomGetPropertyNames
+ CustomGetPropertyNames,
+ OmitConstructor
] History {
readonly attribute unsigned long length;
[DoNotCheckDomainSecurity] void back();
[DoNotCheckDomainSecurity] void forward();
[DoNotCheckDomainSecurity] void go(in long distance);
+
+ [Custom, EnabledAtRuntime] void pushState(in any data, in DOMString title, in optional DOMString url)
+ raises(DOMException);
+ [Custom, EnabledAtRuntime] void replaceState(in any data, in DOMString title, in optional DOMString url)
+ raises(DOMException);
};
}
diff --git a/src/3rdparty/webkit/WebCore/page/Location.idl b/src/3rdparty/webkit/WebCore/page/Location.idl
index 7d680f2..b020267 100644
--- a/src/3rdparty/webkit/WebCore/page/Location.idl
+++ b/src/3rdparty/webkit/WebCore/page/Location.idl
@@ -38,7 +38,8 @@ module window {
CustomGetPropertyNames,
CustomDefineGetter,
DelegatingPrototypePutFunction,
- CustomPrototypeDefineGetter
+ CustomPrototypeDefineGetter,
+ OmitConstructor
] Location {
attribute [DoNotCheckDomainSecurityOnSet, CustomSetter, V8DisallowShadowing] DOMString href;
diff --git a/src/3rdparty/webkit/WebCore/page/android/DragControllerAndroid.cpp b/src/3rdparty/webkit/WebCore/page/MediaCanStartListener.h
index 19d02c6..317babf 100644
--- a/src/3rdparty/webkit/WebCore/page/android/DragControllerAndroid.cpp
+++ b/src/3rdparty/webkit/WebCore/page/MediaCanStartListener.h
@@ -1,6 +1,5 @@
/*
- * Copyright 2009, The Android Open Source Project
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,10 +10,10 @@
* 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -24,35 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "DragController.h"
-
-#include "DragData.h"
-#include "NotImplemented.h"
+#ifndef MediaCanStartListener_h
+#define MediaCanStartListener_h
namespace WebCore {
-bool DragController::isCopyKeyDown()
-{
- return false;
-}
-
-DragOperation DragController::dragOperation(DragData* dragData)
-{
- // FIXME: This logic is incomplete
- notImplemented();
- if (dragData->containsURL())
- return DragOperationCopy;
-
- return DragOperationNone;
-}
+class MediaCanStartListener {
+public:
+ virtual void mediaCanStart() = 0;
+protected:
+ virtual ~MediaCanStartListener() { }
+};
-const float DragController::DragImageAlpha = 1.0f;
-static IntSize dummy;
-const IntSize& DragController::maxDragImageSize() { return dummy; }
-const int DragController::DragIconRightInset = 0;
-const int DragController::DragIconBottomInset = 0;
-const int DragController::LinkDragBorderInset = 0;
-const int DragController::MaxOriginalImageArea = 0;
+}
-} // namespace WebCore
+#endif
diff --git a/src/3rdparty/webkit/WebCore/page/MouseEventWithHitTestResults.h b/src/3rdparty/webkit/WebCore/page/MouseEventWithHitTestResults.h
index 7330d93..8c28574 100644
--- a/src/3rdparty/webkit/WebCore/page/MouseEventWithHitTestResults.h
+++ b/src/3rdparty/webkit/WebCore/page/MouseEventWithHitTestResults.h
@@ -1,4 +1,4 @@
-/* This file is part of the KDE project
+/*
Copyright (C) 2000 Simon Hausmann <hausmann@kde.org>
Copyright (C) 2006 Apple Computer, Inc.
diff --git a/src/3rdparty/webkit/WebCore/page/Navigator.cpp b/src/3rdparty/webkit/WebCore/page/Navigator.cpp
index 4922860..7078454 100644
--- a/src/3rdparty/webkit/WebCore/page/Navigator.cpp
+++ b/src/3rdparty/webkit/WebCore/page/Navigator.cpp
@@ -23,11 +23,14 @@
#include "config.h"
#include "Navigator.h"
+#include "Chrome.h"
#include "CookieJar.h"
+#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "Geolocation.h"
+#include "KURL.h"
#include "Language.h"
#include "MimeTypeArray.h"
#include "Page.h"
@@ -169,4 +172,93 @@ void Navigator::getStorageUpdates()
}
#endif
+static bool verifyCustomHandlerURL(const String& baseURL, const String& url, ExceptionCode& ec)
+{
+ // The specification requires that it is a SYNTAX_ERR if the the "%s" token is not present.
+ static const char token[] = "%s";
+ int index = url.find(token);
+ if (-1 == index) {
+ ec = SYNTAX_ERR;
+ return false;
+ }
+
+ // It is also a SYNTAX_ERR if the custom handler URL, as created by removing
+ // the "%s" token and prepending the base url, does not resolve.
+ String newURL = url;
+ newURL.remove(index, sizeof(token) / sizeof(token[0]));
+
+ KURL base(ParsedURLString, baseURL);
+ KURL kurl(base, newURL);
+
+ if (kurl.isEmpty() || !kurl.isValid()) {
+ ec = SYNTAX_ERR;
+ return false;
+ }
+
+ return true;
+}
+
+static bool verifyProtocolHandlerScheme(const String& scheme, ExceptionCode& ec)
+{
+ // It is a SECURITY_ERR for these schemes to be handled by a custom handler.
+ if (equalIgnoringCase(scheme, "http") || equalIgnoringCase(scheme, "https") || equalIgnoringCase(scheme, "file")) {
+ ec = SECURITY_ERR;
+ return false;
+ }
+ return true;
+}
+
+void Navigator::registerProtocolHandler(const String& scheme, const String& url, const String& title, ExceptionCode& ec)
+{
+ if (!verifyProtocolHandlerScheme(scheme, ec))
+ return;
+
+ if (!m_frame)
+ return;
+
+ Document* document = m_frame->document();
+ if (!document)
+ return;
+
+ String baseURL = document->baseURL().baseAsString();
+
+ if (!verifyCustomHandlerURL(baseURL, url, ec))
+ return;
+
+ if (Page* page = m_frame->page())
+ page->chrome()->registerProtocolHandler(scheme, baseURL, url, m_frame->displayStringModifiedByEncoding(title));
+}
+
+static bool verifyProtocolHandlerMimeType(const String& type, ExceptionCode& ec)
+{
+ // It is a SECURITY_ERR for these mime types to be assigned to a custom
+ // handler.
+ if (equalIgnoringCase(type, "text/html") || equalIgnoringCase(type, "text/css") || equalIgnoringCase(type, "application/x-javascript")) {
+ ec = SECURITY_ERR;
+ return false;
+ }
+ return true;
+}
+
+void Navigator::registerContentHandler(const String& mimeType, const String& url, const String& title, ExceptionCode& ec)
+{
+ if (!verifyProtocolHandlerMimeType(mimeType, ec))
+ return;
+
+ if (!m_frame)
+ return;
+
+ Document* document = m_frame->document();
+ if (!document)
+ return;
+
+ String baseURL = document->baseURL().baseAsString();
+
+ if (!verifyCustomHandlerURL(baseURL, url, ec))
+ return;
+
+ if (Page* page = m_frame->page())
+ page->chrome()->registerContentHandler(mimeType, baseURL, url, m_frame->displayStringModifiedByEncoding(title));
+}
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/Navigator.h b/src/3rdparty/webkit/WebCore/page/Navigator.h
index 4adebe1..107082b 100644
--- a/src/3rdparty/webkit/WebCore/page/Navigator.h
+++ b/src/3rdparty/webkit/WebCore/page/Navigator.h
@@ -34,6 +34,8 @@ namespace WebCore {
class PluginArray;
class String;
+ typedef int ExceptionCode;
+
class Navigator : public NavigatorBase, public RefCounted<Navigator> {
public:
static PassRefPtr<Navigator> create(Frame* frame) { return adoptRef(new Navigator(frame)); }
@@ -60,6 +62,9 @@ namespace WebCore {
void getStorageUpdates();
#endif
+ void registerProtocolHandler(const String& scheme, const String& url, const String& title, ExceptionCode& ec);
+ void registerContentHandler(const String& mimeType, const String& url, const String& title, ExceptionCode& ec);
+
private:
Navigator(Frame*);
Frame* m_frame;
diff --git a/src/3rdparty/webkit/WebCore/page/Navigator.idl b/src/3rdparty/webkit/WebCore/page/Navigator.idl
index 80ef4fb..257ede1 100644
--- a/src/3rdparty/webkit/WebCore/page/Navigator.idl
+++ b/src/3rdparty/webkit/WebCore/page/Navigator.idl
@@ -20,7 +20,8 @@
module window {
interface [
- CustomMarkFunction
+ CustomMarkFunction,
+ OmitConstructor
] Navigator {
readonly attribute DOMString appCodeName;
readonly attribute DOMString appName;
@@ -40,12 +41,17 @@ module window {
readonly attribute boolean onLine;
#if defined(ENABLE_GEOLOCATION) && ENABLE_GEOLOCATION
- readonly attribute Geolocation geolocation;
+ readonly attribute [EnabledAtRuntime] Geolocation geolocation;
#endif
#if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE
void getStorageUpdates();
#endif
+
+ void registerProtocolHandler(in DOMString scheme, in DOMString url, in DOMString title)
+ raises(DomException);
+ void registerContentHandler(in DOMString mimeType, in DOMString url, in DOMString title)
+ raises(DomException);
};
}
diff --git a/src/3rdparty/webkit/WebCore/page/NavigatorBase.cpp b/src/3rdparty/webkit/WebCore/page/NavigatorBase.cpp
index 5b0c5d4..ca51a29 100644
--- a/src/3rdparty/webkit/WebCore/page/NavigatorBase.cpp
+++ b/src/3rdparty/webkit/WebCore/page/NavigatorBase.cpp
@@ -29,19 +29,19 @@
#include "NetworkStateNotifier.h"
#include "PlatformString.h"
-#if PLATFORM(LINUX)
+#if OS(LINUX)
#include "sys/utsname.h"
#include <wtf/StdLibExtras.h>
#endif
#ifndef WEBCORE_NAVIGATOR_PLATFORM
-#if PLATFORM(MAC) && (PLATFORM(PPC) || PLATFORM(PPC64))
+#if OS(MAC_OS_X) && (CPU(PPC) || CPU(PPC64))
#define WEBCORE_NAVIGATOR_PLATFORM "MacPPC"
-#elif PLATFORM(MAC) && (PLATFORM(X86) || PLATFORM(X86_64))
+#elif OS(MAC_OS_X) && (CPU(X86) || CPU(X86_64))
#define WEBCORE_NAVIGATOR_PLATFORM "MacIntel"
-#elif PLATFORM(WIN_OS)
+#elif OS(WINDOWS)
#define WEBCORE_NAVIGATOR_PLATFORM "Win32"
-#elif PLATFORM(SYMBIAN)
+#elif OS(SYMBIAN)
#define WEBCORE_NAVIGATOR_PLATFORM "Symbian"
#else
#define WEBCORE_NAVIGATOR_PLATFORM ""
@@ -85,7 +85,7 @@ String NavigatorBase::appVersion() const
String NavigatorBase::platform() const
{
-#if PLATFORM(LINUX)
+#if OS(LINUX)
if (String("") != WEBCORE_NAVIGATOR_PLATFORM)
return WEBCORE_NAVIGATOR_PLATFORM;
struct utsname osname;
diff --git a/src/3rdparty/webkit/WebCore/page/Page.cpp b/src/3rdparty/webkit/WebCore/page/Page.cpp
index 8a685f4..d66e497 100644
--- a/src/3rdparty/webkit/WebCore/page/Page.cpp
+++ b/src/3rdparty/webkit/WebCore/page/Page.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All Rights Reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -21,6 +21,7 @@
#include "config.h"
#include "Page.h"
+#include "BackForwardList.h"
#include "Base64.h"
#include "CSSStyleSelector.h"
#include "Chrome.h"
@@ -29,10 +30,10 @@
#include "ContextMenuController.h"
#include "DOMWindow.h"
#include "DragController.h"
-#include "ExceptionCode.h"
#include "EditorClient.h"
-#include "EventNames.h"
#include "Event.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
#include "FileSystem.h"
#include "FocusController.h"
#include "Frame.h"
@@ -45,17 +46,20 @@
#include "InspectorController.h"
#include "InspectorTimelineAgent.h"
#include "Logging.h"
+#include "MediaCanStartListener.h"
#include "Navigator.h"
#include "NetworkStateNotifier.h"
#include "PageGroup.h"
#include "PluginData.h"
#include "PluginHalter.h"
+#include "PluginView.h"
#include "ProgressTracker.h"
-#include "RenderWidget.h"
#include "RenderTheme.h"
+#include "RenderWidget.h"
#include "ScriptController.h"
#include "SelectionController.h"
#include "Settings.h"
+#include "SharedBuffer.h"
#include "StringHash.h"
#include "TextResourceDecoder.h"
#include "Widget.h"
@@ -69,13 +73,17 @@
#endif
#if ENABLE(JAVASCRIPT_DEBUGGER)
-#include "JavaScriptDebugServer.h"
+#include "ScriptDebugServer.h"
#endif
#if ENABLE(WML)
#include "WMLPageState.h"
#endif
+#if ENABLE(CLIENT_BASED_GEOLOCATION)
+#include "GeolocationController.h"
+#endif
+
namespace WebCore {
static HashSet<Page*>* allPages;
@@ -100,7 +108,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)
@@ -113,6 +121,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))
@@ -127,16 +138,13 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
, m_areMemoryCacheClientCallsEnabled(true)
, m_mediaVolume(1)
, m_javaScriptURLsAreAllowed(true)
-#if ENABLE(INSPECTOR)
- , m_parentInspectorController(0)
-#endif
, m_didLoadUserStyleSheet(false)
, m_userStyleSheetModificationTime(0)
, m_group(0)
, m_debugger(0)
, m_customHTMLTokenizerTimeDelay(-1)
, m_customHTMLTokenizerChunkSize(-1)
- , m_canStartPlugins(true)
+ , m_canStartMedia(true)
{
#if !ENABLE(CONTEXT_MENUS)
UNUSED_PARAM(contextMenuClient);
@@ -147,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*>;
@@ -162,7 +174,7 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
}
#if ENABLE(JAVASCRIPT_DEBUGGER)
- JavaScriptDebugServer::shared().pageCreated(this);
+ ScriptDebugServer::shared().pageCreated(this);
#endif
#ifndef NDEBUG
@@ -181,8 +193,6 @@ Page::~Page()
m_editorClient->pageDestroyed();
#if ENABLE(INSPECTOR)
- if (m_parentInspectorController)
- m_parentInspectorController->pageDestroyed();
m_inspectorController->inspectedPageDestroyed();
#endif
@@ -277,26 +287,30 @@ void Page::goBackOrForward(int distance)
void Page::goToItem(HistoryItem* item, FrameLoadType type)
{
- // Abort any current load if we're going to a history item
-
- // Define what to do with any open database connections. By default we stop them and terminate the database thread.
- DatabasePolicy databasePolicy = DatabasePolicyStop;
+ // Abort any current load unless we're navigating the current document to a new state object
+ HistoryItem* currentItem = m_mainFrame->loader()->history()->currentItem();
+ if (!item->stateObject() || !currentItem || item->documentSequenceNumber() != currentItem->documentSequenceNumber() || item == currentItem) {
+ // Define what to do with any open database connections. By default we stop them and terminate the database thread.
+ DatabasePolicy databasePolicy = DatabasePolicyStop;
#if ENABLE(DATABASE)
- // If we're navigating the history via a fragment on the same document, then we do not want to stop databases.
- const KURL& currentURL = m_mainFrame->loader()->url();
- const KURL& newURL = item->url();
-
- if (newURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(currentURL, newURL))
- databasePolicy = DatabasePolicyContinue;
+ // If we're navigating the history via a fragment on the same document, then we do not want to stop databases.
+ const KURL& currentURL = m_mainFrame->loader()->url();
+ const KURL& newURL = item->url();
+
+ if (newURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(currentURL, newURL))
+ databasePolicy = DatabasePolicyContinue;
#endif
- m_mainFrame->loader()->stopAllLoaders(databasePolicy);
+
+ m_mainFrame->loader()->stopAllLoaders(databasePolicy);
+ }
+
m_mainFrame->loader()->history()->goToItem(item, type);
}
int Page::getHistoryLength()
{
- return m_backForwardList->backListCount() + 1;
+ return m_backForwardList->backListCount() + 1 + m_backForwardList->forwardListCount();
}
void Page::setGlobalHistoryItem(HistoryItem* item)
@@ -372,24 +386,44 @@ void Page::refreshPlugins(bool reload)
PluginData* Page::pluginData() const
{
- if (!settings()->arePluginsEnabled())
+ if (!mainFrame()->loader()->allowPlugins(NotAboutToInstantiatePlugin))
return 0;
if (!m_pluginData)
m_pluginData = PluginData::create(this);
return m_pluginData.get();
}
-void Page::addUnstartedPlugin(PluginView* view)
+void Page::addMediaCanStartListener(MediaCanStartListener* listener)
{
- ASSERT(!m_canStartPlugins);
- m_unstartedPlugins.add(view);
+ ASSERT(!m_canStartMedia);
+ ASSERT(!m_mediaCanStartListeners.contains(listener));
+ m_mediaCanStartListeners.add(listener);
}
-void Page::removeUnstartedPlugin(PluginView* view)
+void Page::removeMediaCanStartListener(MediaCanStartListener* listener)
{
- ASSERT(!m_canStartPlugins);
- ASSERT(m_unstartedPlugins.contains(view));
- m_unstartedPlugins.remove(view);
+ ASSERT(!m_canStartMedia);
+ ASSERT(m_mediaCanStartListeners.contains(listener));
+ m_mediaCanStartListeners.remove(listener);
+}
+
+void Page::setCanStartMedia(bool canStartMedia)
+{
+ if (m_canStartMedia == canStartMedia)
+ return;
+
+ m_canStartMedia = canStartMedia;
+
+ if (!m_canStartMedia || m_mediaCanStartListeners.isEmpty())
+ return;
+
+ Vector<MediaCanStartListener*> listeners;
+ copyToVector(m_mediaCanStartListeners, listeners);
+ m_mediaCanStartListeners.clear();
+
+ size_t size = listeners.size();
+ for (size_t i = 0; i < size; ++i)
+ listeners[i]->mediaCanStart();
}
static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
@@ -463,6 +497,9 @@ const VisibleSelection& Page::selection() const
void Page::setDefersLoading(bool defers)
{
+ if (!m_settings->loadDeferringEnabled())
+ return;
+
if (defers == m_defersLoading)
return;
@@ -542,7 +579,7 @@ void Page::userStyleSheetLocationChanged()
Vector<char> styleSheetAsUTF8;
if (base64Decode(encodedData, styleSheetAsUTF8))
- m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data());
+ m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data(), styleSheetAsUTF8.size());
}
for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
@@ -667,7 +704,7 @@ void Page::setDebugger(JSC::Debugger* debugger)
StorageNamespace* Page::sessionStorage(bool optionalCreate)
{
if (!m_sessionStorage && optionalCreate)
- m_sessionStorage = StorageNamespace::sessionStorageNamespace();
+ m_sessionStorage = StorageNamespace::sessionStorageNamespace(this);
return m_sessionStorage.get();
}
@@ -735,6 +772,35 @@ InspectorTimelineAgent* Page::inspectorTimelineAgent() const
}
#endif
+void Page::privateBrowsingStateChanged()
+{
+ bool privateBrowsingEnabled = m_settings->privateBrowsingEnabled();
+
+ // Collect the PluginViews in to a vector to ensure that action the plug-in takes
+ // from below privateBrowsingStateChanged does not affect their lifetime.
+
+ Vector<RefPtr<PluginView>, 32> pluginViews;
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ FrameView* view = frame->view();
+ if (!view)
+ return;
+
+ const HashSet<RefPtr<Widget> >* children = view->children();
+ ASSERT(children);
+
+ HashSet<RefPtr<Widget> >::const_iterator end = children->end();
+ for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
+ Widget* widget = (*it).get();
+ if (!widget->isPluginView())
+ continue;
+ pluginViews.append(static_cast<PluginView*>(widget));
+ }
+ }
+
+ for (size_t i = 0; i < pluginViews.size(); i++)
+ pluginViews[i]->privateBrowsingStateChanged(privateBrowsingEnabled);
+}
+
void Page::pluginAllowedRunTimeChanged()
{
if (m_pluginHalter)
@@ -753,4 +819,16 @@ void Page::didStopPlugin(HaltablePlugin* obj)
m_pluginHalter->didStopPlugin(obj);
}
+#if !ASSERT_DISABLED
+void Page::checkFrameCountConsistency() const
+{
+ ASSERT(m_frameCount >= 0);
+
+ int frameCount = 0;
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
+ ++frameCount;
+
+ ASSERT(m_frameCount + 1 == frameCount);
+}
+#endif
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/Page.h b/src/3rdparty/webkit/WebCore/page/Page.h
index 4886464..94e6dd5 100644
--- a/src/3rdparty/webkit/WebCore/page/Page.h
+++ b/src/3rdparty/webkit/WebCore/page/Page.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
*
* This library is free software; you can redistribute it and/or
@@ -21,29 +21,23 @@
#ifndef Page_h
#define Page_h
-#include "BackForwardList.h"
-#include "Chrome.h"
-#include "ContextMenuController.h"
#include "FrameLoaderTypes.h"
-#include "LinkHash.h"
#include "PlatformString.h"
+#include <wtf/Forward.h>
#include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
+#include <wtf/Noncopyable.h>
#if PLATFORM(MAC)
#include "SchedulePair.h"
#endif
-#if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS)) || (PLATFORM(QT) && defined(Q_WS_WIN))
-typedef struct HINSTANCE__* HINSTANCE;
-#endif
-
namespace JSC {
class Debugger;
}
namespace WebCore {
+ class BackForwardList;
class Chrome;
class ChromeClient;
class ContextMenuClient;
@@ -54,30 +48,36 @@ namespace WebCore {
class EditorClient;
class FocusController;
class Frame;
+ class GeolocationController;
+ class GeolocationControllerClient;
class HaltablePlugin;
+ class HistoryItem;
class InspectorClient;
class InspectorController;
class InspectorTimelineAgent;
+ class MediaCanStartListener;
class Node;
class PageGroup;
class PluginData;
class PluginHalter;
class PluginHalterClient;
- class PluginView;
class ProgressTracker;
class RenderTheme;
class VisibleSelection;
class SelectionController;
class Settings;
+
#if ENABLE(DOM_STORAGE)
class StorageNamespace;
#endif
-#if ENABLE(WML)
- class WMLPageState;
-#endif
#if ENABLE(NOTIFICATIONS)
class NotificationPresenter;
#endif
+#if ENABLE(WML)
+ class WMLPageState;
+#endif
+
+ typedef uint64_t LinkHash;
enum FindDirection { FindDirectionForward, FindDirectionBackward };
@@ -85,7 +85,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(); };
@@ -93,10 +93,10 @@ namespace WebCore {
static void refreshPlugins(bool reload);
PluginData* pluginData() const;
- void setCanStartPlugins(bool);
- bool canStartPlugins() const { return m_canStartPlugins; }
- void addUnstartedPlugin(PluginView*);
- void removeUnstartedPlugin(PluginView*);
+ void setCanStartMedia(bool);
+ bool canStartMedia() const { return m_canStartMedia; }
+ void addMediaCanStartListener(MediaCanStartListener*);
+ void removeMediaCanStartListener(MediaCanStartListener*);
EditorClient* editorClient() const { return m_editorClient; }
@@ -129,8 +129,8 @@ namespace WebCore {
PageGroup* groupPtr() { return m_group; } // can return 0
void incrementFrameCount() { ++m_frameCount; }
- void decrementFrameCount() { --m_frameCount; }
- int frameCount() const { return m_frameCount; }
+ void decrementFrameCount() { ASSERT(m_frameCount); --m_frameCount; }
+ int frameCount() const { checkFrameCountConsistency(); return m_frameCount; }
Chrome* chrome() const { return m_chrome.get(); }
SelectionController* dragCaretController() const { return m_dragCaretController.get(); }
@@ -144,13 +144,11 @@ 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(); }
-
-#if ENABLE(INSPECTOR)
- void setParentInspectorController(InspectorController* controller) { m_parentInspectorController = controller; }
- InspectorController* parentInspectorController() const { return m_parentInspectorController; }
-#endif
void setTabKeyCyclesThroughElements(bool b) { m_tabKeyCyclesThroughElements = b; }
bool tabKeyCyclesThroughElements() const { return m_tabKeyCyclesThroughElements; }
@@ -190,6 +188,8 @@ namespace WebCore {
void userStyleSheetLocationChanged();
const String& userStyleSheet() const;
+ void privateBrowsingStateChanged();
+
void didStartPlugin(HaltablePlugin*);
void didStopPlugin(HaltablePlugin*);
void pluginAllowedRunTimeChanged();
@@ -198,12 +198,6 @@ namespace WebCore {
void setDebugger(JSC::Debugger*);
JSC::Debugger* debugger() const { return m_debugger; }
-#if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS)) || (PLATFORM(QT) && defined(Q_WS_WIN))
- // The global DLL or application instance used for all windows.
- static void setInstanceHandle(HINSTANCE instanceHandle) { s_instanceHandle = instanceHandle; }
- static HINSTANCE instanceHandle() { return s_instanceHandle; }
-#endif
-
static void removeAllVisitedLinks();
static void allVisitedStateChanged(PageGroup*);
@@ -238,6 +232,12 @@ namespace WebCore {
private:
void initGroup();
+#if ASSERT_DISABLED
+ void checkFrameCountConsistency() const { }
+#else
+ void checkFrameCountConsistency() const;
+#endif
+
OwnPtr<Chrome> m_chrome;
OwnPtr<SelectionController> m_dragCaretController;
#if ENABLE(DRAG_SUPPORT)
@@ -250,6 +250,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;
@@ -278,10 +281,6 @@ namespace WebCore {
bool m_javaScriptURLsAreAllowed;
-#if ENABLE(INSPECTOR)
- InspectorController* m_parentInspectorController;
-#endif
-
String m_userStyleSheetPath;
mutable String m_userStyleSheet;
mutable bool m_didLoadUserStyleSheet;
@@ -295,8 +294,8 @@ namespace WebCore {
double m_customHTMLTokenizerTimeDelay;
int m_customHTMLTokenizerChunkSize;
- bool m_canStartPlugins;
- HashSet<PluginView*> m_unstartedPlugins;
+ bool m_canStartMedia;
+ HashSet<MediaCanStartListener*> m_mediaCanStartListeners;
OwnPtr<PluginHalter> m_pluginHalter;
@@ -304,10 +303,6 @@ namespace WebCore {
RefPtr<StorageNamespace> m_sessionStorage;
#endif
-#if PLATFORM(WIN) || (PLATFORM(WX) && defined(__WXMSW__)) || (PLATFORM(QT) && defined(Q_WS_WIN))
- static HINSTANCE s_instanceHandle;
-#endif
-
#if ENABLE(WML)
OwnPtr<WMLPageState> m_wmlPageState;
#endif
diff --git a/src/3rdparty/webkit/WebCore/page/PageGroup.cpp b/src/3rdparty/webkit/WebCore/page/PageGroup.cpp
index 427c240..f376d52 100644
--- a/src/3rdparty/webkit/WebCore/page/PageGroup.cpp
+++ b/src/3rdparty/webkit/WebCore/page/PageGroup.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "PageGroup.h"
+#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
#include "Frame.h"
@@ -50,7 +51,7 @@ static unsigned getUniqueIdentifier()
// --------
-static bool shouldTrackVisitedLinks;
+static bool shouldTrackVisitedLinks = false;
PageGroup::PageGroup(const String& name)
: m_name(name)
@@ -200,29 +201,29 @@ StorageNamespace* PageGroup::localStorage()
}
#endif
-void PageGroup::addUserScriptToWorld(unsigned worldID, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist,
+void PageGroup::addUserScriptToWorld(DOMWrapperWorld* world, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist,
PassOwnPtr<Vector<String> > blacklist, UserScriptInjectionTime injectionTime)
{
- if (worldID == UINT_MAX)
- return;
- OwnPtr<UserScript> userScript(new UserScript(source, url, whitelist, blacklist, worldID, injectionTime));
+ ASSERT_ARG(world, world);
+
+ OwnPtr<UserScript> userScript(new UserScript(source, url, whitelist, blacklist, injectionTime));
if (!m_userScripts)
m_userScripts.set(new UserScriptMap);
- UserScriptVector*& scriptsInWorld = m_userScripts->add(worldID, 0).first->second;
+ UserScriptVector*& scriptsInWorld = m_userScripts->add(world, 0).first->second;
if (!scriptsInWorld)
scriptsInWorld = new UserScriptVector;
scriptsInWorld->append(userScript.release());
}
-void PageGroup::addUserStyleSheetToWorld(unsigned worldID, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist,
+void PageGroup::addUserStyleSheetToWorld(DOMWrapperWorld* world, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist,
PassOwnPtr<Vector<String> > blacklist)
{
- if (worldID == UINT_MAX)
- return;
- OwnPtr<UserStyleSheet> userStyleSheet(new UserStyleSheet(source, url, whitelist, blacklist, worldID));
+ ASSERT_ARG(world, world);
+
+ OwnPtr<UserStyleSheet> userStyleSheet(new UserStyleSheet(source, url, whitelist, blacklist));
if (!m_userStyleSheets)
m_userStyleSheets.set(new UserStyleSheetMap);
- UserStyleSheetVector*& styleSheetsInWorld = m_userStyleSheets->add(worldID, 0).first->second;
+ UserStyleSheetVector*& styleSheetsInWorld = m_userStyleSheets->add(world, 0).first->second;
if (!styleSheetsInWorld)
styleSheetsInWorld = new UserStyleSheetVector;
styleSheetsInWorld->append(userStyleSheet.release());
@@ -235,12 +236,14 @@ void PageGroup::addUserStyleSheetToWorld(unsigned worldID, const String& source,
}
}
-void PageGroup::removeUserScriptFromWorld(unsigned worldID, const KURL& url)
+void PageGroup::removeUserScriptFromWorld(DOMWrapperWorld* world, const KURL& url)
{
+ ASSERT_ARG(world, world);
+
if (!m_userScripts)
return;
- UserScriptMap::iterator it = m_userScripts->find(worldID);
+ UserScriptMap::iterator it = m_userScripts->find(world);
if (it == m_userScripts->end())
return;
@@ -257,12 +260,14 @@ void PageGroup::removeUserScriptFromWorld(unsigned worldID, const KURL& url)
m_userScripts->remove(it);
}
-void PageGroup::removeUserStyleSheetFromWorld(unsigned worldID, const KURL& url)
+void PageGroup::removeUserStyleSheetFromWorld(DOMWrapperWorld* world, const KURL& url)
{
+ ASSERT_ARG(world, world);
+
if (!m_userStyleSheets)
return;
- UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID);
+ UserStyleSheetMap::iterator it = m_userStyleSheets->find(world);
bool sheetsChanged = false;
if (it == m_userStyleSheets->end())
return;
@@ -291,12 +296,14 @@ void PageGroup::removeUserStyleSheetFromWorld(unsigned worldID, const KURL& url)
}
}
-void PageGroup::removeUserScriptsFromWorld(unsigned worldID)
+void PageGroup::removeUserScriptsFromWorld(DOMWrapperWorld* world)
{
+ ASSERT_ARG(world, world);
+
if (!m_userScripts)
return;
- UserScriptMap::iterator it = m_userScripts->find(worldID);
+ UserScriptMap::iterator it = m_userScripts->find(world);
if (it == m_userScripts->end())
return;
@@ -304,12 +311,14 @@ void PageGroup::removeUserScriptsFromWorld(unsigned worldID)
m_userScripts->remove(it);
}
-void PageGroup::removeUserStyleSheetsFromWorld(unsigned worldID)
+void PageGroup::removeUserStyleSheetsFromWorld(DOMWrapperWorld* world)
{
+ ASSERT_ARG(world, world);
+
if (!m_userStyleSheets)
return;
- UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID);
+ UserStyleSheetMap::iterator it = m_userStyleSheets->find(world);
if (it == m_userStyleSheets->end())
return;
diff --git a/src/3rdparty/webkit/WebCore/page/PageGroup.h b/src/3rdparty/webkit/WebCore/page/PageGroup.h
index c233cd1..446f0c7 100644
--- a/src/3rdparty/webkit/WebCore/page/PageGroup.h
+++ b/src/3rdparty/webkit/WebCore/page/PageGroup.h
@@ -70,17 +70,17 @@ namespace WebCore {
bool hasLocalStorage() { return m_localStorage; }
#endif
- void addUserScriptToWorld(unsigned worldID, const String& source, const KURL&,
+ void addUserScriptToWorld(DOMWrapperWorld*, const String& source, const KURL&,
PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist,
UserScriptInjectionTime);
- void addUserStyleSheetToWorld(unsigned worldID, const String& source, const KURL&,
+ void addUserStyleSheetToWorld(DOMWrapperWorld*, const String& source, const KURL&,
PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist);
- void removeUserScriptFromWorld(unsigned, const KURL&);
- void removeUserStyleSheetFromWorld(unsigned, const KURL&);
+ void removeUserScriptFromWorld(DOMWrapperWorld*, const KURL&);
+ void removeUserStyleSheetFromWorld(DOMWrapperWorld*, const KURL&);
- void removeUserScriptsFromWorld(unsigned);
- void removeUserStyleSheetsFromWorld(unsigned);
+ void removeUserScriptsFromWorld(DOMWrapperWorld*);
+ void removeUserStyleSheetsFromWorld(DOMWrapperWorld*);
void removeAllUserContent();
diff --git a/src/3rdparty/webkit/WebCore/page/PluginHalter.cpp b/src/3rdparty/webkit/WebCore/page/PluginHalter.cpp
index 63f5469..c0a6452 100644
--- a/src/3rdparty/webkit/WebCore/page/PluginHalter.cpp
+++ b/src/3rdparty/webkit/WebCore/page/PluginHalter.cpp
@@ -28,6 +28,7 @@
#include "PluginHalter.h"
#include "HaltablePlugin.h"
+#include "PlatformString.h"
#include <wtf/CurrentTime.h>
#include <wtf/Vector.h>
@@ -93,7 +94,7 @@ void PluginHalter::timerFired(Timer<PluginHalter>*)
continue;
}
- if (m_client->shouldHaltPlugin(plugins[i]->node()))
+ if (m_client->shouldHaltPlugin(plugins[i]->node(), plugins[i]->isWindowed(), plugins[i]->pluginName()))
plugins[i]->halt();
m_plugins.remove(plugins[i]);
diff --git a/src/3rdparty/webkit/WebCore/page/PluginHalter.h b/src/3rdparty/webkit/WebCore/page/PluginHalter.h
index eddce34..af8b31e 100644
--- a/src/3rdparty/webkit/WebCore/page/PluginHalter.h
+++ b/src/3rdparty/webkit/WebCore/page/PluginHalter.h
@@ -35,7 +35,7 @@ namespace WebCore {
class HaltablePlugin;
-class PluginHalter {
+class PluginHalter : public Noncopyable {
public:
PluginHalter(PluginHalterClient*);
diff --git a/src/3rdparty/webkit/WebCore/page/PluginHalterClient.h b/src/3rdparty/webkit/WebCore/page/PluginHalterClient.h
index f77091f..0251547 100644
--- a/src/3rdparty/webkit/WebCore/page/PluginHalterClient.h
+++ b/src/3rdparty/webkit/WebCore/page/PluginHalterClient.h
@@ -29,12 +29,13 @@
namespace WebCore {
class Node;
+class String;
class PluginHalterClient {
public:
virtual ~PluginHalterClient() { }
- virtual bool shouldHaltPlugin(Node*) const = 0;
+ virtual bool shouldHaltPlugin(Node*, bool isWindowed, const String& pluginName) const = 0;
virtual bool enabled() const = 0;
};
diff --git a/src/3rdparty/webkit/WebCore/page/PositionCallback.h b/src/3rdparty/webkit/WebCore/page/PositionCallback.h
index 9f36d7a..5b7a202 100644
--- a/src/3rdparty/webkit/WebCore/page/PositionCallback.h
+++ b/src/3rdparty/webkit/WebCore/page/PositionCallback.h
@@ -26,7 +26,6 @@
#ifndef PositionCallback_h
#define PositionCallback_h
-#include <wtf/Platform.h>
#include <wtf/RefCounted.h>
namespace WebCore {
diff --git a/src/3rdparty/webkit/WebCore/page/PositionError.h b/src/3rdparty/webkit/WebCore/page/PositionError.h
index f6f56f0..1467170 100644
--- a/src/3rdparty/webkit/WebCore/page/PositionError.h
+++ b/src/3rdparty/webkit/WebCore/page/PositionError.h
@@ -35,7 +35,6 @@ namespace WebCore {
class PositionError : public RefCounted<PositionError> {
public:
enum ErrorCode {
- UNKNOWN_ERROR = 0,
PERMISSION_DENIED = 1,
POSITION_UNAVAILABLE = 2,
TIMEOUT = 3
diff --git a/src/3rdparty/webkit/WebCore/page/PositionError.idl b/src/3rdparty/webkit/WebCore/page/PositionError.idl
index cb2ef5e..5870e0d 100644
--- a/src/3rdparty/webkit/WebCore/page/PositionError.idl
+++ b/src/3rdparty/webkit/WebCore/page/PositionError.idl
@@ -25,13 +25,10 @@
module core {
- interface [
- GenerateConstructor
- ] PositionError {
+ interface [Conditional=GEOLOCATION] PositionError {
readonly attribute unsigned short code;
readonly attribute DOMString message;
- const unsigned short UNKNOWN_ERROR = 0;
const unsigned short PERMISSION_DENIED = 1;
const unsigned short POSITION_UNAVAILABLE = 2;
const unsigned short TIMEOUT = 3;
diff --git a/src/3rdparty/webkit/WebCore/page/PositionErrorCallback.h b/src/3rdparty/webkit/WebCore/page/PositionErrorCallback.h
index c23e883..e784297 100644
--- a/src/3rdparty/webkit/WebCore/page/PositionErrorCallback.h
+++ b/src/3rdparty/webkit/WebCore/page/PositionErrorCallback.h
@@ -26,7 +26,6 @@
#ifndef PositionErrorCallback_h
#define PositionErrorCallback_h
-#include <wtf/Platform.h>
#include <wtf/RefCounted.h>
namespace WebCore {
diff --git a/src/3rdparty/webkit/WebCore/page/PrintContext.cpp b/src/3rdparty/webkit/WebCore/page/PrintContext.cpp
index 4d3a839..b6806eb 100644
--- a/src/3rdparty/webkit/WebCore/page/PrintContext.cpp
+++ b/src/3rdparty/webkit/WebCore/page/PrintContext.cpp
@@ -45,6 +45,11 @@ int PrintContext::pageCount() const
return m_pageRects.size();
}
+const IntRect& PrintContext::pageRect(int pageNumber) const
+{
+ return m_pageRects[pageNumber];
+}
+
void PrintContext::computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight)
{
m_pageRects.clear();
@@ -60,11 +65,6 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig
return;
}
- if (userScaleFactor <= 0) {
- LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
- return;
- }
-
float ratio = printRect.height() / printRect.width();
float pageWidth = (float)root->rightLayoutOverflow();
@@ -77,14 +77,31 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig
return;
}
- float currPageHeight = pageHeight / userScaleFactor;
+ computePageRectsWithPageSize(FloatSize(pageWidth, pageHeight), userScaleFactor);
+}
+
+void PrintContext::computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, float userScaleFactor)
+{
+ RenderView* root = toRenderView(m_frame->document()->renderer());
+
+ if (!root) {
+ LOG_ERROR("document to be printed has no renderer");
+ return;
+ }
+
+ if (userScaleFactor <= 0) {
+ LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
+ return;
+ }
+
+ float currPageHeight = pageSizeInPixels.height() / userScaleFactor;
float docHeight = root->layer()->height();
- float currPageWidth = pageWidth / userScaleFactor;
+ float currPageWidth = pageSizeInPixels.width() / userScaleFactor;
// always return at least one page, since empty files should print a blank page
- float printedPagesHeight = 0.0;
+ float printedPagesHeight = 0;
do {
- float proposedBottom = std::min(docHeight, printedPagesHeight + pageHeight);
+ float proposedBottom = std::min(docHeight, printedPagesHeight + pageSizeInPixels.height());
m_frame->view()->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
@@ -134,4 +151,54 @@ void PrintContext::end()
m_frame->setPrinting(false, 0, 0, true);
}
+static RenderBoxModelObject* enclosingBoxModelObject(RenderObject* object)
+{
+
+ while (object && !object->isBoxModelObject())
+ object = object->parent();
+ if (!object)
+ return 0;
+ return toRenderBoxModelObject(object);
+}
+
+int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSizeInPixels)
+{
+ // Make sure the element is not freed during the layout.
+ RefPtr<Element> elementRef(element);
+ element->document()->updateLayout();
+
+ RenderBoxModelObject* box = enclosingBoxModelObject(element->renderer());
+ if (!box)
+ return -1;
+
+ Frame* frame = element->document()->frame();
+ FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
+ PrintContext printContext(frame);
+ printContext.begin(pageRect.width());
+ printContext.computePageRectsWithPageSize(pageSizeInPixels, 1);
+
+ int top = box->offsetTop();
+ int left = box->offsetLeft();
+ int pageNumber = 0;
+ for (; pageNumber < printContext.pageCount(); pageNumber++) {
+ const IntRect& page = printContext.pageRect(pageNumber);
+ if (page.x() <= left && left < page.right() && page.y() <= top && top < page.bottom())
+ break;
+ }
+ printContext.end();
+ return (pageNumber < printContext.pageCount() ? pageNumber : -1);
+}
+
+int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels)
+{
+ frame->document()->updateLayout();
+
+ FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
+ PrintContext printContext(frame);
+ printContext.begin(pageRect.width());
+ printContext.computePageRectsWithPageSize(pageSizeInPixels, 1);
+ printContext.end();
+ return printContext.pageCount();
+}
+
}
diff --git a/src/3rdparty/webkit/WebCore/page/PrintContext.h b/src/3rdparty/webkit/WebCore/page/PrintContext.h
index 0b3b303..ec15b84 100644
--- a/src/3rdparty/webkit/WebCore/page/PrintContext.h
+++ b/src/3rdparty/webkit/WebCore/page/PrintContext.h
@@ -25,8 +25,10 @@
namespace WebCore {
+class Element;
class Frame;
class FloatRect;
+class FloatSize;
class GraphicsContext;
class IntRect;
@@ -36,6 +38,8 @@ public:
~PrintContext();
int pageCount() const;
+ const IntRect& pageRect(int pageNumber) const;
+ const Vector<IntRect>& pageRects() const { return m_pageRects; }
void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight);
@@ -47,7 +51,13 @@ public:
void end();
+ // Used by layout tests.
+ static int pageNumberForElement(Element*, const FloatSize& pageSizeInPixels);
+ static int numberOfPages(Frame*, const FloatSize& pageSizeInPixels);
+
protected:
+ void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, float userScaleFactor);
+
Frame* m_frame;
Vector<IntRect> m_pageRects;
};
diff --git a/src/3rdparty/webkit/WebCore/page/Screen.idl b/src/3rdparty/webkit/WebCore/page/Screen.idl
index ca7d20d..cd181eb 100644
--- a/src/3rdparty/webkit/WebCore/page/Screen.idl
+++ b/src/3rdparty/webkit/WebCore/page/Screen.idl
@@ -29,7 +29,7 @@
module window {
- interface Screen {
+ interface [OmitConstructor] Screen {
readonly attribute unsigned long height;
readonly attribute unsigned long width;
readonly attribute unsigned long colorDepth;
diff --git a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp
index 338bf9f..c0b3e22 100644
--- a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp
+++ b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp
@@ -65,37 +65,37 @@ static URLSchemesMap& localSchemes()
return localSchemes;
}
-static URLSchemesMap& noAccessSchemes()
+static URLSchemesMap& secureSchemes()
{
- DEFINE_STATIC_LOCAL(URLSchemesMap, noAccessSchemes, ());
+ DEFINE_STATIC_LOCAL(URLSchemesMap, secureSchemes, ());
- if (noAccessSchemes.isEmpty())
- noAccessSchemes.add("data");
+ if (secureSchemes.isEmpty()) {
+ secureSchemes.add("https");
+ secureSchemes.add("about");
+ secureSchemes.add("data");
+ }
- return noAccessSchemes;
+ return secureSchemes;
}
-bool SecurityOrigin::isDefaultPortForProtocol(unsigned short port, const String& protocol)
+static URLSchemesMap& schemesWithUniqueOrigins()
{
- if (protocol.isEmpty())
- return false;
+ DEFINE_STATIC_LOCAL(URLSchemesMap, schemesWithUniqueOrigins, ());
- typedef HashMap<String, unsigned> DefaultPortsMap;
- DEFINE_STATIC_LOCAL(DefaultPortsMap, defaultPorts, ());
- if (defaultPorts.isEmpty()) {
- defaultPorts.set("http", 80);
- defaultPorts.set("https", 443);
- defaultPorts.set("ftp", 21);
- defaultPorts.set("ftps", 990);
- }
- return defaultPorts.get(protocol) == port;
+ // This is a willful violation of HTML5.
+ // See https://bugs.webkit.org/show_bug.cgi?id=11885
+ if (schemesWithUniqueOrigins.isEmpty())
+ schemesWithUniqueOrigins.add("data");
+
+ return schemesWithUniqueOrigins;
}
-SecurityOrigin::SecurityOrigin(const KURL& url)
- : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower())
+SecurityOrigin::SecurityOrigin(const KURL& url, SandboxFlags sandboxFlags)
+ : m_sandboxFlags(sandboxFlags)
+ , m_protocol(url.protocol().isNull() ? "" : url.protocol().lower())
, m_host(url.host().isNull() ? "" : url.host().lower())
, m_port(url.port())
- , m_noAccess(false)
+ , m_isUnique(isSandboxed(SandboxOrigin) || shouldTreatURLSchemeAsNoAccess(m_protocol))
, m_universalAccess(false)
, m_domainWasSetInDOM(false)
{
@@ -103,26 +103,29 @@ SecurityOrigin::SecurityOrigin(const KURL& url)
if (m_protocol == "about" || m_protocol == "javascript")
m_protocol = "";
- // Some URLs are not allowed access to anything other than themselves.
- if (shouldTreatURLSchemeAsNoAccess(m_protocol))
- m_noAccess = true;
-
// document.domain starts as m_host, but can be set by the DOM.
m_domain = m_host;
// By default, only local SecurityOrigins can load local resources.
m_canLoadLocalResources = isLocal();
+ if (m_canLoadLocalResources) {
+ // Directories should never be readable.
+ if (!url.hasPath() || url.path().endsWith("/"))
+ m_isUnique = true;
+ }
if (isDefaultPortForProtocol(m_port, m_protocol))
m_port = 0;
}
SecurityOrigin::SecurityOrigin(const SecurityOrigin* other)
- : m_protocol(other->m_protocol.threadsafeCopy())
+ : m_sandboxFlags(other->m_sandboxFlags)
+ , m_protocol(other->m_protocol.threadsafeCopy())
, m_host(other->m_host.threadsafeCopy())
+ , m_encodedHost(other->m_encodedHost.threadsafeCopy())
, m_domain(other->m_domain.threadsafeCopy())
, m_port(other->m_port)
- , m_noAccess(other->m_noAccess)
+ , m_isUnique(other->m_isUnique)
, m_universalAccess(other->m_universalAccess)
, m_domainWasSetInDOM(other->m_domainWasSetInDOM)
, m_canLoadLocalResources(other->m_canLoadLocalResources)
@@ -134,11 +137,11 @@ bool SecurityOrigin::isEmpty() const
return m_protocol.isEmpty();
}
-PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url)
+PassRefPtr<SecurityOrigin> SecurityOrigin::create(const KURL& url, SandboxFlags sandboxFlags)
{
if (!url.isValid())
- return adoptRef(new SecurityOrigin(KURL()));
- return adoptRef(new SecurityOrigin(url));
+ return adoptRef(new SecurityOrigin(KURL(), sandboxFlags));
+ return adoptRef(new SecurityOrigin(url, sandboxFlags));
}
PassRefPtr<SecurityOrigin> SecurityOrigin::createEmpty()
@@ -157,20 +160,45 @@ void SecurityOrigin::setDomainFromDOM(const String& newDomain)
m_domain = newDomain.lower();
}
+static HashSet<String>& schemesForbiddenFromDomainRelaxation()
+{
+ DEFINE_STATIC_LOCAL(HashSet<String>, schemes, ());
+ return schemes;
+}
+
+void SecurityOrigin::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String& scheme)
+{
+ if (scheme.isEmpty())
+ return;
+
+ if (forbidden)
+ schemesForbiddenFromDomainRelaxation().add(scheme);
+ else
+ schemesForbiddenFromDomainRelaxation().remove(scheme);
+}
+
+bool SecurityOrigin::isDomainRelaxationForbiddenForURLScheme(const String& scheme)
+{
+ if (scheme.isEmpty())
+ return false;
+
+ return schemesForbiddenFromDomainRelaxation().contains(scheme);
+}
+
bool SecurityOrigin::canAccess(const SecurityOrigin* other) const
{
if (m_universalAccess)
return true;
- if (m_noAccess || other->m_noAccess)
+ if (isUnique() || other->isUnique())
return false;
// Here are two cases where we should permit access:
//
- // 1) Neither document has set document.domain. In this case, we insist
+ // 1) Neither document has set document.domain. In this case, we insist
// that the scheme, host, and port of the URLs match.
//
- // 2) Both documents have set document.domain. In this case, we insist
+ // 2) Both documents have set document.domain. In this case, we insist
// that the documents have set document.domain to the same value and
// that the scheme of the URLs match.
//
@@ -203,10 +231,12 @@ bool SecurityOrigin::canRequest(const KURL& url) const
if (m_universalAccess)
return true;
- if (m_noAccess)
+ if (isUnique())
return false;
RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url);
+ if (targetOrigin->isUnique())
+ return false;
// We call isSameSchemeHostPort here instead of canAccess because we want
// to ignore document.domain effects.
@@ -228,11 +258,12 @@ bool SecurityOrigin::taintsCanvas(const KURL& url) const
if (canRequest(url))
return false;
- // This method exists because we treat data URLs as noAccess, contrary
- // to the current (9/19/2009) draft of the HTML5 specification. We still
- // want to let folks paint data URLs onto untainted canvases, so we special
- // case data URLs below. If we change to match HTML5 w.r.t. data URL
- // security, then we can remove this method in favor of !canRequest.
+ // This function exists because we treat data URLs as having a unique origin,
+ // contrary to the current (9/19/2009) draft of the HTML5 specification.
+ // We still want to let folks paint data URLs onto untainted canvases, so
+ // we special case data URLs below. If we change to match HTML5 w.r.t.
+ // data URL security, then we can remove this function in favor of
+ // !canRequest.
if (url.protocolIs("data"))
return false;
@@ -255,8 +286,8 @@ bool SecurityOrigin::canLoad(const KURL& url, const String& referrer, Document*
void SecurityOrigin::grantLoadLocalResources()
{
- // This method exists only to support backwards compatibility with older
- // versions of WebKit. Granting privileges to some, but not all, documents
+ // This function exists only to support backwards compatibility with older
+ // versions of WebKit. Granting privileges to some, but not all, documents
// in a SecurityOrigin is a security hazard because the documents without
// the privilege can obtain the privilege by injecting script into the
// documents that have been granted the privilege.
@@ -269,6 +300,11 @@ void SecurityOrigin::grantUniversalAccess()
m_universalAccess = true;
}
+void SecurityOrigin::makeUnique()
+{
+ m_isUnique = true;
+}
+
bool SecurityOrigin::isLocal() const
{
return shouldTreatURLSchemeAsLocal(m_protocol);
@@ -289,7 +325,7 @@ String SecurityOrigin::toString() const
if (isEmpty())
return "null";
- if (m_noAccess)
+ if (isUnique())
return "null";
if (m_protocol == "file")
@@ -346,13 +382,92 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const St
// Split out the 3 sections of data
String protocol = databaseIdentifier.substring(0, separator1);
String host = databaseIdentifier.substring(separator1 + 1, separator2 - separator1 - 1);
+
+ host = decodeURLEscapeSequences(host);
return create(KURL(KURL(), protocol + "://" + host + ":" + String::number(port)));
}
+// The following lower-ASCII characters need escaping to be used in a filename
+// across all systems, including Windows:
+// - Unprintable ASCII (00-1F)
+// - Space (20)
+// - Double quote (22)
+// - Percent (25) (escaped because it is our escape character)
+// - Asterisk (2A)
+// - Slash (2F)
+// - Colon (3A)
+// - Less-than (3C)
+// - Greater-than (3E)
+// - Question Mark (3F)
+// - Backslash (5C)
+// - Pipe (7C)
+// - Delete (7F)
+
+static const bool needsEscaping[128] = {
+ /* 00-07 */ true, true, true, true, true, true, true, true,
+ /* 08-0F */ true, true, true, true, true, true, true, true,
+
+ /* 10-17 */ true, true, true, true, true, true, true, true,
+ /* 18-1F */ true, true, true, true, true, true, true, true,
+
+ /* 20-27 */ true, false, true, false, false, true, false, false,
+ /* 28-2F */ false, false, true, false, false, false, false, true,
+
+ /* 30-37 */ false, false, false, false, false, false, false, false,
+ /* 38-3F */ false, false, true, false, true, false, true, true,
+
+ /* 40-47 */ false, false, false, false, false, false, false, false,
+ /* 48-4F */ false, false, false, false, false, false, false, false,
+
+ /* 50-57 */ false, false, false, false, false, false, false, false,
+ /* 58-5F */ false, false, false, false, true, false, false, false,
+
+ /* 60-67 */ false, false, false, false, false, false, false, false,
+ /* 68-6F */ false, false, false, false, false, false, false, false,
+
+ /* 70-77 */ false, false, false, false, false, false, false, false,
+ /* 78-7F */ false, false, false, false, true, false, false, true,
+};
+
+static inline bool shouldEscapeUChar(UChar c)
+{
+ return c > 127 ? false : needsEscaping[c];
+}
+
+static const char hexDigits[17] = "0123456789ABCDEF";
+
+static String encodedHost(const String& host)
+{
+ unsigned length = host.length();
+ Vector<UChar, 512> buffer(length * 3 + 1);
+ UChar* p = buffer.data();
+
+ const UChar* str = host.characters();
+ const UChar* strEnd = str + length;
+
+ while (str < strEnd) {
+ UChar c = *str++;
+ if (shouldEscapeUChar(c)) {
+ *p++ = '%';
+ *p++ = hexDigits[(c >> 4) & 0xF];
+ *p++ = hexDigits[c & 0xF];
+ } else
+ *p++ = c;
+ }
+
+ ASSERT(p - buffer.data() <= static_cast<int>(buffer.size()));
+
+ return String(buffer.data(), p - buffer.data());
+}
+
String SecurityOrigin::databaseIdentifier() const
{
- DEFINE_STATIC_LOCAL(String, separatorString, (&SeparatorCharacter, 1));
- return m_protocol + separatorString + m_host + separatorString + String::number(m_port);
+ String separatorString(&SeparatorCharacter, 1);
+
+ if (m_encodedHost.isEmpty())
+ m_encodedHost = encodedHost(m_host);
+
+ return m_protocol + separatorString + m_encodedHost + separatorString + String::number(m_port);
}
bool SecurityOrigin::equal(const SecurityOrigin* other) const
@@ -399,14 +514,10 @@ void SecurityOrigin::removeURLSchemeRegisteredAsLocal(const String& scheme)
if (scheme == "applewebdata")
return;
#endif
-#if PLATFORM(QT)
- if (scheme == "qrc")
- return;
-#endif
localSchemes().remove(scheme);
}
-const URLSchemesMap& SecurityOrigin::localURLSchemes()
+const URLSchemesMap& SecurityOrigin::localURLSchemes()
{
return localSchemes();
}
@@ -451,12 +562,22 @@ bool SecurityOrigin::shouldTreatURLSchemeAsLocal(const String& scheme)
void SecurityOrigin::registerURLSchemeAsNoAccess(const String& scheme)
{
- noAccessSchemes().add(scheme);
+ schemesWithUniqueOrigins().add(scheme);
}
bool SecurityOrigin::shouldTreatURLSchemeAsNoAccess(const String& scheme)
{
- return noAccessSchemes().contains(scheme);
+ return schemesWithUniqueOrigins().contains(scheme);
+}
+
+void SecurityOrigin::registerURLSchemeAsSecure(const String& scheme)
+{
+ secureSchemes().add(scheme);
+}
+
+bool SecurityOrigin::shouldTreatURLSchemeAsSecure(const String& scheme)
+{
+ return secureSchemes().contains(scheme);
}
bool SecurityOrigin::shouldHideReferrer(const KURL& url, const String& referrer)
diff --git a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h
index 6d4ce1f..11c213e 100644
--- a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h
+++ b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h
@@ -34,152 +34,184 @@
#include <wtf/PassRefPtr.h>
#include <wtf/Threading.h>
+#include "FrameLoaderTypes.h"
#include "PlatformString.h"
#include "StringHash.h"
namespace WebCore {
- typedef HashSet<String, CaseFoldingHash> URLSchemesMap;
-
- class Document;
- class KURL;
-
- class SecurityOrigin : public ThreadSafeShared<SecurityOrigin> {
- public:
- static PassRefPtr<SecurityOrigin> createFromDatabaseIdentifier(const String&);
- static PassRefPtr<SecurityOrigin> createFromString(const String&);
- static PassRefPtr<SecurityOrigin> create(const KURL&);
- static PassRefPtr<SecurityOrigin> createEmpty();
-
- // Create a deep copy of this SecurityOrigin. This method is useful
- // when marshalling a SecurityOrigin to another thread.
- PassRefPtr<SecurityOrigin> threadsafeCopy();
-
- // Set the domain property of this security origin to newDomain. This
- // function does not check whether newDomain is a suffix of the current
- // domain. The caller is responsible for validating newDomain.
- void setDomainFromDOM(const String& newDomain);
- bool domainWasSetInDOM() const { return m_domainWasSetInDOM; }
-
- String protocol() const { return m_protocol; }
- String host() const { return m_host; }
- String domain() const { return m_domain; }
- unsigned short port() const { return m_port; }
-
- // Returns true if this SecurityOrigin can script objects in the given
- // SecurityOrigin. For example, call this function before allowing
- // script from one security origin to read or write objects from
- // another SecurityOrigin.
- bool canAccess(const SecurityOrigin*) const;
-
- // Returns true if this SecurityOrigin can read content retrieved from
- // the given URL. For example, call this function before issuing
- // XMLHttpRequests.
- bool canRequest(const KURL&) const;
-
- // Returns true if drawing an image from this URL taints a canvas from
- // this security origin. For example, call this function before
- // drawing an image onto an HTML canvas element with the drawImage API.
- bool taintsCanvas(const KURL&) const;
-
- // Returns true for any non-local URL. If document parameter is supplied,
- // its local load policy dictates, otherwise if referrer is non-empty and
- // represents a local file, then the local load is allowed.
- static bool canLoad(const KURL&, const String& referrer, Document* document);
-
- // Returns true if this SecurityOrigin can load local resources, such
- // as images, iframes, and style sheets, and can link to local URLs.
- // For example, call this function before creating an iframe to a
- // file:// URL.
- //
- // Note: A SecurityOrigin might be allowed to load local resources
- // without being able to issue an XMLHttpRequest for a local URL.
- // To determine whether the SecurityOrigin can issue an
- // XMLHttpRequest for a URL, call canRequest(url).
- bool canLoadLocalResources() const { return m_canLoadLocalResources; }
-
- // Explicitly grant the ability to load local resources to this
- // SecurityOrigin.
- //
- // Note: This method exists only to support backwards compatibility
- // with older versions of WebKit.
- void grantLoadLocalResources();
-
- // Explicitly grant the ability to access very other SecurityOrigin.
- //
- // WARNING: This is an extremely powerful ability. Use with caution!
- void grantUniversalAccess();
-
- bool isSecureTransitionTo(const KURL&) const;
-
- // The local SecurityOrigin is the most privileged SecurityOrigin.
- // The local SecurityOrigin can script any document, navigate to local
- // resources, and can set arbitrary headers on XMLHttpRequests.
- bool isLocal() const;
-
- // The empty SecurityOrigin is the least privileged SecurityOrigin.
- bool isEmpty() const;
-
- // Convert this SecurityOrigin into a string. The string
- // representation of a SecurityOrigin is similar to a URL, except it
- // lacks a path component. The string representation does not encode
- // the value of the SecurityOrigin's domain property. The empty
- // SecurityOrigin is represented with the string "null".
- String toString() const;
-
- // Serialize the security origin to a string that could be used as part of
- // file names. This format should be used in storage APIs only.
- String databaseIdentifier() const;
-
- // This method checks for equality between SecurityOrigins, not whether
- // one origin can access another. It is used for hash table keys.
- // For access checks, use canAccess().
- // FIXME: If this method is really only useful for hash table keys, it
- // should be refactored into SecurityOriginHash.
- bool equal(const SecurityOrigin*) const;
-
- // This method checks for equality, ignoring the value of document.domain
- // (and whether it was set) but considering the host. It is used for postMessage.
- bool isSameSchemeHostPort(const SecurityOrigin*) const;
-
- static void registerURLSchemeAsLocal(const String&);
- static void removeURLSchemeRegisteredAsLocal(const String&);
- static const URLSchemesMap& localURLSchemes();
- static bool shouldTreatURLAsLocal(const String&);
- static bool shouldTreatURLSchemeAsLocal(const String&);
-
- static bool shouldHideReferrer(const KURL&, const String& referrer);
-
- enum LocalLoadPolicy {
- AllowLocalLoadsForAll, // No restriction on local loads.
- AllowLocalLoadsForLocalAndSubstituteData,
- AllowLocalLoadsForLocalOnly,
- };
- static void setLocalLoadPolicy(LocalLoadPolicy);
- static bool restrictAccessToLocal();
- static bool allowSubstituteDataAccessToLocal();
-
- static void registerURLSchemeAsNoAccess(const String&);
- static bool shouldTreatURLSchemeAsNoAccess(const String&);
-
- static void whiteListAccessFromOrigin(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains);
- static void resetOriginAccessWhiteLists();
-
- static bool isDefaultPortForProtocol(unsigned short port, const String& protocol);
-
- private:
- explicit SecurityOrigin(const KURL&);
- explicit SecurityOrigin(const SecurityOrigin*);
-
- String m_protocol;
- String m_host;
- String m_domain;
- unsigned short m_port;
- bool m_noAccess;
- bool m_universalAccess;
- bool m_domainWasSetInDOM;
- bool m_canLoadLocalResources;
+typedef HashSet<String, CaseFoldingHash> URLSchemesMap;
+
+class Document;
+class KURL;
+
+class SecurityOrigin : public ThreadSafeShared<SecurityOrigin> {
+public:
+ static PassRefPtr<SecurityOrigin> createFromDatabaseIdentifier(const String&);
+ static PassRefPtr<SecurityOrigin> createFromString(const String&);
+ static PassRefPtr<SecurityOrigin> create(const KURL&, SandboxFlags = SandboxNone);
+ static PassRefPtr<SecurityOrigin> createEmpty();
+
+ // Create a deep copy of this SecurityOrigin. This method is useful
+ // when marshalling a SecurityOrigin to another thread.
+ PassRefPtr<SecurityOrigin> threadsafeCopy();
+
+ // Set the domain property of this security origin to newDomain. This
+ // function does not check whether newDomain is a suffix of the current
+ // domain. The caller is responsible for validating newDomain.
+ void setDomainFromDOM(const String& newDomain);
+ bool domainWasSetInDOM() const { return m_domainWasSetInDOM; }
+
+ static void setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String&);
+ static bool isDomainRelaxationForbiddenForURLScheme(const String&);
+
+ String protocol() const { return m_protocol; }
+ String host() const { return m_host; }
+ String domain() const { return m_domain; }
+ unsigned short port() const { return m_port; }
+
+ // Returns true if this SecurityOrigin can script objects in the given
+ // SecurityOrigin. For example, call this function before allowing
+ // script from one security origin to read or write objects from
+ // another SecurityOrigin.
+ bool canAccess(const SecurityOrigin*) const;
+
+ // Returns true if this SecurityOrigin can read content retrieved from
+ // the given URL. For example, call this function before issuing
+ // XMLHttpRequests.
+ bool canRequest(const KURL&) const;
+
+ // Returns true if drawing an image from this URL taints a canvas from
+ // this security origin. For example, call this function before
+ // drawing an image onto an HTML canvas element with the drawImage API.
+ bool taintsCanvas(const KURL&) const;
+
+ // Returns true for any non-local URL. If document parameter is supplied,
+ // its local load policy dictates, otherwise if referrer is non-empty and
+ // represents a local file, then the local load is allowed.
+ static bool canLoad(const KURL&, const String& referrer, Document* document);
+
+ // Returns true if this SecurityOrigin can load local resources, such
+ // as images, iframes, and style sheets, and can link to local URLs.
+ // For example, call this function before creating an iframe to a
+ // file:// URL.
+ //
+ // Note: A SecurityOrigin might be allowed to load local resources
+ // without being able to issue an XMLHttpRequest for a local URL.
+ // To determine whether the SecurityOrigin can issue an
+ // XMLHttpRequest for a URL, call canRequest(url).
+ bool canLoadLocalResources() const { return m_canLoadLocalResources; }
+
+ // Explicitly grant the ability to load local resources to this
+ // SecurityOrigin.
+ //
+ // Note: This method exists only to support backwards compatibility
+ // with older versions of WebKit.
+ void grantLoadLocalResources();
+
+ // Explicitly grant the ability to access very other SecurityOrigin.
+ //
+ // WARNING: This is an extremely powerful ability. Use with caution!
+ void grantUniversalAccess();
+
+ bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
+
+ bool canAccessDatabase() const { return !isUnique(); }
+ bool canAccessLocalStorage() const { return !isUnique(); }
+ bool canAccessCookies() const { return !isUnique(); }
+
+ bool isSecureTransitionTo(const KURL&) const;
+
+ // The local SecurityOrigin is the most privileged SecurityOrigin.
+ // The local SecurityOrigin can script any document, navigate to local
+ // resources, and can set arbitrary headers on XMLHttpRequests.
+ bool isLocal() const;
+
+ // The empty SecurityOrigin is the least privileged SecurityOrigin.
+ bool isEmpty() const;
+
+ // The origin is a globally unique identifier assigned when the Document is
+ // created. http://www.whatwg.org/specs/web-apps/current-work/#sandboxOrigin
+ //
+ // There's a subtle difference between a unique origin and an origin that
+ // has the SandboxOrigin flag set. The latter implies the former, and, in
+ // addition, the SandboxOrigin flag is inherited by iframes.
+ bool isUnique() const { return m_isUnique; }
+
+ // Marks an origin as being unique.
+ void makeUnique();
+
+ // Convert this SecurityOrigin into a string. The string
+ // representation of a SecurityOrigin is similar to a URL, except it
+ // lacks a path component. The string representation does not encode
+ // the value of the SecurityOrigin's domain property.
+ //
+ // When using the string value, it's important to remember that it might be
+ // "null". This happens when this SecurityOrigin is unique. For example,
+ // this SecurityOrigin might have come from a sandboxed iframe, the
+ // SecurityOrigin might be empty, or we might have explicitly decided that
+ // we shouldTreatURLSchemeAsNoAccess.
+ String toString() const;
+
+ // Serialize the security origin to a string that could be used as part of
+ // file names. This format should be used in storage APIs only.
+ String databaseIdentifier() const;
+
+ // This method checks for equality between SecurityOrigins, not whether
+ // one origin can access another. It is used for hash table keys.
+ // For access checks, use canAccess().
+ // FIXME: If this method is really only useful for hash table keys, it
+ // should be refactored into SecurityOriginHash.
+ bool equal(const SecurityOrigin*) const;
+
+ // This method checks for equality, ignoring the value of document.domain
+ // (and whether it was set) but considering the host. It is used for postMessage.
+ bool isSameSchemeHostPort(const SecurityOrigin*) const;
+
+ static void registerURLSchemeAsLocal(const String&);
+ static void removeURLSchemeRegisteredAsLocal(const String&);
+ static const URLSchemesMap& localURLSchemes();
+ static bool shouldTreatURLAsLocal(const String&);
+ static bool shouldTreatURLSchemeAsLocal(const String&);
+
+ // Secure schemes do not trigger mixed content warnings. For example,
+ // https and data are secure schemes because they cannot be corrupted by
+ // active network attackers.
+ static void registerURLSchemeAsSecure(const String&);
+ static bool shouldTreatURLSchemeAsSecure(const String&);
+
+ static bool shouldHideReferrer(const KURL&, const String& referrer);
+
+ enum LocalLoadPolicy {
+ AllowLocalLoadsForAll, // No restriction on local loads.
+ AllowLocalLoadsForLocalAndSubstituteData,
+ AllowLocalLoadsForLocalOnly,
};
+ static void setLocalLoadPolicy(LocalLoadPolicy);
+ static bool restrictAccessToLocal();
+ static bool allowSubstituteDataAccessToLocal();
+
+ static void registerURLSchemeAsNoAccess(const String&);
+ static bool shouldTreatURLSchemeAsNoAccess(const String&);
+
+ static void whiteListAccessFromOrigin(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains);
+ static void resetOriginAccessWhiteLists();
+
+private:
+ SecurityOrigin(const KURL&, SandboxFlags);
+ explicit SecurityOrigin(const SecurityOrigin*);
+
+ SandboxFlags m_sandboxFlags;
+ String m_protocol;
+ String m_host;
+ mutable String m_encodedHost;
+ String m_domain;
+ unsigned short m_port;
+ bool m_isUnique;
+ bool m_universalAccess;
+ bool m_domainWasSetInDOM;
+ bool m_canLoadLocalResources;
+};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/Settings.cpp b/src/3rdparty/webkit/WebCore/page/Settings.cpp
index f528f37..475d373 100644
--- a/src/3rdparty/webkit/WebCore/page/Settings.cpp
+++ b/src/3rdparty/webkit/WebCore/page/Settings.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "Settings.h"
+#include "BackForwardList.h"
+#include "Database.h"
#include "Frame.h"
#include "FrameTree.h"
#include "FrameView.h"
@@ -48,7 +50,7 @@ static void setNeedsReapplyStylesInAllFrames(Page* page)
bool Settings::gShouldPaintNativeControls = true;
#endif
-#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX))
+#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
bool Settings::gShouldUseHighResolutionTimers = true;
#endif
@@ -63,17 +65,19 @@ Settings::Settings(Page* page)
, m_maximumDecodedImageSize(numeric_limits<size_t>::max())
, m_localStorageQuota(5 * 1024 * 1024) // Suggested by the HTML5 spec.
, m_pluginAllowedRunTime(numeric_limits<unsigned>::max())
+ , m_zoomMode(ZoomPage)
+ , m_isSpatialNavigationEnabled(false)
, m_isJavaEnabled(false)
, m_loadsImagesAutomatically(false)
, m_privateBrowsingEnabled(false)
, m_caretBrowsingEnabled(false)
+ , m_areImagesEnabled(true)
, m_arePluginsEnabled(false)
- , m_databasesEnabled(false)
, m_localStorageEnabled(false)
- , m_sessionStorageEnabled(true)
, m_isJavaScriptEnabled(false)
, m_isWebSecurityEnabled(true)
, m_allowUniversalAccessFromFileURLs(true)
+ , m_allowFileAccessFromFileURLs(true)
, m_javaScriptCanOpenWindowsAutomatically(false)
, m_shouldPrintBackgrounds(false)
, m_textAreasAreResizable(false)
@@ -94,17 +98,17 @@ Settings::Settings(Page* page)
, m_authorAndUserStylesEnabled(true)
, m_needsSiteSpecificQuirks(false)
, m_fontRenderingMode(0)
+ , m_frameFlatteningEnabled(false)
, m_webArchiveDebugModeEnabled(false)
, m_localFileContentSniffingEnabled(false)
, m_inApplicationChromeMode(false)
, m_offlineWebApplicationCacheEnabled(false)
, m_shouldPaintCustomScrollbars(false)
- , m_zoomsTextOnly(false)
, m_enforceCSSMIMETypeInStrictMode(true)
, m_usesEncodingDetector(false)
, m_allowScriptsToCloseWindows(false)
, m_editingBehavior(
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
// (PLATFORM(MAC) is always false in Chromium, hence the extra condition.)
EditingMacBehavior
#else
@@ -116,8 +120,12 @@ Settings::Settings(Page* page)
, m_downloadableBinaryFontsEnabled(true)
, m_xssAuditorEnabled(false)
, m_acceleratedCompositingEnabled(true)
+ , m_showDebugBorders(false)
+ , m_showRepaintCounter(false)
, m_experimentalNotificationsEnabled(false)
, m_webGLEnabled(false)
+ , m_loadDeferringEnabled(true)
+ , m_tiledBackingStoreEnabled(false)
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
@@ -234,19 +242,29 @@ void Settings::setAllowUniversalAccessFromFileURLs(bool allowUniversalAccessFrom
m_allowUniversalAccessFromFileURLs = allowUniversalAccessFromFileURLs;
}
+void Settings::setAllowFileAccessFromFileURLs(bool allowFileAccessFromFileURLs)
+{
+ m_allowFileAccessFromFileURLs = allowFileAccessFromFileURLs;
+}
+
+void Settings::setSpatialNavigationEnabled(bool isSpatialNavigationEnabled)
+{
+ m_isSpatialNavigationEnabled = isSpatialNavigationEnabled;
+}
+
void Settings::setJavaEnabled(bool isJavaEnabled)
{
m_isJavaEnabled = isJavaEnabled;
}
-void Settings::setPluginsEnabled(bool arePluginsEnabled)
+void Settings::setImagesEnabled(bool areImagesEnabled)
{
- m_arePluginsEnabled = arePluginsEnabled;
+ m_areImagesEnabled = areImagesEnabled;
}
-void Settings::setDatabasesEnabled(bool databasesEnabled)
+void Settings::setPluginsEnabled(bool arePluginsEnabled)
{
- m_databasesEnabled = databasesEnabled;
+ m_arePluginsEnabled = arePluginsEnabled;
}
void Settings::setLocalStorageEnabled(bool localStorageEnabled)
@@ -254,11 +272,6 @@ void Settings::setLocalStorageEnabled(bool localStorageEnabled)
m_localStorageEnabled = localStorageEnabled;
}
-void Settings::setSessionStorageEnabled(bool sessionStorageEnabled)
-{
- m_sessionStorageEnabled = sessionStorageEnabled;
-}
-
void Settings::setLocalStorageQuota(unsigned localStorageQuota)
{
m_localStorageQuota = localStorageQuota;
@@ -266,7 +279,11 @@ void Settings::setLocalStorageQuota(unsigned localStorageQuota)
void Settings::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
{
+ if (m_privateBrowsingEnabled == privateBrowsingEnabled)
+ return;
+
m_privateBrowsingEnabled = privateBrowsingEnabled;
+ m_page->privateBrowsingStateChanged();
}
void Settings::setJavaScriptCanOpenWindowsAutomatically(bool javaScriptCanOpenWindowsAutomatically)
@@ -421,6 +438,11 @@ void Settings::setNeedsSiteSpecificQuirks(bool needsQuirks)
m_needsSiteSpecificQuirks = needsQuirks;
}
+void Settings::setFrameFlatteningEnabled(bool frameFlatteningEnabled)
+{
+ m_frameFlatteningEnabled = frameFlatteningEnabled;
+}
+
void Settings::setWebArchiveDebugModeEnabled(bool enabled)
{
m_webArchiveDebugModeEnabled = enabled;
@@ -451,12 +473,12 @@ void Settings::setShouldPaintCustomScrollbars(bool shouldPaintCustomScrollbars)
m_shouldPaintCustomScrollbars = shouldPaintCustomScrollbars;
}
-void Settings::setZoomsTextOnly(bool zoomsTextOnly)
+void Settings::setZoomMode(ZoomMode mode)
{
- if (zoomsTextOnly == m_zoomsTextOnly)
+ if (mode == m_zoomMode)
return;
- m_zoomsTextOnly = zoomsTextOnly;
+ m_zoomMode = mode;
setNeedsReapplyStylesInAllFrames(m_page);
}
@@ -506,6 +528,24 @@ void Settings::setAcceleratedCompositingEnabled(bool enabled)
setNeedsReapplyStylesInAllFrames(m_page);
}
+void Settings::setShowDebugBorders(bool enabled)
+{
+ if (m_showDebugBorders == enabled)
+ return;
+
+ m_showDebugBorders = enabled;
+ setNeedsReapplyStylesInAllFrames(m_page);
+}
+
+void Settings::setShowRepaintCounter(bool enabled)
+{
+ if (m_showRepaintCounter == enabled)
+ return;
+
+ m_showRepaintCounter = enabled;
+ setNeedsReapplyStylesInAllFrames(m_page);
+}
+
void Settings::setExperimentalNotificationsEnabled(bool enabled)
{
m_experimentalNotificationsEnabled = enabled;
@@ -517,7 +557,7 @@ void Settings::setPluginAllowedRunTime(unsigned runTime)
m_page->pluginAllowedRunTimeChanged();
}
-#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX))
+#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
void Settings::setShouldUseHighResolutionTimers(bool shouldUseHighResolutionTimers)
{
gShouldUseHighResolutionTimers = shouldUseHighResolutionTimers;
@@ -529,4 +569,18 @@ void Settings::setWebGLEnabled(bool enabled)
m_webGLEnabled = enabled;
}
+void Settings::setLoadDeferringEnabled(bool enabled)
+{
+ m_loadDeferringEnabled = enabled;
+}
+
+void Settings::setTiledBackingStoreEnabled(bool enabled)
+{
+ m_tiledBackingStoreEnabled = enabled;
+#if ENABLE(TILED_BACKING_STORE)
+ if (m_page->mainFrame())
+ m_page->mainFrame()->setTiledBackingStoreEnabled(enabled);
+#endif
+}
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/Settings.h b/src/3rdparty/webkit/WebCore/page/Settings.h
index 09b5bec..b677712 100644
--- a/src/3rdparty/webkit/WebCore/page/Settings.h
+++ b/src/3rdparty/webkit/WebCore/page/Settings.h
@@ -30,6 +30,7 @@
#include "AtomicString.h"
#include "FontRenderingMode.h"
#include "KURL.h"
+#include "ZoomMode.h"
namespace WebCore {
@@ -64,7 +65,7 @@ namespace WebCore {
// if possible in the future.
enum EditingBehavior { EditingMacBehavior, EditingWindowsBehavior };
- class Settings {
+ class Settings : public Noncopyable {
public:
Settings(Page*);
@@ -98,10 +99,15 @@ namespace WebCore {
void setDefaultFixedFontSize(int);
int defaultFixedFontSize() const { return m_defaultFixedFontSize; }
+ // Unlike areImagesEnabled, this only suppresses the network load of
+ // the image URL. A cached image will still be rendered if requested.
void setLoadsImagesAutomatically(bool);
bool loadsImagesAutomatically() const { return m_loadsImagesAutomatically; }
void setJavaScriptEnabled(bool);
+ // Instead of calling isJavaScriptEnabled directly, please consider calling
+ // ScriptController::canExecuteScripts, which takes things like the
+ // HTML sandbox attribute into account.
bool isJavaScriptEnabled() const { return m_isJavaScriptEnabled; }
void setWebSecurityEnabled(bool);
@@ -110,24 +116,27 @@ namespace WebCore {
void setAllowUniversalAccessFromFileURLs(bool);
bool allowUniversalAccessFromFileURLs() const { return m_allowUniversalAccessFromFileURLs; }
+ void setAllowFileAccessFromFileURLs(bool);
+ bool allowFileAccessFromFileURLs() const { return m_allowFileAccessFromFileURLs; }
+
void setJavaScriptCanOpenWindowsAutomatically(bool);
bool javaScriptCanOpenWindowsAutomatically() const { return m_javaScriptCanOpenWindowsAutomatically; }
+ void setSpatialNavigationEnabled(bool);
+ bool isSpatialNavigationEnabled() const { return m_isSpatialNavigationEnabled; }
+
void setJavaEnabled(bool);
bool isJavaEnabled() const { return m_isJavaEnabled; }
+ void setImagesEnabled(bool);
+ bool areImagesEnabled() const { return m_areImagesEnabled; }
+
void setPluginsEnabled(bool);
bool arePluginsEnabled() const { return m_arePluginsEnabled; }
- void setDatabasesEnabled(bool);
- bool databasesEnabled() const { return m_databasesEnabled; }
-
void setLocalStorageEnabled(bool);
bool localStorageEnabled() const { return m_localStorageEnabled; }
- void setSessionStorageEnabled(bool);
- bool sessionStorageEnabled() const { return m_sessionStorageEnabled; }
-
void setLocalStorageQuota(unsigned);
unsigned localStorageQuota() const { return m_localStorageQuota; }
@@ -198,7 +207,10 @@ namespace WebCore {
void setDeveloperExtrasEnabled(bool);
bool developerExtrasEnabled() const { return m_developerExtrasEnabled; }
-
+
+ void setFrameFlatteningEnabled(bool);
+ bool frameFlatteningEnabled() const { return m_frameFlatteningEnabled; }
+
void setAuthorAndUserStylesEnabled(bool);
bool authorAndUserStylesEnabled() const { return m_authorAndUserStylesEnabled; }
@@ -226,8 +238,8 @@ namespace WebCore {
void setShouldPaintCustomScrollbars(bool);
bool shouldPaintCustomScrollbars() const { return m_shouldPaintCustomScrollbars; }
- void setZoomsTextOnly(bool);
- bool zoomsTextOnly() const { return m_zoomsTextOnly; }
+ void setZoomMode(ZoomMode);
+ ZoomMode zoomMode() const { return m_zoomMode; }
void setEnforceCSSMIMETypeInStrictMode(bool);
bool enforceCSSMIMETypeInStrictMode() { return m_enforceCSSMIMETypeInStrictMode; }
@@ -256,10 +268,16 @@ namespace WebCore {
void setAcceleratedCompositingEnabled(bool);
bool acceleratedCompositingEnabled() const { return m_acceleratedCompositingEnabled; }
+ void setShowDebugBorders(bool);
+ bool showDebugBorders() const { return m_showDebugBorders; }
+
+ void setShowRepaintCounter(bool);
+ bool showRepaintCounter() const { return m_showRepaintCounter; }
+
void setExperimentalNotificationsEnabled(bool);
bool experimentalNotificationsEnabled() const { return m_experimentalNotificationsEnabled; }
-#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX))
+#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
static void setShouldUseHighResolutionTimers(bool);
static bool shouldUseHighResolutionTimers() { return gShouldUseHighResolutionTimers; }
#endif
@@ -270,6 +288,12 @@ namespace WebCore {
void setWebGLEnabled(bool);
bool webGLEnabled() const { return m_webGLEnabled; }
+ void setLoadDeferringEnabled(bool);
+ bool loadDeferringEnabled() const { return m_loadDeferringEnabled; }
+
+ void setTiledBackingStoreEnabled(bool);
+ bool tiledBackingStoreEnabled() const { return m_tiledBackingStoreEnabled; }
+
private:
Page* m_page;
@@ -292,17 +316,19 @@ namespace WebCore {
size_t m_maximumDecodedImageSize;
unsigned m_localStorageQuota;
unsigned m_pluginAllowedRunTime;
+ ZoomMode m_zoomMode;
+ bool m_isSpatialNavigationEnabled : 1;
bool m_isJavaEnabled : 1;
bool m_loadsImagesAutomatically : 1;
bool m_privateBrowsingEnabled : 1;
bool m_caretBrowsingEnabled : 1;
+ bool m_areImagesEnabled : 1;
bool m_arePluginsEnabled : 1;
- bool m_databasesEnabled : 1;
bool m_localStorageEnabled : 1;
- bool m_sessionStorageEnabled : 1;
bool m_isJavaScriptEnabled : 1;
bool m_isWebSecurityEnabled : 1;
bool m_allowUniversalAccessFromFileURLs: 1;
+ bool m_allowFileAccessFromFileURLs: 1;
bool m_javaScriptCanOpenWindowsAutomatically : 1;
bool m_shouldPrintBackgrounds : 1;
bool m_textAreasAreResizable : 1;
@@ -323,12 +349,12 @@ namespace WebCore {
bool m_authorAndUserStylesEnabled : 1;
bool m_needsSiteSpecificQuirks : 1;
unsigned m_fontRenderingMode : 1;
+ bool m_frameFlatteningEnabled : 1;
bool m_webArchiveDebugModeEnabled : 1;
bool m_localFileContentSniffingEnabled : 1;
bool m_inApplicationChromeMode : 1;
bool m_offlineWebApplicationCacheEnabled : 1;
bool m_shouldPaintCustomScrollbars : 1;
- bool m_zoomsTextOnly : 1;
bool m_enforceCSSMIMETypeInStrictMode : 1;
bool m_usesEncodingDetector : 1;
bool m_allowScriptsToCloseWindows : 1;
@@ -336,13 +362,17 @@ namespace WebCore {
bool m_downloadableBinaryFontsEnabled : 1;
bool m_xssAuditorEnabled : 1;
bool m_acceleratedCompositingEnabled : 1;
+ bool m_showDebugBorders : 1;
+ bool m_showRepaintCounter : 1;
bool m_experimentalNotificationsEnabled : 1;
bool m_webGLEnabled : 1;
+ bool m_loadDeferringEnabled : 1;
+ bool m_tiledBackingStoreEnabled : 1;
#if USE(SAFARI_THEME)
static bool gShouldPaintNativeControls;
#endif
-#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX))
+#if PLATFORM(WIN) || (OS(WINDOWS) && PLATFORM(WX))
static bool gShouldUseHighResolutionTimers;
#endif
};
diff --git a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
new file mode 100644
index 0000000..86c9c5d
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org>
+ *
+ * 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 COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SpatialNavigation.h"
+
+#include "Frame.h"
+#include "FrameTree.h"
+#include "FrameView.h"
+#include "HTMLFrameOwnerElement.h"
+#include "IntRect.h"
+#include "Node.h"
+#include "Page.h"
+
+namespace WebCore {
+
+static long long spatialDistance(FocusDirection, const IntRect&, const IntRect&);
+static IntRect renderRectRelativeToRootDocument(RenderObject*);
+static RectsAlignment alignmentForRects(FocusDirection, const IntRect&, const IntRect&);
+static bool areRectsFullyAligned(FocusDirection, const IntRect&, const IntRect&);
+static bool areRectsPartiallyAligned(FocusDirection, const IntRect&, const IntRect&);
+static bool isRectInDirection(FocusDirection, const IntRect&, const IntRect&);
+static void deflateIfOverlapped(IntRect&, IntRect&);
+
+long long distanceInDirection(Node* start, Node* dest, FocusDirection direction, FocusCandidate& candidate)
+{
+ RenderObject* startRender = start->renderer();
+ if (!startRender)
+ return maxDistance();
+
+ RenderObject* destRender = dest->renderer();
+ if (!destRender)
+ return maxDistance();
+
+ IntRect curRect = renderRectRelativeToRootDocument(startRender);
+ IntRect targetRect = renderRectRelativeToRootDocument(destRender);
+
+ // The bounding rectangle of two consecutive nodes can overlap. In such cases,
+ // deflate both.
+ deflateIfOverlapped(curRect, targetRect);
+
+ if (curRect.isEmpty() || targetRect.isEmpty()
+ || targetRect.x() < 0 || targetRect.y() < 0)
+ return maxDistance();
+
+ if (!isRectInDirection(direction, curRect, targetRect))
+ return maxDistance();
+
+ // The distance between two nodes is not to be considered alone when evaluating/looking
+ // for the best focus candidate node. Alignment of rects can be also a good point to be
+ // considered in order to make the algorithm to behavior in a more intuitive way.
+ RectsAlignment alignment = alignmentForRects(direction, curRect, targetRect);
+
+ bool sameDocument = dest->document() == candidate.document();
+ if (sameDocument) {
+ if (candidate.alignment > alignment || (candidate.parentAlignment && alignment > candidate.parentAlignment))
+ return maxDistance();
+ } else if (candidate.alignment > alignment && (candidate.parentAlignment && alignment > candidate.parentAlignment))
+ return maxDistance();
+
+ // FIXME_tonikitoo: simplify the logic here !
+ if (alignment != None
+ || (!candidate.isNull() && candidate.parentAlignment >= alignment
+ && candidate.document() == dest->document())) {
+
+ // If we are now in an higher precedent case, lets reset the current |candidate|'s
+ // |distance| so we force it to be bigger than the result we will get from
+ // |spatialDistance| (see below).
+ if (candidate.alignment < alignment && candidate.parentAlignment < alignment)
+ candidate.distance = maxDistance();
+
+ candidate.alignment = alignment;
+ }
+
+ return spatialDistance(direction, curRect, targetRect);
+}
+
+// FIXME: This function does not behave correctly with transformed frames.
+static IntRect renderRectRelativeToRootDocument(RenderObject* render)
+{
+ ASSERT(render);
+
+ IntRect rect(render->absoluteClippedOverflowRect());
+
+ // In cases when the |render|'s associated node is in a scrollable inner
+ // document, we only consider its scrollOffset if it is not offscreen.
+ Node* node = render->node();
+ Document* mainDocument = node->document()->page()->mainFrame()->document();
+ bool considerScrollOffset = !(hasOffscreenRect(node) && node->document() != mainDocument);
+
+ if (considerScrollOffset) {
+ if (FrameView* frameView = render->node()->document()->view())
+ rect.move(-frameView->scrollOffset());
+ }
+
+ // Handle nested frames.
+ for (Frame* frame = render->document()->frame(); frame; frame = frame->tree()->parent()) {
+ if (HTMLFrameOwnerElement* ownerElement = frame->ownerElement())
+ rect.move(ownerElement->offsetLeft(), ownerElement->offsetTop());
+ }
+
+ return rect;
+}
+
+static RectsAlignment alignmentForRects(FocusDirection direction, const IntRect& curRect, const IntRect& targetRect)
+{
+ if (areRectsFullyAligned(direction, curRect, targetRect))
+ return Full;
+
+ if (areRectsPartiallyAligned(direction, curRect, targetRect))
+ return Partial;
+
+ return None;
+}
+
+static inline bool isHorizontalMove(FocusDirection direction)
+{
+ return direction == FocusDirectionLeft || direction == FocusDirectionRight;
+}
+
+static inline int start(FocusDirection direction, const IntRect& rect)
+{
+ return isHorizontalMove(direction) ? rect.y() : rect.x();
+}
+
+static inline int middle(FocusDirection direction, const IntRect& rect)
+{
+ IntPoint center(rect.center());
+ return isHorizontalMove(direction) ? center.y(): center.x();
+}
+
+static inline int end(FocusDirection direction, const IntRect& rect)
+{
+ return isHorizontalMove(direction) ? rect.bottom() : rect.right();
+}
+
+// This method checks if rects |a| and |b| are fully aligned either vertically or
+// horizontally. In general, rects whose central point falls between the top or
+// bottom of each other are considered fully aligned.
+// Rects that match this criteria are preferable target nodes in move focus changing
+// operations.
+// * a = Current focused node's rect.
+// * b = Focus candidate node's rect.
+static bool areRectsFullyAligned(FocusDirection direction, const IntRect& a, const IntRect& b)
+{
+ int aStart, bStart, aEnd, bEnd;
+
+ switch (direction) {
+ case FocusDirectionLeft:
+ aStart = a.x();
+ bEnd = b.right();
+ break;
+ case FocusDirectionRight:
+ aStart = b.x();
+ bEnd = a.right();
+ break;
+ case FocusDirectionUp:
+ aStart = a.y();
+ bEnd = b.y();
+ break;
+ case FocusDirectionDown:
+ aStart = b.y();
+ bEnd = a.y();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ if (aStart < bEnd)
+ return false;
+
+ aStart = start(direction, a);
+ bStart = start(direction, b);
+
+ int aMiddle = middle(direction, a);
+ int bMiddle = middle(direction, b);
+
+ aEnd = end(direction, a);
+ bEnd = end(direction, b);
+
+ // Picture of the totally aligned logic:
+ //
+ // Horizontal Vertical Horizontal Vertical
+ // **************************** *****************************
+ // * _ * _ _ _ _ * * _ * _ _ *
+ // * |_| _ * |_|_|_|_| * * _ |_| * |_|_| *
+ // * |_|....|_| * . * * |_|....|_| * . *
+ // * |_| |_| (1) . * * |_| |_| (2) . *
+ // * |_| * _._ * * |_| * _ _._ _ *
+ // * * |_|_| * * * |_|_|_|_| *
+ // * * * * * *
+ // **************************** *****************************
+
+ // Horizontal Vertical Horizontal Vertical
+ // **************************** *****************************
+ // * _......_ * _ _ _ _ * * _ * _ _ _ _ *
+ // * |_| |_| * |_|_|_|_| * * |_| _ * |_|_|_|_| *
+ // * |_| |_| * . * * |_| |_| * . *
+ // * |_| (3) . * * |_|....|_| (4) . *
+ // * * ._ _ * * * _ _. *
+ // * * |_|_| * * * |_|_| *
+ // * * * * * *
+ // **************************** *****************************
+
+ return ((bMiddle >= aStart && bMiddle <= aEnd) // (1)
+ || (aMiddle >= bStart && aMiddle <= bEnd) // (2)
+ || (bStart == aStart) // (3)
+ || (bEnd == aEnd)); // (4)
+}
+
+// This method checks if |start| and |dest| have a partial intersection, either
+// horizontally or vertically.
+// * a = Current focused node's rect.
+// * b = Focus candidate node's rect.
+static bool areRectsPartiallyAligned(FocusDirection direction, const IntRect& a, const IntRect& b)
+{
+ int aStart = start(direction, a);
+ int bStart = start(direction, b);
+ int bMiddle = middle(direction, b);
+ int aEnd = end(direction, a);
+ int bEnd = end(direction, b);
+
+ // Picture of the partially aligned logic:
+ //
+ // Horizontal Vertical
+ // ********************************
+ // * _ * _ _ _ *
+ // * |_| * |_|_|_| *
+ // * |_|.... _ * . . *
+ // * |_| |_| * . . *
+ // * |_|....|_| * ._._ _ *
+ // * |_| * |_|_|_| *
+ // * |_| * *
+ // * * *
+ // ********************************
+ //
+ // ... and variants of the above cases.
+ return ((bStart >= aStart && bStart <= aEnd)
+ || (bStart >= aStart && bStart <= aEnd)
+ || (bEnd >= aStart && bEnd <= aEnd)
+ || (bMiddle >= aStart && bMiddle <= aEnd)
+ || (bEnd >= aStart && bEnd <= aEnd));
+}
+
+// Return true if rect |a| is below |b|. False otherwise.
+static inline bool below(const IntRect& a, const IntRect& b)
+{
+ return a.y() > b.bottom();
+}
+
+// Return true if rect |a| is on the right of |b|. False otherwise.
+static inline bool rightOf(const IntRect& a, const IntRect& b)
+{
+ return a.x() > b.right();
+}
+
+// * a = Current focused node's rect.
+// * b = Focus candidate node's rect.
+static long long spatialDistance(FocusDirection direction, const IntRect& a, const IntRect& b)
+{
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+
+ if (direction == FocusDirectionLeft) {
+ // #1 |--|
+ //
+ // #2 |--| |--|
+ //
+ // #3 |--|
+
+ x1 = a.x();
+ x2 = b.right();
+
+ if (below(a, b)) {
+ // #1 The a rect is below b.
+ y1 = a.y();
+ y2 = b.bottom();
+ } else if (below(b, a)) {
+ // #3 The b rect is below a.
+ y1 = a.bottom();
+ y2 = b.y();
+ } else {
+ // #2 Both b and a share some common y's.
+ y1 = 0;
+ y2 = 0;
+ }
+ } else if (direction == FocusDirectionRight) {
+ // |--| #1
+ //
+ // |--| |--| #2
+ //
+ // |--| #3
+
+ x1 = a.right();
+ x2 = b.x();
+
+ if (below(a, b)) {
+ // #1 The b rect is above a.
+ y1 = a.y();
+ y2 = b.bottom();
+ } else if (below(b, a)) {
+ // #3 The b rect is below a.
+ y1 = a.bottom();
+ y2 = b.y();
+ } else {
+ // #2 Both b and a share some common y's.
+ y1 = 0;
+ y2 = 0;
+ }
+ } else if (direction == FocusDirectionUp) {
+ //
+ // #1 #2 #3
+ //
+ // |--| |--| |--|
+ //
+ // |--|
+
+ y1 = a.y();
+ y2 = b.bottom();
+
+ if (rightOf(a, b)) {
+ // #1 The b rect is to the left of a.
+ x1 = a.x();
+ x2 = b.right();
+ } else if (rightOf(b, a)) {
+ // #3 The b rect is to the right of a.
+ x1 = a.right();
+ x2 = b.x();
+ } else {
+ // #2 Both b and a share some common x's.
+ x1 = 0;
+ x2 = 0;
+ }
+ } else if (direction == FocusDirectionDown) {
+ // |--|
+ //
+ // |--| |--| |--|
+ //
+ // #1 #2 #3
+
+ y1 = a.bottom();
+ y2 = b.y();
+
+ if (rightOf(a, b)) {
+ // #1 The b rect is to the left of a.
+ x1 = a.x();
+ x2 = b.right();
+ } else if (rightOf(b, a)) {
+ // #3 The b rect is to the right of a
+ x1 = a.right();
+ x2 = b.x();
+ } else {
+ // #2 Both b and a share some common x's.
+ x1 = 0;
+ x2 = 0;
+ }
+ }
+
+ long long dx = x1 - x2;
+ long long dy = y1 - y2;
+
+ long long distance = (dx * dx) + (dy * dy);
+
+ if (distance < 0)
+ distance *= -1;
+
+ return distance;
+}
+
+static bool isRectInDirection(FocusDirection direction, const IntRect& curRect, const IntRect& targetRect)
+{
+ IntPoint center(targetRect.center());
+ int targetMiddle = isHorizontalMove(direction) ? center.x() : center.y();
+
+ switch (direction) {
+ case FocusDirectionLeft:
+ return targetMiddle < curRect.x();
+ case FocusDirectionRight:
+ return targetMiddle > curRect.right();
+ case FocusDirectionUp:
+ return targetMiddle < curRect.y();
+ case FocusDirectionDown:
+ return targetMiddle > curRect.bottom();
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return false;
+}
+
+// Checks if |node| is offscreen the visible area (viewport) of its container
+// document. In case it is, one can scroll in direction or take any different
+// desired action later on.
+bool hasOffscreenRect(Node* node)
+{
+ // Get the FrameView in which |node| is (which means the current viewport if |node|
+ // is not in an inner document), so we can check if its content rect is visible
+ // before we actually move the focus to it.
+ FrameView* frameView = node->document()->view();
+ if (!frameView)
+ return true;
+
+ IntRect containerViewportRect = frameView->visibleContentRect();
+
+ RenderObject* render = node->renderer();
+ if (!render)
+ return true;
+
+ IntRect rect(render->absoluteClippedOverflowRect());
+ return !containerViewportRect.intersects(rect);
+}
+
+// In a bottom-up way, this method tries to scroll |frame| in a given direction
+// |direction|, going up in the frame tree hierarchy in case it does not succeed.
+bool scrollInDirection(Frame* frame, FocusDirection direction)
+{
+ if (!frame)
+ return false;
+
+ ScrollDirection scrollDirection;
+
+ switch (direction) {
+ case FocusDirectionLeft:
+ scrollDirection = ScrollLeft;
+ break;
+ case FocusDirectionRight:
+ scrollDirection = ScrollRight;
+ break;
+ case FocusDirectionUp:
+ scrollDirection = ScrollUp;
+ break;
+ case FocusDirectionDown:
+ scrollDirection = ScrollDown;
+ break;
+ default:
+ return false;
+ }
+
+ return frame->eventHandler()->scrollRecursively(scrollDirection, ScrollByLine);
+}
+
+void scrollIntoView(Element* element)
+{
+ // NOTE: Element's scrollIntoView method could had been used here, but
+ // it is preferable to inflate |element|'s bounding rect a bit before
+ // scrolling it for accurate reason.
+ // Element's scrollIntoView method does not provide this flexibility.
+ static const int fudgeFactor = 2;
+ IntRect bounds = element->getRect();
+ bounds.inflate(fudgeFactor);
+ element->renderer()->enclosingLayer()->scrollRectToVisible(bounds);
+}
+
+bool isInRootDocument(Node* node)
+{
+ if (!node)
+ return false;
+
+ Document* rootDocument = node->document()->page()->mainFrame()->document();
+ return node->document() == rootDocument;
+}
+
+static void deflateIfOverlapped(IntRect& a, IntRect& b)
+{
+ if (!a.intersects(b) || a.contains(b) || b.contains(a))
+ return;
+
+ static const int fudgeFactor = -2;
+
+ // Avoid negative width or height values.
+ if ((a.width() + 2 * fudgeFactor > 0) && (a.height() + 2 * fudgeFactor > 0))
+ a.inflate(fudgeFactor);
+
+ if ((b.width() + 2 * fudgeFactor > 0) && (b.height() + 2 * fudgeFactor > 0))
+ b.inflate(fudgeFactor);
+}
+
+} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
new file mode 100644
index 0000000..7c183df
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SpatialNavigation_h
+#define SpatialNavigation_h
+
+#include "FocusDirection.h"
+#include "Node.h"
+
+#include <limits>
+
+namespace WebCore {
+
+class Element;
+class Frame;
+class IntRect;
+class RenderObject;
+
+using namespace std;
+
+inline long long maxDistance()
+{
+ return numeric_limits<long long>::max();
+}
+
+// Spatially speaking, two given elements in a web page can be:
+// 1) Fully aligned: There is a full intersection between the rects, either
+// vertically or horizontally.
+//
+// * Horizontally * Vertically
+// _
+// |_| _ _ _ _ _ _
+// |_|...... _ |_|_|_|_|_|_|
+// |_| |_| . .
+// |_|......|_| OR . .
+// |_| |_| . .
+// |_|......|_| _ _ _ _
+// |_| |_|_|_|_|
+//
+//
+// 2) Partially aligned: There is a partial intersection between the rects, either
+// vertically or horizontally.
+//
+// * Horizontally * Vertically
+// _ _ _ _ _ _
+// |_| |_|_|_|_|_|
+// |_|.... _ OR . .
+// |_| |_| . .
+// |_|....|_| ._._ _
+// |_| |_|_|_|
+// |_|
+//
+// 3) Or, otherwise, not aligned at all.
+//
+// * Horizontally * Vertically
+// _ _ _ _ _
+// |_| |_|_|_|_|
+// |_| .
+// |_| .
+// . OR .
+// _ . ._ _ _ _ _
+// |_| |_|_|_|_|_|
+// |_|
+// |_|
+//
+// "Totally Aligned" elements are preferable candidates to move
+// focus to over "Partially Aligned" ones, that on its turns are
+// more preferable than "Not Aligned".
+enum RectsAlignment {
+ None = 0,
+ Partial,
+ Full
+};
+
+struct FocusCandidate {
+ FocusCandidate()
+ : node(0)
+ , distance(maxDistance())
+ , parentDistance(maxDistance())
+ , alignment(None)
+ , parentAlignment(None)
+ {
+ }
+
+ FocusCandidate(Node* n)
+ : node(n)
+ , distance(maxDistance())
+ , parentDistance(maxDistance())
+ , alignment(None)
+ , parentAlignment(None)
+ {
+ }
+
+ bool isNull() const { return !node; }
+ Document* document() const { return node ? node->document() : 0; }
+
+ Node* node;
+ long long distance;
+ long long parentDistance;
+ RectsAlignment alignment;
+ RectsAlignment parentAlignment;
+};
+
+long long distanceInDirection(Node*, Node*, FocusDirection, FocusCandidate&);
+bool scrollInDirection(Frame*, FocusDirection);
+void scrollIntoView(Element*);
+bool hasOffscreenRect(Node*);
+bool isInRootDocument(Node*);
+
+} // namspace WebCore
+
+#endif // SpatialNavigation_h
diff --git a/src/3rdparty/webkit/WebCore/page/UserScript.h b/src/3rdparty/webkit/WebCore/page/UserScript.h
index dbbb879..8b3703f 100644
--- a/src/3rdparty/webkit/WebCore/page/UserScript.h
+++ b/src/3rdparty/webkit/WebCore/page/UserScript.h
@@ -34,16 +34,15 @@
namespace WebCore {
-class UserScript {
+class UserScript : public Noncopyable {
public:
UserScript(const String& source, const KURL& url,
PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist,
- unsigned worldID, UserScriptInjectionTime injectionTime)
+ UserScriptInjectionTime injectionTime)
: m_source(source)
, m_url(url)
, m_whitelist(whitelist)
, m_blacklist(blacklist)
- , m_worldID(worldID)
, m_injectionTime(injectionTime)
{
}
@@ -52,7 +51,6 @@ public:
const KURL& url() const { return m_url; }
const Vector<String>* whitelist() const { return m_whitelist.get(); }
const Vector<String>* blacklist() const { return m_blacklist.get(); }
- unsigned worldID() const { return m_worldID; }
UserScriptInjectionTime injectionTime() const { return m_injectionTime; }
private:
@@ -60,7 +58,6 @@ private:
KURL m_url;
OwnPtr<Vector<String> > m_whitelist;
OwnPtr<Vector<String> > m_blacklist;
- unsigned m_worldID;
UserScriptInjectionTime m_injectionTime;
};
diff --git a/src/3rdparty/webkit/WebCore/page/UserScriptTypes.h b/src/3rdparty/webkit/WebCore/page/UserScriptTypes.h
index ac37662..ad27e79 100644
--- a/src/3rdparty/webkit/WebCore/page/UserScriptTypes.h
+++ b/src/3rdparty/webkit/WebCore/page/UserScriptTypes.h
@@ -33,10 +33,11 @@ namespace WebCore {
enum UserScriptInjectionTime { InjectAtDocumentStart, InjectAtDocumentEnd };
+class DOMWrapperWorld;
class UserScript;
typedef Vector<OwnPtr<UserScript> > UserScriptVector;
-typedef HashMap<unsigned, UserScriptVector*> UserScriptMap;
+typedef HashMap<RefPtr<DOMWrapperWorld>, UserScriptVector*> UserScriptMap;
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/UserStyleSheet.h b/src/3rdparty/webkit/WebCore/page/UserStyleSheet.h
index 56bec40..610778f 100644
--- a/src/3rdparty/webkit/WebCore/page/UserStyleSheet.h
+++ b/src/3rdparty/webkit/WebCore/page/UserStyleSheet.h
@@ -34,16 +34,14 @@
namespace WebCore {
-class UserStyleSheet {
+class UserStyleSheet : public Noncopyable {
public:
UserStyleSheet(const String& source, const KURL& url,
- PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist,
- unsigned worldID)
+ PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist)
: m_source(source)
, m_url(url)
, m_whitelist(whitelist)
, m_blacklist(blacklist)
- , m_worldID(worldID)
{
}
@@ -51,14 +49,12 @@ public:
const KURL& url() const { return m_url; }
const Vector<String>* whitelist() const { return m_whitelist.get(); }
const Vector<String>* blacklist() const { return m_blacklist.get(); }
- unsigned worldID() const { return m_worldID; }
private:
String m_source;
KURL m_url;
OwnPtr<Vector<String> > m_whitelist;
OwnPtr<Vector<String> > m_blacklist;
- unsigned m_worldID;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/UserStyleSheetTypes.h b/src/3rdparty/webkit/WebCore/page/UserStyleSheetTypes.h
index 094b2cf..ef662f2 100644
--- a/src/3rdparty/webkit/WebCore/page/UserStyleSheetTypes.h
+++ b/src/3rdparty/webkit/WebCore/page/UserStyleSheetTypes.h
@@ -31,10 +31,11 @@
namespace WebCore {
+class DOMWrapperWorld;
class UserStyleSheet;
typedef Vector<OwnPtr<UserStyleSheet> > UserStyleSheetVector;
-typedef HashMap<unsigned, UserStyleSheetVector*> UserStyleSheetMap;
+typedef HashMap<RefPtr<DOMWrapperWorld>, UserStyleSheetVector*> UserStyleSheetMap;
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/WebKitPoint.idl b/src/3rdparty/webkit/WebCore/page/WebKitPoint.idl
index 1eefbc3..fd617b2 100644
--- a/src/3rdparty/webkit/WebCore/page/WebKitPoint.idl
+++ b/src/3rdparty/webkit/WebCore/page/WebKitPoint.idl
@@ -25,7 +25,7 @@
module window {
- interface WebKitPoint {
+ interface [CustomConstructor] WebKitPoint {
attribute float x;
attribute float y;
};
diff --git a/src/3rdparty/webkit/WebCore/page/WorkerNavigator.idl b/src/3rdparty/webkit/WebCore/page/WorkerNavigator.idl
index 195f0bc..ec75f8a 100644
--- a/src/3rdparty/webkit/WebCore/page/WorkerNavigator.idl
+++ b/src/3rdparty/webkit/WebCore/page/WorkerNavigator.idl
@@ -30,7 +30,8 @@ module threads {
interface [
Conditional=WORKERS,
- NoStaticTables
+ NoStaticTables,
+ OmitConstructor
] WorkerNavigator {
readonly attribute DOMString appName;
readonly attribute DOMString appVersion;
diff --git a/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp
index 890c3fa..094f200 100644
--- a/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp
+++ b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp
@@ -105,7 +105,12 @@ bool XSSAuditor::canEvaluate(const String& code) const
if (!isEnabled())
return true;
- if (findInRequest(code, false, true)) {
+ FindTask task;
+ task.string = code;
+ task.decodeEntities = false;
+ task.allowRequestIfNoIllegalURICharacters = true;
+
+ if (findInRequest(task)) {
DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
return false;
@@ -118,7 +123,11 @@ bool XSSAuditor::canEvaluateJavaScriptURL(const String& code) const
if (!isEnabled())
return true;
- if (findInRequest(code, true, false, true)) {
+ FindTask task;
+ task.string = code;
+ task.decodeURLEscapeSequencesTwice = true;
+
+ if (findInRequest(task)) {
DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
return false;
@@ -131,7 +140,11 @@ bool XSSAuditor::canCreateInlineEventListener(const String&, const String& code)
if (!isEnabled())
return true;
- if (findInRequest(code, true, true)) {
+ FindTask task;
+ task.string = code;
+ task.allowRequestIfNoIllegalURICharacters = true;
+
+ if (findInRequest(task)) {
DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
return false;
@@ -144,17 +157,14 @@ bool XSSAuditor::canLoadExternalScriptFromSrc(const String& context, const Strin
if (!isEnabled())
return true;
- // If the script is loaded from the same URL as the enclosing page, it's
- // probably not an XSS attack, so we reduce false positives by allowing the
- // script. If the script has a query string, we're more suspicious,
- // however, because that's pretty rare and the attacker might be able to
- // trick a server-side script into doing something dangerous with the query
- // string.
- KURL scriptURL(m_frame->document()->url(), url);
- if (m_frame->document()->url().host() == scriptURL.host() && scriptURL.query().isEmpty())
+ if (isSameOriginResource(url))
return true;
- if (findInRequest(context + url)) {
+ FindTask task;
+ task.context = context;
+ task.string = url;
+
+ if (findInRequest(task)) {
DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
return false;
@@ -167,8 +177,15 @@ bool XSSAuditor::canLoadObject(const String& url) const
if (!isEnabled())
return true;
- if (findInRequest(url)) {
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request"));
+ if (isSameOriginResource(url))
+ return true;
+
+ FindTask task;
+ task.string = url;
+ task.allowRequestIfNoIllegalURICharacters = true;
+
+ if (findInRequest(task)) {
+ String consoleMessage = String::format("Refused to load an object. URL found within request: \"%s\".\n", url.utf8().data());
m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
return false;
}
@@ -179,10 +196,16 @@ bool XSSAuditor::canSetBaseElementURL(const String& url) const
{
if (!isEnabled())
return true;
-
- KURL baseElementURL(m_frame->document()->url(), url);
- if (m_frame->document()->url().host() != baseElementURL.host() && findInRequest(url)) {
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request"));
+
+ if (isSameOriginResource(url))
+ return true;
+
+ FindTask task;
+ task.string = url;
+ task.allowRequestIfNoIllegalURICharacters = true;
+
+ if (findInRequest(task)) {
+ DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to load from document base URL. URL found within request.\n"));
m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
return false;
}
@@ -255,20 +278,61 @@ String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodabl
return String::adopt(result);
}
-bool XSSAuditor::findInRequest(const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters,
- bool decodeURLEscapeSequencesTwice) const
+bool XSSAuditor::isSameOriginResource(const String& url) const
+{
+ // If the resource is loaded from the same URL as the enclosing page, it's
+ // probably not an XSS attack, so we reduce false positives by allowing the
+ // request. If the resource has a query string, we're more suspicious,
+ // however, because that's pretty rare and the attacker might be able to
+ // trick a server-side script into doing something dangerous with the query
+ // string.
+ KURL resourceURL(m_frame->document()->url(), url);
+ return (m_frame->document()->url().host() == resourceURL.host() && resourceURL.query().isEmpty());
+}
+
+XSSProtectionDisposition XSSAuditor::xssProtection() const
+{
+ DEFINE_STATIC_LOCAL(String, XSSProtectionHeader, ("X-XSS-Protection"));
+
+ Frame* frame = m_frame;
+ if (frame->document()->url() == blankURL())
+ frame = m_frame->tree()->parent();
+
+ return parseXSSProtectionHeader(frame->loader()->documentLoader()->response().httpHeaderField(XSSProtectionHeader));
+}
+
+bool XSSAuditor::findInRequest(const FindTask& task) const
{
bool result = false;
Frame* parentFrame = m_frame->tree()->parent();
+ Frame* blockFrame = parentFrame;
if (parentFrame && m_frame->document()->url() == blankURL())
- result = findInRequest(parentFrame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice);
+ result = findInRequest(parentFrame, task);
+ if (!result) {
+ result = findInRequest(m_frame, task);
+ blockFrame = m_frame;
+ }
if (!result)
- result = findInRequest(m_frame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice);
- return result;
+ return false;
+
+ switch (xssProtection()) {
+ case XSSProtectionDisabled:
+ return false;
+ case XSSProtectionEnabled:
+ break;
+ case XSSProtectionBlockEnabled:
+ if (blockFrame) {
+ blockFrame->loader()->stopAllLoaders();
+ blockFrame->redirectScheduler()->scheduleLocationChange(blankURL(), String());
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ return true;
}
-bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters,
- bool decodeURLEscapeSequencesTwice) const
+bool XSSAuditor::findInRequest(Frame* frame, const FindTask& task) const
{
ASSERT(frame->document());
@@ -277,17 +341,19 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEn
return false;
}
- if (string.isEmpty())
+ if (task.string.isEmpty())
return false;
FormData* formDataObj = frame->loader()->documentLoader()->originalRequest().httpBody();
+ const bool hasFormData = formDataObj && !formDataObj->isEmpty();
String pageURL = frame->document()->url().string();
- if (!formDataObj && string.length() >= 2 * pageURL.length()) {
+ String canonicalizedString;
+ if (!hasFormData && task.string.length() > 2 * pageURL.length()) {
// Q: Why do we bother to do this check at all?
// A: Canonicalizing large inline scripts can be expensive. We want to
- // bail out before the call to canonicalize below, which could
- // result in an unneeded allocation and memcpy.
+ // reduce the size of the string before we call canonicalize below,
+ // since it could result in an unneeded allocation and memcpy.
//
// Q: Why do we multiply by two here?
// A: We attempt to detect reflected XSS even when the server
@@ -295,39 +361,32 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEn
// attacker can do get the server to inflate his/her input by a
// factor of two by sending " characters, which the server
// transforms to \".
- return false;
- }
+ canonicalizedString = task.string.substring(0, 2 * pageURL.length());
+ } else
+ canonicalizedString = task.string;
if (frame->document()->url().protocolIs("data"))
return false;
- String canonicalizedString = canonicalize(string);
+ canonicalizedString = canonicalize(canonicalizedString);
if (canonicalizedString.isEmpty())
return false;
- if (string.length() < pageURL.length()) {
- // The string can actually fit inside the pageURL.
- String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice);
+ if (!task.context.isEmpty())
+ canonicalizedString = task.context + canonicalizedString;
- if (allowRequestIfNoIllegalURICharacters && (!formDataObj || formDataObj->isEmpty())
- && decodedPageURL.find(&isIllegalURICharacter, 0) == -1)
- return false; // Injection is impossible because the request does not contain any illegal URI characters.
+ String decodedPageURL = m_pageURLCache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice);
- if (decodedPageURL.find(canonicalizedString, 0, false) != -1)
- return true; // We've found the smoking gun.
- }
+ if (task.allowRequestIfNoIllegalURICharacters && !hasFormData && decodedPageURL.find(&isIllegalURICharacter, 0) == -1)
+ return false; // Injection is impossible because the request does not contain any illegal URI characters.
- if (formDataObj && !formDataObj->isEmpty()) {
- String formData = formDataObj->flattenToString();
- if (string.length() < formData.length()) {
- // Notice it is sufficient to compare the length of the string to
- // the url-encoded POST data because the length of the url-decoded
- // code is less than or equal to the length of the url-encoded
- // string.
- String decodedFormData = m_cache.canonicalizeURL(formData, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice);
- if (decodedFormData.find(canonicalizedString, 0, false) != -1)
- return true; // We found the string in the POST data.
- }
+ if (decodedPageURL.find(canonicalizedString, 0, false) != -1)
+ return true; // We've found the string in the GET data.
+
+ if (hasFormData) {
+ String decodedFormData = m_formDataCache.canonicalizeURL(formDataObj->flattenToString(), frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice);
+ if (decodedFormData.find(canonicalizedString, 0, false) != -1)
+ return true; // We found the string in the POST data.
}
return false;
diff --git a/src/3rdparty/webkit/WebCore/page/XSSAuditor.h b/src/3rdparty/webkit/WebCore/page/XSSAuditor.h
index adfa5c7..a7628f3 100644
--- a/src/3rdparty/webkit/WebCore/page/XSSAuditor.h
+++ b/src/3rdparty/webkit/WebCore/page/XSSAuditor.h
@@ -27,6 +27,7 @@
#ifndef XSSAuditor_h
#define XSSAuditor_h
+#include "HTTPParsers.h"
#include "PlatformString.h"
#include "TextEncoding.h"
@@ -36,34 +37,37 @@ namespace WebCore {
class ScriptSourceCode;
// The XSSAuditor class is used to prevent type 1 cross-site scripting
- // vulnerabilites (also known as reflected vulnerabilities).
+ // vulnerabilities (also known as reflected vulnerabilities).
//
// More specifically, the XSSAuditor class decides whether the execution of
// a script is to be allowed or denied based on the content of any
// user-submitted data, including:
//
- // * the query string of the URL.
+ // * the URL.
// * the HTTP-POST data.
//
// If the source code of a script resembles any user-submitted data then it
// is denied execution.
//
- // When you instantiate the XSSAuditor you must specify the {@link Frame}
- // of the page that you wish to audit.
+ // When you instantiate the XSSAuditor you must specify the Frame of the
+ // page that you wish to audit.
//
// Bindings
//
- // An XSSAuditor is instantiated within the contructor of a
+ // An XSSAuditor is instantiated within the constructor of a
// ScriptController object and passed the Frame the script originated. The
// ScriptController calls back to the XSSAuditor to determine whether a
// JavaScript script is safe to execute before executing it. The following
// methods call into XSSAuditor:
//
- // * ScriptController::evaluate - used to evaluate JavaScript scripts.
- // * ScriptController::createInlineEventListener - used to create JavaScript event handlers.
- // * HTMLTokenizer::scriptHandler - used to load external JavaScript scripts.
+ // * ScriptController::evaluateInWorld - used to evaluate JavaScript scripts.
+ // * ScriptController::executeIfJavaScriptURL - used to evaluate JavaScript URLs.
+ // * ScriptEventListener::createAttributeEventListener - used to create JavaScript event handlers.
+ // * HTMLBaseElement::process - used to set the document base URL.
+ // * HTMLTokenizer::parseTag - used to load external JavaScript scripts.
+ // * FrameLoader::requestObject - used to load <object>/<embed> elements.
//
- class XSSAuditor {
+ class XSSAuditor : public Noncopyable {
public:
XSSAuditor(Frame*);
~XSSAuditor();
@@ -117,21 +121,43 @@ namespace WebCore {
String m_cachedCanonicalizedURL;
};
+ struct FindTask {
+ FindTask()
+ : decodeEntities(true)
+ , allowRequestIfNoIllegalURICharacters(false)
+ , decodeURLEscapeSequencesTwice(false)
+ {
+ }
+
+ String context;
+ String string;
+ bool decodeEntities;
+ bool allowRequestIfNoIllegalURICharacters;
+ bool decodeURLEscapeSequencesTwice;
+ };
+
static String canonicalize(const String&);
static String decodeURL(const String& url, const TextEncoding& encoding, bool decodeEntities,
bool decodeURLEscapeSequencesTwice = false);
static String decodeHTMLEntities(const String&, bool leaveUndecodableEntitiesUntouched = true);
- bool findInRequest(const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false,
- bool decodeURLEscapeSequencesTwice = false) const;
- bool findInRequest(Frame*, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false,
- bool decodeURLEscapeSequencesTwice = false) const;
+ bool isSameOriginResource(const String& url) const;
+ bool findInRequest(const FindTask&) const;
+ bool findInRequest(Frame*, const FindTask&) const;
+
+ XSSProtectionDisposition xssProtection() const;
// The frame to audit.
Frame* m_frame;
// A state store to help us avoid canonicalizing the same URL repeated.
- mutable CachingURLCanonicalizer m_cache;
+ // When a page has form data, we need two caches: one to store the
+ // canonicalized URL and another to store the cannonicalized form
+ // data. If we only had one cache, we'd always generate a cache miss
+ // and load some pages extremely slowly.
+ // https://bugs.webkit.org/show_bug.cgi?id=35373
+ mutable CachingURLCanonicalizer m_pageURLCache;
+ mutable CachingURLCanonicalizer m_formDataCache;
};
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/ZoomMode.h b/src/3rdparty/webkit/WebCore/page/ZoomMode.h
new file mode 100644
index 0000000..3f02184
--- /dev/null
+++ b/src/3rdparty/webkit/WebCore/page/ZoomMode.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 Research in Motion Ltd. http://www.rim.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ZoomMode_h
+#define ZoomMode_h
+
+namespace WebCore {
+
+enum ZoomMode {
+ ZoomPage,
+ ZoomTextOnly
+};
+
+}
+
+#endif
diff --git a/src/3rdparty/webkit/WebCore/page/android/EventHandlerAndroid.cpp b/src/3rdparty/webkit/WebCore/page/android/EventHandlerAndroid.cpp
deleted file mode 100644
index cf2acfb..0000000
--- a/src/3rdparty/webkit/WebCore/page/android/EventHandlerAndroid.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright 2009, The Android Open Source Project
- * Copyright (C) 2006 Zack Rusin <zack@kde.org>
- *
- * 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 COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#define LOG_TAG "WebCore"
-
-#include "config.h"
-#include "EventHandler.h"
-
-#include "FocusController.h"
-#include "Frame.h"
-#include "KeyboardEvent.h"
-#include "MouseEventWithHitTestResults.h"
-#include "Page.h"
-#include "PlatformKeyboardEvent.h"
-#include "PlatformWheelEvent.h"
-#include "RenderWidget.h"
-
-namespace WebCore {
-
-unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::AltKey;
-
-bool EventHandler::tabsToAllControls(KeyboardEvent*) const
-{
- return true;
-}
-
-void EventHandler::focusDocumentView()
-{
- if (Page* page = m_frame->page())
- page->focusController()->setFocusedFrame(m_frame);
-}
-
-bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
-{
- // Figure out which view to send the event to.
- RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0;
- if (!target || !target->isWidget())
- return false;
- return passMouseDownEventToWidget(toRenderWidget(target)->widget());
-}
-
-bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
-{
- return passMouseDownEventToWidget(renderWidget->widget());
-}
-
-// This function is used to route the mouse down event to the native widgets, it seems like a
-// work around for the Mac platform which does not support double clicks, but browsers do.
-bool EventHandler::passMouseDownEventToWidget(Widget*)
-{
- // return false so the normal propogation handles the event
- return false;
-}
-
-bool EventHandler::eventActivatedView(const PlatformMouseEvent&) const
-{
- notImplemented();
- return false;
-}
-
-// This function is called for mouse events by FrameView::handleMousePressEvent().
-// It is used to ensure that events are sync'ed correctly between frames. For example
-// if the user presses down in one frame and up in another frame, this function will
-// returns true, and pass the event to the correct frame.
-bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame*, HitTestResult*)
-{
- notImplemented();
- return false;
-}
-
-// This is called to route wheel events to child widgets when they are RenderWidget
-// as the parent usually gets wheel event. Don't have a mouse with a wheel to confirm
-// the operation of this function.
-bool EventHandler::passWheelEventToWidget(PlatformWheelEvent&, Widget*)
-{
- notImplemented();
- return false;
-}
-
-bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
-{
- return passSubframeEventToSubframe(mev, subframe);
-}
-
-bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev,
- Frame* subframe, HitTestResult*)
-{
- return passSubframeEventToSubframe(mev, subframe);
-}
-
-bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
-{
- return passSubframeEventToSubframe(mev, subframe);
-}
-
-class Clipboard : public RefCounted<Clipboard> {
-};
-
-PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
-{
- return PassRefPtr<Clipboard>(0);
-}
-
-const double EventHandler::TextDragDelay = 0.0;
-
-} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/android/InspectorControllerAndroid.cpp b/src/3rdparty/webkit/WebCore/page/android/InspectorControllerAndroid.cpp
deleted file mode 100644
index 978bc25..0000000
--- a/src/3rdparty/webkit/WebCore/page/android/InspectorControllerAndroid.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "InspectorController.h"
-
-#include "Frame.h"
-#include "Node.h"
-#include "Profile.h"
-
-// This stub file was created to avoid building and linking in all the
-// Inspector codebase. If you would like to enable the Inspector, do the
-// following steps:
-// 1. Replace this file in WebCore/Android.mk with the common
-// implementation, ie page/InsepctorController.cpp
-// 2. Add the JS API files to JavaScriptCore/Android.mk:
-// ? API/JSBase.cpp \
-// API/JSCallbackConstructor.cpp \
-// API/JSCallbackFunction.cpp \
-// API/JSCallbackObject.cpp \
-// API/JSClassRef.cpp \
-// API/JSContextRef.cpp \
-// API/JSObjectRef.cpp \
-// API/JSStringRef.cpp \
-// API/JSValueRef.cpp
-// 3. Add the following LOCAL_C_INCLUDES to JavaScriptCore/Android.mk:
-// ?$(LOCAL_PATH)/API \
-// $(LOCAL_PATH)/ForwardingHeaders \
-// $(LOCAL_PATH)/../../WebKit \
-// 4. Rebuild WebKit
-//
-// Note, for a functional Inspector, you must implement InspectorClientAndroid.
-
-namespace WebCore {
-
-struct InspectorResource : public RefCounted<InspectorResource> {
-};
-
-struct InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> {
-};
-
-InspectorController::InspectorController(Page*, InspectorClient*)
- : m_startProfiling(this, 0)
-{
-}
-
-InspectorController::~InspectorController() {}
-
-void InspectorController::windowScriptObjectAvailable() {}
-void InspectorController::didCommitLoad(DocumentLoader*) {}
-void InspectorController::identifierForInitialRequest(unsigned long, DocumentLoader*, ResourceRequest const&) {}
-void InspectorController::willSendRequest(DocumentLoader*, unsigned long, ResourceRequest&, ResourceResponse const&) {}
-void InspectorController::didReceiveResponse(DocumentLoader*, unsigned long, ResourceResponse const&) {}
-void InspectorController::didReceiveContentLength(DocumentLoader*, unsigned long, int) {}
-void InspectorController::didFinishLoading(DocumentLoader*, unsigned long) {}
-void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader*, ResourceRequest const&, ResourceResponse const&, int) {}
-void InspectorController::frameDetachedFromParent(Frame*) {}
-
-void InspectorController::addMessageToConsole(MessageSource, MessageLevel, JSC::ExecState*, JSC::ArgList const&, unsigned int, String const&) {}
-void InspectorController::addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID) {}
-#if ENABLE(DATABASE)
-void InspectorController::didOpenDatabase(Database*, String const&, String const&, String const&) {}
-#endif
-bool InspectorController::enabled() const { return false; }
-void InspectorController::inspect(Node*) {}
-bool InspectorController::windowVisible() { return false; }
-void InspectorController::addProfile(PassRefPtr<JSC::Profile>, unsigned int, const JSC::UString&) {}
-void InspectorController::inspectedPageDestroyed() {}
-void InspectorController::resourceRetrievedByXMLHttpRequest(unsigned long identifier, JSC::UString& sourceString) {}
-
-void InspectorController::inspectedWindowScriptObjectCleared(Frame* frame) {}
-void InspectorController::startGroup(MessageSource source, JSC::ExecState* exec, const JSC::ArgList& arguments, unsigned lineNumber, const String& sourceURL) {}
-void InspectorController::endGroup(MessageSource source, unsigned lineNumber, const String& sourceURL) {}
-void InspectorController::startTiming(const JSC::UString& title) {}
-bool InspectorController::stopTiming(const JSC::UString& title, double& elapsed) { return false; }
-void InspectorController::count(const JSC::UString& title, unsigned lineNumber, const String& sourceID) {}
-
-void InspectorController::mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) {}
-void InspectorController::handleMousePressOnNode(Node*) {}
-void InspectorController::failedToParseSource(JSC::ExecState* exec, const JSC::SourceCode& source, int errorLine, const JSC::UString& errorMessage) {}
-void InspectorController::didParseSource(JSC::ExecState* exec, const JSC::SourceCode& source) {}
-void InspectorController::didPause() {}
-
-} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.cpp b/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.cpp
index 59797da..c2d70ef 100644
--- a/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.cpp
+++ b/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.cpp
@@ -92,10 +92,17 @@ static inline Color blendFunc(const AnimationBase* anim, const Color& from, cons
if (progress == 1 && !to.isValid())
return Color();
- return Color(blendFunc(anim, from.red(), to.red(), progress),
- blendFunc(anim, from.green(), to.green(), progress),
- blendFunc(anim, from.blue(), to.blue(), progress),
- blendFunc(anim, from.alpha(), to.alpha(), progress));
+ // Contrary to the name, RGBA32 actually stores ARGB, so we can initialize Color directly from premultipliedARGBFromColor().
+ // Also, premultipliedARGBFromColor() bails on zero alpha, so special-case that.
+ Color premultFrom = from.alpha() ? premultipliedARGBFromColor(from) : 0;
+ Color premultTo = to.alpha() ? premultipliedARGBFromColor(to) : 0;
+
+ Color premultBlended(blendFunc(anim, premultFrom.red(), premultTo.red(), progress),
+ blendFunc(anim, premultFrom.green(), premultTo.green(), progress),
+ blendFunc(anim, premultFrom.blue(), premultTo.blue(), progress),
+ blendFunc(anim, premultFrom.alpha(), premultTo.alpha(), progress));
+
+ return Color(colorFromPremultipliedARGB(premultBlended.rgb()));
}
static inline Length blendFunc(const AnimationBase*, const Length& from, const Length& to, double progress)
@@ -190,7 +197,7 @@ class PropertyWrapperBase;
static void addShorthandProperties();
static PropertyWrapperBase* wrapperForProperty(int propertyID);
-class PropertyWrapperBase {
+class PropertyWrapperBase : public Noncopyable {
public:
PropertyWrapperBase(int prop)
: m_prop(prop)
@@ -407,7 +414,7 @@ public:
};
template <typename T>
-class FillLayerPropertyWrapperGetter : public FillLayerPropertyWrapperBase {
+class FillLayerPropertyWrapperGetter : public FillLayerPropertyWrapperBase, public Noncopyable {
public:
FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const)
: m_getter(getter)
@@ -863,7 +870,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
m_pauseTime = -1;
m_requestedStartTime = 0;
m_nextIterationDuration = -1;
- endAnimation(false);
+ endAnimation();
return;
}
@@ -875,7 +882,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
m_pauseTime = -1;
m_requestedStartTime = 0;
m_nextIterationDuration = -1;
- endAnimation(false);
+ endAnimation();
if (!paused())
updateStateMachine(AnimationStateInputStartAnimation, -1);
@@ -886,7 +893,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (m_animState == AnimationStateStartWaitStyleAvailable)
m_compAnim->animationController()->removeFromStyleAvailableWaitList(this);
m_animState = AnimationStateDone;
- endAnimation(true);
+ endAnimation();
return;
}
@@ -894,7 +901,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (m_animState == AnimationStateStartWaitResponse) {
// If we are in AnimationStateStartWaitResponse, the animation will get canceled before
// we get a response, so move to the next state.
- endAnimation(false);
+ endAnimation();
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
}
return;
@@ -903,7 +910,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (input == AnimationStateInputResumeOverride) {
if (m_animState == AnimationStateLooping || m_animState == AnimationStateEnding) {
// Start the animation
- startAnimation(m_startTime);
+ startAnimation(beginAnimationUpdateTime() - m_startTime);
}
return;
}
@@ -911,8 +918,8 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// Execute state machine
switch (m_animState) {
case AnimationStateNew:
- ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputPlayStatePaused);
- if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning) {
+ ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunning || input == AnimationStateInputPlayStatePaused);
+ if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunning) {
m_requestedStartTime = beginAnimationUpdateTime();
m_animState = AnimationStateStartWaitTimer;
}
@@ -956,7 +963,12 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
}
else {
- bool started = startAnimation(0);
+ double timeOffset = 0;
+ // If the value for 'animation-delay' is negative then the animation appears to have started in the past.
+ if (m_animation->delay() < 0)
+ timeOffset = -m_animation->delay();
+ bool started = startAnimation(timeOffset);
+
m_compAnim->animationController()->addToStartTimeResponseWaitList(this, started);
m_fallbackAnimating = !started;
}
@@ -967,8 +979,12 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
if (input == AnimationStateInputStartTimeSet) {
ASSERT(param >= 0);
// We have a start time, set it, unless the startTime is already set
- if (m_startTime <= 0)
+ if (m_startTime <= 0) {
m_startTime = param;
+ // If the value for 'animation-delay' is negative then the animation appears to have started in the past.
+ if (m_animation->delay() < 0)
+ m_startTime += m_animation->delay();
+ }
// Decide whether to go into looping or ending state
goIntoEndingOrLoopingState();
@@ -980,7 +996,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// We are pausing while waiting for a start response. Cancel the animation and wait. When
// we unpause, we will act as though the start timer just fired
m_pauseTime = -1;
- endAnimation(false);
+ pauseAnimation(beginAnimationUpdateTime() - m_startTime);
m_animState = AnimationStatePausedWaitResponse;
}
break;
@@ -997,7 +1013,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
} else {
// We are pausing while running. Cancel the animation and wait
m_pauseTime = beginAnimationUpdateTime();
- endAnimation(false);
+ pauseAnimation(beginAnimationUpdateTime() - m_startTime);
m_animState = AnimationStatePausedRun;
}
break;
@@ -1005,6 +1021,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
ASSERT(input == AnimationStateInputEndTimerFired || input == AnimationStateInputPlayStatePaused);
if (input == AnimationStateInputEndTimerFired) {
+
ASSERT(param >= 0);
// End timer fired, finish up
onAnimationEnd(param);
@@ -1012,7 +1029,10 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
m_animState = AnimationStateDone;
if (m_object) {
- resumeOverriddenAnimations();
+ if (m_animation->fillsForwards())
+ m_animState = AnimationStateFillingForwards;
+ else
+ resumeOverriddenAnimations();
// Fire off another style change so we can set the final value
m_compAnim->animationController()->addNodeChangeToDispatch(m_object->node());
@@ -1020,13 +1040,13 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
} else {
// We are pausing while running. Cancel the animation and wait
m_pauseTime = beginAnimationUpdateTime();
- endAnimation(false);
+ pauseAnimation(beginAnimationUpdateTime() - m_startTime);
m_animState = AnimationStatePausedRun;
}
// |this| may be deleted here
break;
case AnimationStatePausedWaitTimer:
- ASSERT(input == AnimationStateInputPlayStateRunnning);
+ ASSERT(input == AnimationStateInputPlayStateRunning);
ASSERT(paused());
// Update the times
m_startTime += beginAnimationUpdateTime() - m_pauseTime;
@@ -1042,7 +1062,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// AnimationStatePausedWaitResponse, we don't yet have a valid startTime, so we send 0 to startAnimation.
// When the AnimationStateInputStartTimeSet comes in and we were in AnimationStatePausedRun, we will notice
// that we have already set the startTime and will ignore it.
- ASSERT(input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputStartTimeSet);
+ ASSERT(input == AnimationStateInputPlayStateRunning || input == AnimationStateInputStartTimeSet);
ASSERT(paused());
// If we are paused, but we get the callback that notifies us that an accelerated animation started,
@@ -1072,11 +1092,12 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
m_fallbackAnimating = true;
} else {
- bool started = startAnimation(m_startTime);
+ bool started = startAnimation(beginAnimationUpdateTime() - m_startTime);
m_compAnim->animationController()->addToStartTimeResponseWaitList(this, started);
m_fallbackAnimating = !started;
}
break;
+ case AnimationStateFillingForwards:
case AnimationStateDone:
// We're done. Stay in this state until we are deleted
break;
@@ -1136,14 +1157,14 @@ void AnimationBase::fireAnimationEventsIfNeeded()
void AnimationBase::updatePlayState(bool run)
{
if (paused() == run || isNew())
- updateStateMachine(run ? AnimationStateInputPlayStateRunnning : AnimationStateInputPlayStatePaused, -1);
+ updateStateMachine(run ? AnimationStateInputPlayStateRunning : AnimationStateInputPlayStatePaused, -1);
}
double AnimationBase::timeToNextService()
{
// Returns the time at which next service is required. -1 means no service is required. 0 means
// service is required now, and > 0 means service is required that many seconds in the future.
- if (paused() || isNew())
+ if (paused() || isNew() || m_animState == AnimationStateFillingForwards)
return -1;
if (m_animState == AnimationStateStartWaitTimer) {
@@ -1168,8 +1189,10 @@ double AnimationBase::progress(double scale, double offset, const TimingFunction
if (m_animation->iterationCount() > 0)
dur *= m_animation->iterationCount();
- if (postActive() || !m_animation->duration() || (m_animation->iterationCount() > 0 && elapsedTime >= dur))
+ if (postActive() || !m_animation->duration())
return 1.0;
+ if (m_animation->iterationCount() > 0 && elapsedTime >= dur)
+ return (m_animation->iterationCount() % 2) ? 1.0 : 0.0;
// Compute the fractional time, taking into account direction.
// There is no need to worry about iterations, we assume that we would have
diff --git a/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.h b/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.h
index 3482f65..a957119 100644
--- a/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.h
+++ b/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.h
@@ -71,7 +71,8 @@ public:
AnimationStatePausedWaitTimer, // in pause mode when animation started
AnimationStatePausedWaitResponse, // animation paused when in STARTING state
AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state
- AnimationStateDone // end timer fired, animation finished and removed
+ AnimationStateDone, // end timer fired, animation finished and removed
+ AnimationStateFillingForwards // animation has ended and is retaining its final value
};
enum AnimStateInput {
@@ -85,7 +86,7 @@ public:
AnimationStateInputEndTimerFired, // end timer fired
AnimationStateInputPauseOverride, // pause an animation due to override
AnimationStateInputResumeOverride, // resume an overridden animation
- AnimationStateInputPlayStateRunnning, // play state paused -> running
+ AnimationStateInputPlayStateRunning, // play state paused -> running
AnimationStateInputPlayStatePaused, // play state running -> paused
AnimationStateInputEndAnimation // force an end from any state
};
@@ -186,8 +187,13 @@ protected:
virtual void onAnimationStart(double /*elapsedTime*/) { }
virtual void onAnimationIteration(double /*elapsedTime*/) { }
virtual void onAnimationEnd(double /*elapsedTime*/) { }
- virtual bool startAnimation(double /*beginTime*/) { return false; }
- virtual void endAnimation(bool /*reset*/) { }
+
+ // timeOffset is an offset from the current time when the animation should start. Negative values are OK.
+ // Return value indicates whether to expect an asynchronous notifyAnimationStarted() callback.
+ virtual bool startAnimation(double /*timeOffset*/) { return false; }
+ // timeOffset is the time at which the animation is being paused.
+ virtual void pauseAnimation(double /*timeOffset*/) { }
+ virtual void endAnimation() { }
void goIntoEndingOrLoopingState();
diff --git a/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp b/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp
index aa5de2c..cb609a5 100644
--- a/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp
+++ b/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp
@@ -134,6 +134,9 @@ void AnimationControllerPrivate::updateAnimationTimer(bool callSetChanged/* = fa
void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<AnimationControllerPrivate>*)
{
+ // Protect the frame from getting destroyed in the event handler
+ RefPtr<Frame> protector = m_frame;
+
// fire all the events
Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = m_eventsToDispatch.end();
for (Vector<EventToDispatch>::const_iterator it = m_eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) {
@@ -484,7 +487,7 @@ PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject* rend
m_data->updateAnimationTimer();
if (blendedStyle != newStyle) {
- // If the animations/transitions change opacity or transform, we neeed to update
+ // If the animations/transitions change opacity or transform, we need to update
// the style to impose the stacking rules. Note that this is also
// done in CSSStyleSelector::adjustRenderStyle().
if (blendedStyle->hasAutoZIndex() && (blendedStyle->opacity() < 1.0f || blendedStyle->hasTransform()))
diff --git a/src/3rdparty/webkit/WebCore/page/animation/AnimationControllerPrivate.h b/src/3rdparty/webkit/WebCore/page/animation/AnimationControllerPrivate.h
index 7db3803..682dd75 100644
--- a/src/3rdparty/webkit/WebCore/page/animation/AnimationControllerPrivate.h
+++ b/src/3rdparty/webkit/WebCore/page/animation/AnimationControllerPrivate.h
@@ -49,7 +49,7 @@ class Node;
class RenderObject;
class RenderStyle;
-class AnimationControllerPrivate {
+class AnimationControllerPrivate : public Noncopyable {
public:
AnimationControllerPrivate(Frame*);
~AnimationControllerPrivate();
diff --git a/src/3rdparty/webkit/WebCore/page/animation/CompositeAnimation.cpp b/src/3rdparty/webkit/WebCore/page/animation/CompositeAnimation.cpp
index 8946d80..34f03c7 100644
--- a/src/3rdparty/webkit/WebCore/page/animation/CompositeAnimation.cpp
+++ b/src/3rdparty/webkit/WebCore/page/animation/CompositeAnimation.cpp
@@ -57,6 +57,7 @@ void CompositeAnimation::clearRenderer()
}
}
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();
@@ -186,6 +187,8 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, Render
if (m_keyframeAnimations.isEmpty() && !targetStyle->hasAnimations())
return;
+ m_keyframeAnimations.checkConsistency();
+
AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
if (currentStyle && currentStyle->hasAnimations() && targetStyle->hasAnimations() && *(currentStyle->animations()) == *(targetStyle->animations())) {
@@ -262,6 +265,7 @@ PassRefPtr<RenderStyle> CompositeAnimation::animate(RenderObject* renderer, Rend
// We don't do any transitions if we don't have a currentStyle (on startup).
updateTransitions(renderer, currentStyle, targetStyle);
updateKeyframeAnimations(renderer, currentStyle, targetStyle);
+ m_keyframeAnimations.checkConsistency();
if (currentStyle) {
// Now that we have transition objects ready, let them know about the new goal state. We want them
@@ -295,6 +299,8 @@ PassRefPtr<RenderStyle> CompositeAnimation::getAnimatedStyle() const
implicitAnimation->getAnimatedStyle(resultStyle);
}
+ m_keyframeAnimations.checkConsistency();
+
for (Vector<AtomicStringImpl*>::const_iterator it = m_keyframeAnimationOrderMap.begin(); it != m_keyframeAnimationOrderMap.end(); ++it) {
RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(*it);
if (keyframeAnimation)
@@ -315,6 +321,7 @@ void CompositeAnimation::setAnimating(bool animating)
}
}
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();
@@ -341,6 +348,7 @@ double CompositeAnimation::timeToNextService() 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* animation = it->second.get();
@@ -362,6 +370,7 @@ PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(int pr
// We want to send back the last animation with the property if there are multiples.
// So we need to iterate through all animations
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) {
RefPtr<KeyframeAnimation> anim = it->second;
@@ -381,6 +390,7 @@ void CompositeAnimation::suspendAnimations()
m_isSuspended = true;
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) {
if (KeyframeAnimation* anim = it->second.get())
@@ -405,6 +415,7 @@ void CompositeAnimation::resumeAnimations()
m_isSuspended = false;
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();
@@ -450,6 +461,7 @@ void CompositeAnimation::resumeOverriddenImplicitAnimations(int property)
bool CompositeAnimation::isAnimatingProperty(int property, 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();
@@ -474,6 +486,8 @@ bool CompositeAnimation::pauseAnimationAtTime(const AtomicString& name, double t
if (!name)
return false;
+ m_keyframeAnimations.checkConsistency();
+
RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name.impl());
if (!keyframeAnim || !keyframeAnim->running())
return false;
@@ -509,6 +523,7 @@ unsigned CompositeAnimation::numberOfActiveAnimations() const
unsigned count = 0;
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();
diff --git a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp
index 50fc781..328fe0e 100644
--- a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp
+++ b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp
@@ -55,7 +55,7 @@ ImplicitAnimation::~ImplicitAnimation()
{
// // Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed.
if (!postActive())
- endAnimation(true);
+ endAnimation();
}
bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inListenerType) const
@@ -106,21 +106,21 @@ void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
}
-bool ImplicitAnimation::startAnimation(double beginTime)
+bool ImplicitAnimation::startAnimation(double timeOffset)
{
#if USE(ACCELERATED_COMPOSITING)
if (m_object && m_object->hasLayer()) {
RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
if (layer->isComposited())
- return layer->backing()->startTransition(beginTime, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
+ return layer->backing()->startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
}
#else
- UNUSED_PARAM(beginTime);
+ UNUSED_PARAM(timeOffset);
#endif
return false;
}
-void ImplicitAnimation::endAnimation(bool /*reset*/)
+void ImplicitAnimation::endAnimation()
{
#if USE(ACCELERATED_COMPOSITING)
if (m_object && m_object->hasLayer()) {
@@ -143,7 +143,7 @@ void ImplicitAnimation::onAnimationEnd(double elapsedTime)
keyframeAnim->setUnanimatedStyle(m_toStyle);
sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime);
- endAnimation(true);
+ endAnimation();
}
bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, double elapsedTime)
@@ -161,7 +161,7 @@ bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, doubl
if (m_object->node() && m_object->node()->isElementNode())
element = static_cast<Element*>(m_object->node());
- ASSERT(!element || element->document() && !element->document()->inPageCache());
+ ASSERT(!element || (element->document() && !element->document()->inPageCache()));
if (!element)
return false;
diff --git a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.h b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.h
index 7e286d2..be5c197 100644
--- a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.h
+++ b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.h
@@ -47,8 +47,9 @@ public:
int animatingProperty() const { return m_animatingProperty; }
virtual void onAnimationEnd(double elapsedTime);
- virtual bool startAnimation(double beginTime);
- virtual void endAnimation(bool reset);
+ virtual bool startAnimation(double timeOffset);
+ virtual void pauseAnimation(double /*timeOffset*/) { }
+ virtual void endAnimation();
virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
virtual void getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle);
diff --git a/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.cpp b/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.cpp
index 7e37e5f..0e76ea9 100644
--- a/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.cpp
+++ b/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.cpp
@@ -36,6 +36,7 @@
#include "EventNames.h"
#include "RenderLayer.h"
#include "RenderLayerBacking.h"
+#include "RenderStyle.h"
#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -58,7 +59,7 @@ KeyframeAnimation::~KeyframeAnimation()
{
// Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed.
if (!postActive())
- endAnimation(true);
+ endAnimation();
}
void KeyframeAnimation::getKeyframeAnimationInterval(const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& prog) const
@@ -119,9 +120,11 @@ void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const Render
}
// If we are waiting for the start timer, we don't want to change the style yet.
- // Special case - if the delay time is 0, then we do want to set the first frame of the
+ // Special case 1 - if the delay time is 0, then we do want to set the first frame of the
// animation right away. This avoids a flash when the animation starts.
- if (waitingToStart() && m_animation->delay() > 0)
+ // Special case 2 - if there is a backwards fill mode, then we want to continue
+ // through to the style blend so that we get the fromStyle.
+ if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
return;
// FIXME: we need to be more efficient about determining which keyframes we are animating between.
@@ -191,40 +194,54 @@ bool KeyframeAnimation::hasAnimationForProperty(int property) const
return false;
}
-bool KeyframeAnimation::startAnimation(double beginTime)
+bool KeyframeAnimation::startAnimation(double timeOffset)
{
#if USE(ACCELERATED_COMPOSITING)
if (m_object && m_object->hasLayer()) {
RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
if (layer->isComposited())
- return layer->backing()->startAnimation(beginTime, m_animation.get(), m_keyframes);
+ return layer->backing()->startAnimation(timeOffset, m_animation.get(), m_keyframes);
}
#else
- UNUSED_PARAM(beginTime);
+ UNUSED_PARAM(timeOffset);
#endif
return false;
}
-void KeyframeAnimation::endAnimation(bool reset)
+void KeyframeAnimation::pauseAnimation(double timeOffset)
{
- if (m_object) {
+ if (!m_object)
+ return;
+
#if USE(ACCELERATED_COMPOSITING)
- if (m_object->hasLayer()) {
- RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
- if (layer->isComposited()) {
- if (reset)
- layer->backing()->animationFinished(m_keyframes.animationName());
- else
- layer->backing()->animationPaused(m_keyframes.animationName());
- }
- }
+ if (m_object->hasLayer()) {
+ RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+ if (layer->isComposited())
+ layer->backing()->animationPaused(timeOffset, m_keyframes.animationName());
+ }
#else
- UNUSED_PARAM(reset);
+ UNUSED_PARAM(timeOffset);
#endif
- // Restore the original (unanimated) style
- if (!paused())
- setNeedsStyleRecalc(m_object->node());
+ // Restore the original (unanimated) style
+ if (!paused())
+ setNeedsStyleRecalc(m_object->node());
+}
+
+void KeyframeAnimation::endAnimation()
+{
+ if (!m_object)
+ return;
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_object->hasLayer()) {
+ RenderLayer* layer = toRenderBoxModelObject(m_object)->layer();
+ if (layer->isComposited())
+ layer->backing()->animationFinished(m_keyframes.animationName());
}
+#endif
+ // Restore the original (unanimated) style
+ if (!paused())
+ setNeedsStyleRecalc(m_object->node());
}
bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType) const
@@ -245,7 +262,10 @@ void KeyframeAnimation::onAnimationIteration(double elapsedTime)
void KeyframeAnimation::onAnimationEnd(double elapsedTime)
{
sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime);
- endAnimation(true);
+ // End the animation if we don't fill forwards. Forward filling
+ // animations are ended properly in the class destructor.
+ if (!m_animation->fillsForwards())
+ endAnimation();
}
bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime)
@@ -266,7 +286,7 @@ bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double
if (m_object->node() && m_object->node()->isElementNode())
element = static_cast<Element*>(m_object->node());
- ASSERT(!element || element->document() && !element->document()->inPageCache());
+ ASSERT(!element || (element->document() && !element->document()->inPageCache()));
if (!element)
return false;
diff --git a/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.h b/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.h
index 4905fc3..fab0ae8 100644
--- a/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.h
+++ b/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.h
@@ -32,10 +32,11 @@
#include "AnimationBase.h"
#include "Document.h"
#include "KeyframeList.h"
-#include "RenderStyle.h"
namespace WebCore {
+class RenderStyle;
+
// A KeyframeAnimation tracks the state of an explicit animation
// for a single RenderObject.
class KeyframeAnimation : public AnimationBase {
@@ -63,8 +64,9 @@ protected:
virtual void onAnimationStart(double elapsedTime);
virtual void onAnimationIteration(double elapsedTime);
virtual void onAnimationEnd(double elapsedTime);
- virtual bool startAnimation(double beginTime);
- virtual void endAnimation(bool reset);
+ virtual bool startAnimation(double timeOffset);
+ virtual void pauseAnimation(double timeOffset);
+ virtual void endAnimation();
virtual void overrideAnimations();
virtual void resumeOverriddenAnimations();
diff --git a/src/3rdparty/webkit/WebCore/page/qt/DragControllerQt.cpp b/src/3rdparty/webkit/WebCore/page/qt/DragControllerQt.cpp
index e6c7682..33815b5 100644
--- a/src/3rdparty/webkit/WebCore/page/qt/DragControllerQt.cpp
+++ b/src/3rdparty/webkit/WebCore/page/qt/DragControllerQt.cpp
@@ -66,6 +66,7 @@ const IntSize& DragController::maxDragImageSize()
void DragController::cleanupAfterSystemDrag()
{
+ dragEnded();
}
}
diff --git a/src/3rdparty/webkit/WebCore/page/qt/EventHandlerQt.cpp b/src/3rdparty/webkit/WebCore/page/qt/EventHandlerQt.cpp
index 3425289..d7982fa 100644
--- a/src/3rdparty/webkit/WebCore/page/qt/EventHandlerQt.cpp
+++ b/src/3rdparty/webkit/WebCore/page/qt/EventHandlerQt.cpp
@@ -132,7 +132,11 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
unsigned EventHandler::accessKeyModifiers()
{
- return PlatformKeyboardEvent::CtrlKey;
+#if OS(DARWIN)
+ return PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;
+#else
+ return PlatformKeyboardEvent::AltKey;
+#endif
}
}
diff --git a/src/3rdparty/webkit/WebCore/page/win/EventHandlerWin.cpp b/src/3rdparty/webkit/WebCore/page/win/EventHandlerWin.cpp
index 50e50fb..5511209 100644
--- a/src/3rdparty/webkit/WebCore/page/win/EventHandlerWin.cpp
+++ b/src/3rdparty/webkit/WebCore/page/win/EventHandlerWin.cpp
@@ -88,7 +88,7 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const
PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
-#if PLATFORM(WINCE)
+#if OS(WINCE)
return 0;
#else
COMPtr<WCDataObject> dataObject;
diff --git a/src/3rdparty/webkit/WebCore/page/win/FrameCGWin.cpp b/src/3rdparty/webkit/WebCore/page/win/FrameCGWin.cpp
index 7483627..cce5004 100644
--- a/src/3rdparty/webkit/WebCore/page/win/FrameCGWin.cpp
+++ b/src/3rdparty/webkit/WebCore/page/win/FrameCGWin.cpp
@@ -45,13 +45,16 @@ static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext*
rect.move(-offset.width(), -offset.height());
rect = view->convertToContainingWindow(rect);
- gc->concatCTM(TransformationMatrix().translate(-rect.x(), -rect.y()));
+ gc->concatCTM(AffineTransform().translate(-rect.x(), -rect.y()));
view->paint(gc, rect);
}
static HBITMAP imageFromRect(const Frame* frame, IntRect& ir)
{
+ PaintBehavior oldPaintBehavior = frame->view()->paintBehavior();
+ frame->view()->setPaintBehavior(oldPaintBehavior | PaintBehaviorFlattenCompositingLayers);
+
void* bits;
HDC hdc = CreateCompatibleDC(0);
int w = ir.width();
@@ -74,6 +77,8 @@ static HBITMAP imageFromRect(const Frame* frame, IntRect& ir)
SelectObject(hdc, hbmpOld);
DeleteDC(hdc);
+ frame->view()->setPaintBehavior(oldPaintBehavior);
+
return hbmp;
}
@@ -81,12 +86,12 @@ HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
{
frame->document()->updateLayout();
- frame->view()->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
+ frame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0));
FloatRect fr = frame->selectionBounds();
IntRect ir(static_cast<int>(fr.x()), static_cast<int>(fr.y()),
static_cast<int>(fr.width()), static_cast<int>(fr.height()));
HBITMAP image = imageFromRect(frame, ir);
- frame->view()->setPaintRestriction(PaintRestrictionNone);
+ frame->view()->setPaintBehavior(PaintBehaviorNormal);
return image;
}
diff --git a/src/3rdparty/webkit/WebCore/page/win/FrameCairoWin.cpp b/src/3rdparty/webkit/WebCore/page/win/FrameCairoWin.cpp
index f5b832e..3e1fe28 100644
--- a/src/3rdparty/webkit/WebCore/page/win/FrameCairoWin.cpp
+++ b/src/3rdparty/webkit/WebCore/page/win/FrameCairoWin.cpp
@@ -24,6 +24,7 @@
*/
#include "config.h"
+#include "Frame.h"
#include "FrameWin.h"
#include "EditorClient.h"
diff --git a/src/3rdparty/webkit/WebCore/page/win/FrameWin.cpp b/src/3rdparty/webkit/WebCore/page/win/FrameWin.cpp
index b15d195..2b5435d 100644
--- a/src/3rdparty/webkit/WebCore/page/win/FrameWin.cpp
+++ b/src/3rdparty/webkit/WebCore/page/win/FrameWin.cpp
@@ -24,69 +24,25 @@
*/
#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 "PrintContext.h"
#include "RenderView.h"
#include "Settings.h"
-
-using std::min;
+#include "TransformationMatrix.h"
namespace WebCore {
-void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& outPageHeight)
+void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& outPages, int& outPageHeight)
{
- ASSERT(frame);
-
- pages.clear();
- outPageHeight = 0;
-
- if (!frame->document() || !frame->view() || !frame->document()->renderer())
- return;
-
- RenderView* root = toRenderView(frame->document()->renderer());
-
- if (!root) {
- LOG_ERROR("document to be printed has no renderer");
- return;
- }
-
- if (userScaleFactor <= 0) {
- LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
- return;
- }
-
- float ratio = static_cast<float>(printRect.height()) / static_cast<float>(printRect.width());
-
- float pageWidth = static_cast<float>(root->rightLayoutOverflow());
- float pageHeight = pageWidth * ratio;
- outPageHeight = static_cast<int>(pageHeight); // this is the height of the page adjusted by margins
- pageHeight -= (headerHeight + footerHeight);
-
- if (pageHeight <= 0) {
- LOG_ERROR("pageHeight has bad value %.2f", pageHeight);
- return;
- }
-
- float currPageHeight = pageHeight / userScaleFactor;
- float docHeight = root->layer()->height();
- float docWidth = root->layer()->width();
- float currPageWidth = pageWidth / userScaleFactor;
-
-
- // always return at least one page, since empty files should print a blank page
- float printedPagesHeight = 0.0f;
- do {
- float proposedBottom = min(docHeight, printedPagesHeight + pageHeight);
- frame->view()->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
- currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
-
- pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight));
- printedPagesHeight += currPageHeight;
- } while (printedPagesHeight < docHeight);
+ PrintContext printContext(frame);
+ float pageHeight = 0;
+ printContext.computePageRects(printRect, headerHeight, footerHeight, userScaleFactor, pageHeight);
+ outPageHeight = static_cast<int>(pageHeight);
+ outPages = printContext.pageRects();
}
DragImageRef Frame::dragImageForSelection()
diff --git a/src/3rdparty/webkit/WebCore/page/win/FrameWin.h b/src/3rdparty/webkit/WebCore/page/win/FrameWin.h
index 2924291..4c274b7 100644
--- a/src/3rdparty/webkit/WebCore/page/win/FrameWin.h
+++ b/src/3rdparty/webkit/WebCore/page/win/FrameWin.h
@@ -26,15 +26,18 @@
#ifndef FrameWin_H
#define FrameWin_H
-#include "Frame.h"
+#include <wtf/Vector.h>
// Forward declared so we don't need wingdi.h.
typedef struct HBITMAP__* HBITMAP;
namespace WebCore {
+ class Frame;
+ class IntRect;
+
HBITMAP imageFromSelection(Frame* frame, bool forceWhiteText);
- void computePageRectsForFrame(Frame*, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& pageHeight);
+ void computePageRectsForFrame(Frame*, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& outPages, int& outPageHeight);
}
diff --git a/src/3rdparty/webkit/WebCore/page/win/PageWin.cpp b/src/3rdparty/webkit/WebCore/page/win/PageWin.cpp
deleted file mode 100644
index 5d7450c..0000000
--- a/src/3rdparty/webkit/WebCore/page/win/PageWin.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 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 COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "Page.h"
-
-#include "Frame.h"
-#include "FrameLoaderClient.h"
-#include "FrameView.h"
-#include "FloatRect.h"
-#include "PluginView.h"
-#include <windows.h>
-
-namespace WebCore {
-
-HINSTANCE Page::s_instanceHandle = 0;
-
-void Page::setCanStartPlugins(bool canStartPlugins)
-{
- if (m_canStartPlugins == canStartPlugins)
- return;
-
- m_canStartPlugins = canStartPlugins;
-
- if (!m_canStartPlugins || m_unstartedPlugins.isEmpty())
- return;
-
- Vector<PluginView*> unstartedPlugins;
- copyToVector(m_unstartedPlugins, unstartedPlugins);
- m_unstartedPlugins.clear();
-
- for (size_t i = 0; i < unstartedPlugins.size(); ++i) {
- if (unstartedPlugins[i]->start())
- continue;
- unstartedPlugins[i]->parentFrame()->loader()->client()->dispatchDidFailToStartPlugin(unstartedPlugins[i]);
- }
-}
-
-} // namespace WebCore
-