summaryrefslogtreecommitdiffstats
path: root/WebCore/page
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-10-08 17:19:54 +0100
committerSteve Block <steveblock@google.com>2009-10-20 00:41:58 +0100
commit231d4e3152a9c27a73b6ac7badbe6be673aa3ddf (patch)
treea6c7e2d6cd7bfa7011cc39abbb436142d7a4a7c8 /WebCore/page
parente196732677050bd463301566a68a643b6d14b907 (diff)
downloadexternal_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.zip
external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.gz
external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.bz2
Merge webkit.org at R49305 : Automatic merge by git.
Change-Id: I8968561bc1bfd72b8923b7118d3728579c6dbcc7
Diffstat (limited to 'WebCore/page')
-rw-r--r--WebCore/page/Chrome.cpp18
-rw-r--r--WebCore/page/Chrome.h10
-rw-r--r--WebCore/page/ChromeClient.h17
-rw-r--r--WebCore/page/Console.cpp38
-rw-r--r--WebCore/page/Console.h3
-rw-r--r--WebCore/page/ContextMenuController.cpp14
-rw-r--r--WebCore/page/Coordinates.h4
-rw-r--r--WebCore/page/DOMTimer.cpp14
-rw-r--r--WebCore/page/DOMTimer.h3
-rw-r--r--WebCore/page/DOMWindow.cpp1065
-rw-r--r--WebCore/page/DOMWindow.h117
-rw-r--r--WebCore/page/DOMWindow.idl56
-rw-r--r--WebCore/page/DragController.cpp41
-rw-r--r--WebCore/page/EventHandler.cpp147
-rw-r--r--WebCore/page/EventHandler.h49
-rw-r--r--WebCore/page/EventSource.cpp314
-rw-r--r--WebCore/page/EventSource.h134
-rw-r--r--WebCore/page/EventSource.idl65
-rw-r--r--WebCore/page/FocusController.cpp23
-rw-r--r--WebCore/page/Frame.cpp101
-rw-r--r--WebCore/page/Frame.h37
-rw-r--r--WebCore/page/FrameTree.cpp2
-rw-r--r--WebCore/page/FrameView.cpp211
-rw-r--r--WebCore/page/FrameView.h34
-rw-r--r--WebCore/page/Geolocation.cpp119
-rw-r--r--WebCore/page/Geolocation.h19
-rw-r--r--WebCore/page/HaltablePlugin.h44
-rw-r--r--WebCore/page/History.cpp10
-rw-r--r--WebCore/page/Navigator.cpp20
-rw-r--r--WebCore/page/Navigator.h5
-rw-r--r--WebCore/page/Navigator.idl4
-rw-r--r--WebCore/page/OriginAccessEntry.cpp81
-rw-r--r--WebCore/page/OriginAccessEntry.h61
-rw-r--r--WebCore/page/Page.cpp151
-rw-r--r--WebCore/page/Page.h47
-rw-r--r--WebCore/page/PageGroup.cpp137
-rw-r--r--WebCore/page/PageGroup.h25
-rw-r--r--WebCore/page/PageGroupLoadDeferrer.cpp6
-rw-r--r--WebCore/page/PluginHalter.cpp112
-rw-r--r--WebCore/page/PluginHalter.h59
-rw-r--r--WebCore/page/PluginHalterClient.h42
-rw-r--r--WebCore/page/PositionCallback.h4
-rw-r--r--WebCore/page/PositionError.h4
-rw-r--r--WebCore/page/PositionOptions.h4
-rw-r--r--WebCore/page/PrintContext.cpp2
-rw-r--r--WebCore/page/SecurityOrigin.cpp151
-rw-r--r--WebCore/page/SecurityOrigin.h35
-rw-r--r--WebCore/page/Settings.cpp61
-rw-r--r--WebCore/page/Settings.h37
-rw-r--r--WebCore/page/UserContentURLPattern.cpp226
-rw-r--r--WebCore/page/UserContentURLPattern.h72
-rw-r--r--WebCore/page/UserScript.h69
-rw-r--r--WebCore/page/UserScriptTypes.h43
-rw-r--r--WebCore/page/UserStyleSheet.h66
-rw-r--r--WebCore/page/UserStyleSheetTypes.h41
-rw-r--r--WebCore/page/XSSAuditor.cpp90
-rw-r--r--WebCore/page/XSSAuditor.h30
-rw-r--r--WebCore/page/animation/AnimationBase.cpp181
-rw-r--r--WebCore/page/animation/AnimationController.cpp16
-rw-r--r--WebCore/page/chromium/FrameChromium.cpp2
-rw-r--r--WebCore/page/gtk/EventHandlerGtk.cpp9
-rw-r--r--WebCore/page/haiku/DragControllerHaiku.cpp5
-rw-r--r--WebCore/page/haiku/EventHandlerHaiku.cpp11
-rw-r--r--WebCore/page/mac/DragControllerMac.mm5
-rw-r--r--WebCore/page/mac/EventHandlerMac.mm18
-rw-r--r--WebCore/page/mac/FrameMac.mm33
-rw-r--r--WebCore/page/mac/WebCoreViewFactory.h9
-rw-r--r--WebCore/page/qt/FrameQt.cpp18
-rw-r--r--WebCore/page/win/FrameWin.cpp2
-rw-r--r--WebCore/page/wince/FrameWince.cpp17
-rw-r--r--WebCore/page/wx/EventHandlerWx.cpp36
-rw-r--r--WebCore/page/wx/FrameWx.cpp38
72 files changed, 3558 insertions, 1236 deletions
diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp
index 5a5670e..96f0fb7 100644
--- a/WebCore/page/Chrome.cpp
+++ b/WebCore/page/Chrome.cpp
@@ -87,9 +87,9 @@ IntRect Chrome::windowToScreen(const IntRect& rect) const
return m_client->windowToScreen(rect);
}
-PlatformWidget Chrome::platformWindow() const
+PlatformPageClient Chrome::platformPageClient() const
{
- return m_client->platformWindow();
+ return m_client->platformPageClient();
}
void Chrome::contentsSizeChanged(Frame* frame, const IntSize& size) const
@@ -102,6 +102,11 @@ void Chrome::scrollRectIntoView(const IntRect& rect, const ScrollView* scrollVie
m_client->scrollRectIntoView(rect, scrollView);
}
+void Chrome::scrollbarsModeDidChange() const
+{
+ m_client->scrollbarsModeDidChange();
+}
+
void Chrome::setWindowRect(const FloatRect& rect) const
{
m_client->setWindowRect(rect);
@@ -311,8 +316,10 @@ void Chrome::mouseDidMoveOverElement(const HitTestResult& result, unsigned modif
}
m_client->mouseDidMoveOverElement(result, modifierFlags);
+#if ENABLE(INSPECTOR)
if (InspectorController* inspector = m_page->inspectorController())
inspector->mouseDidMoveOverElement(result, modifierFlags);
+#endif
}
void Chrome::setToolTip(const HitTestResult& result)
@@ -403,6 +410,13 @@ bool Chrome::setCursor(PlatformCursorHandle cursor)
return m_client->setCursor(cursor);
}
+#if ENABLE(NOTIFICATIONS)
+NotificationPresenter* Chrome::notificationPresenter() const
+{
+ return m_client->notificationPresenter();
+}
+#endif
+
// --------
#if ENABLE(DASHBOARD_SUPPORT)
diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h
index c26e450..033311d 100644
--- a/WebCore/page/Chrome.h
+++ b/WebCore/page/Chrome.h
@@ -44,6 +44,9 @@ namespace WebCore {
class IntRect;
class Page;
class String;
+#if ENABLE(NOTIFICATIONS)
+ class NotificationPresenter;
+#endif
struct FrameLoadRequest;
struct WindowFeatures;
@@ -60,8 +63,9 @@ namespace WebCore {
virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
virtual IntPoint screenToWindow(const IntPoint&) const;
virtual IntRect windowToScreen(const IntRect&) const;
- virtual PlatformWidget platformWindow() const;
+ virtual PlatformPageClient platformPageClient() const;
virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const;
+ virtual void scrollbarsModeDidChange() const;
void contentsSizeChanged(Frame*, const IntSize&) const;
@@ -128,6 +132,10 @@ namespace WebCore {
void focusNSView(NSView*);
#endif
+#if ENABLE(NOTIFICATIONS)
+ NotificationPresenter* notificationPresenter() const;
+#endif
+
private:
Page* m_page;
ChromeClient* m_client;
diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h
index 409a492..5231603 100644
--- a/WebCore/page/ChromeClient.h
+++ b/WebCore/page/ChromeClient.h
@@ -62,6 +62,10 @@ namespace WebCore {
class GraphicsLayer;
#endif
+#if ENABLE(NOTIFICATIONS)
+ class NotificationPresenter;
+#endif
+
class ChromeClient {
public:
virtual void chromeDestroyed() = 0;
@@ -124,11 +128,12 @@ namespace WebCore {
virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) = 0;
virtual IntPoint screenToWindow(const IntPoint&) const = 0;
virtual IntRect windowToScreen(const IntRect&) const = 0;
- virtual PlatformWidget platformWindow() const = 0;
+ virtual PlatformPageClient platformPageClient() const = 0;
virtual void contentsSizeChanged(Frame*, const IntSize&) const = 0;
virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const = 0; // Currently only Mac has a non empty implementation.
// End methods used by HostWindow.
+ virtual void scrollbarsModeDidChange() const = 0;
virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) = 0;
virtual void setToolTip(const String&, TextDirection) = 0;
@@ -152,6 +157,10 @@ namespace WebCore {
virtual void dashboardRegionsChanged();
#endif
+#if ENABLE(NOTIFICATIONS)
+ virtual NotificationPresenter* notificationPresenter() const = 0;
+#endif
+
virtual void populateVisitedLinks();
virtual FloatRect customHighlightRect(Node*, const AtomicString& type, const FloatRect& lineRect);
@@ -166,7 +175,7 @@ namespace WebCore {
float value, float proportion, ScrollbarControlPartMask);
virtual bool paintCustomScrollCorner(GraphicsContext*, const FloatRect&);
- // This is an asynchronous call. The ChromeClient can display UI asking the user for permission
+ // 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.
virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*) = 0;
@@ -194,6 +203,10 @@ namespace WebCore {
virtual void scheduleCompositingLayerSync() = 0;
#endif
+ virtual bool supportsFullscreenForNode(const Node*) { return false; }
+ virtual void enterFullscreenForNode(Node*) { }
+ virtual void exitFullscreenForNode(Node*) { }
+
#if PLATFORM(MAC)
virtual KeyboardUIMode keyboardUIMode() { return KeyboardAccessDefault; }
diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp
index b5c9bb2..79613d3 100644
--- a/WebCore/page/Console.cpp
+++ b/WebCore/page/Console.cpp
@@ -129,6 +129,9 @@ static void printMessageSourceAndLevelPrefix(MessageSource source, MessageLevel
case ErrorMessageLevel:
levelString = "ERROR";
break;
+ case DebugMessageLevel:
+ levelString = "DEBUG";
+ break;
default:
ASSERT_NOT_REACHED();
levelString = "UNKNOWN";
@@ -147,7 +150,9 @@ void Console::addMessage(MessageSource source, MessageType type, MessageLevel le
if (source == JSMessageSource)
page->chrome()->client()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL);
+#if ENABLE(INSPECTOR)
page->inspectorController()->addMessageToConsole(source, type, level, message, lineNumber, sourceURL);
+#endif
if (!Console::shouldPrintExceptions())
return;
@@ -173,7 +178,9 @@ void Console::addMessage(MessageType type, MessageLevel level, ScriptCallStack*
if (getFirstArgumentAsString(callStack->state(), lastCaller, message))
page->chrome()->client()->addMessageToConsole(JSMessageSource, type, level, message, lastCaller.lineNumber(), lastCaller.sourceURL().prettyURL());
+#if ENABLE(INSPECTOR)
page->inspectorController()->addMessageToConsole(JSMessageSource, type, level, callStack);
+#endif
if (!Console::shouldPrintExceptions())
return;
@@ -246,6 +253,7 @@ void Console::assertCondition(bool condition, ScriptCallStack* callStack)
void Console::count(ScriptCallStack* callStack)
{
+#if ENABLE(INSPECTOR)
Page* page = this->page();
if (!page)
return;
@@ -257,6 +265,9 @@ void Console::count(ScriptCallStack* callStack)
getFirstArgumentAsString(callStack->state(), lastCaller, title);
page->inspectorController()->count(title, lastCaller.lineNumber(), lastCaller.sourceURL().string());
+#else
+ UNUSED_PARAM(callStack);
+#endif
}
#if ENABLE(WML)
@@ -293,19 +304,27 @@ void Console::profile(const JSC::UString& title, ScriptCallStack* callStack)
if (!page)
return;
+#if ENABLE(INSPECTOR)
InspectorController* controller = page->inspectorController();
// FIXME: log a console message when profiling is disabled.
if (!controller->profilerEnabled())
return;
+#endif
JSC::UString 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);
+#if ENABLE(INSPECTOR)
const ScriptCallFrame& lastCaller = callStack->at(0);
controller->addStartProfilingMessageToConsole(resolvedTitle, lastCaller.lineNumber(), lastCaller.sourceURL());
+#endif
}
void Console::profileEnd(const JSC::UString& title, ScriptCallStack* callStack)
@@ -317,9 +336,11 @@ void Console::profileEnd(const JSC::UString& title, ScriptCallStack* callStack)
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);
if (!profile)
@@ -327,14 +348,17 @@ void Console::profileEnd(const JSC::UString& title, ScriptCallStack* callStack)
m_profiles.append(profile);
+#if ENABLE(INSPECTOR)
const ScriptCallFrame& lastCaller = callStack->at(0);
controller->addProfile(profile, lastCaller.lineNumber(), lastCaller.sourceURL());
+#endif
}
#endif
void Console::time(const String& title)
{
+#if ENABLE(INSPECTOR)
Page* page = this->page();
if (!page)
return;
@@ -345,10 +369,14 @@ void Console::time(const String& title)
return;
page->inspectorController()->startTiming(title);
+#else
+ UNUSED_PARAM(title);
+#endif
}
void Console::timeEnd(const String& title, ScriptCallStack* callStack)
{
+#if ENABLE(INSPECTOR)
Page* page = this->page();
if (!page)
return;
@@ -366,24 +394,34 @@ void Console::timeEnd(const String& title, ScriptCallStack* callStack)
const ScriptCallFrame& lastCaller = callStack->at(0);
page->inspectorController()->addMessageToConsole(JSMessageSource, LogMessageType, LogMessageLevel, message, lastCaller.lineNumber(), lastCaller.sourceURL().string());
+#else
+ UNUSED_PARAM(title);
+ UNUSED_PARAM(callStack);
+#endif
}
void Console::group(ScriptCallStack* callStack)
{
+#if ENABLE(INSPECTOR)
Page* page = this->page();
if (!page)
return;
page->inspectorController()->startGroup(JSMessageSource, callStack);
+#else
+ UNUSED_PARAM(callStack);
+#endif
}
void Console::groupEnd()
{
+#if ENABLE(INSPECTOR)
Page* page = this->page();
if (!page)
return;
page->inspectorController()->endGroup(JSMessageSource, 0, String());
+#endif
}
void Console::warn(ScriptCallStack* callStack)
diff --git a/WebCore/page/Console.h b/WebCore/page/Console.h
index 6d4dbce..08d43e3 100644
--- a/WebCore/page/Console.h
+++ b/WebCore/page/Console.h
@@ -71,7 +71,8 @@ namespace WebCore {
TipMessageLevel,
LogMessageLevel,
WarningMessageLevel,
- ErrorMessageLevel
+ ErrorMessageLevel,
+ DebugMessageLevel
};
class Console : public RefCounted<Console> {
diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp
index 0ec9d1c..1cf0014 100644
--- a/WebCore/page/ContextMenuController.cpp
+++ b/WebCore/page/ContextMenuController.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "ContextMenuController.h"
+#if ENABLE(CONTEXT_MENUS)
+
#include "Chrome.h"
#include "ContextMenu.h"
#include "ContextMenuClient.h"
@@ -95,8 +97,10 @@ void ContextMenuController::handleContextMenuEvent(Event* event)
m_contextMenu.set(new ContextMenu(result));
m_contextMenu->populate();
+#if ENABLE(INSPECTOR)
if (m_page->inspectorController()->enabled())
m_contextMenu->addInspectElementItem();
+#endif
PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get());
m_contextMenu->setPlatformDescription(customMenu);
@@ -162,10 +166,12 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
frame->editor()->copy();
break;
case ContextMenuItemTagGoBack:
- frame->loader()->goBackOrForward(-1);
+ if (Page* page = frame->page())
+ page->goBackOrForward(-1);
break;
case ContextMenuItemTagGoForward:
- frame->loader()->goBackOrForward(1);
+ if (Page* page = frame->page())
+ page->goBackOrForward(1);
break;
case ContextMenuItemTagStop:
frame->loader()->stop();
@@ -325,13 +331,17 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item)
frame->editor()->changeBackToReplacedString(result.replacedString());
break;
#endif
+#if ENABLE(INSPECTOR)
case ContextMenuItemTagInspectElement:
if (Page* page = frame->page())
page->inspectorController()->inspect(result.innerNonSharedNode());
break;
+#endif
default:
break;
}
}
} // namespace WebCore
+
+#endif // ENABLE(CONTEXT_MENUS)
diff --git a/WebCore/page/Coordinates.h b/WebCore/page/Coordinates.h
index 43870a1..bd29d42 100644
--- a/WebCore/page/Coordinates.h
+++ b/WebCore/page/Coordinates.h
@@ -50,7 +50,11 @@ public:
bool canProvideAltitudeAccuracy() const { return m_canProvideAltitudeAccuracy; }
bool canProvideHeading() const { return m_canProvideHeading; }
bool canProvideSpeed() const { return m_canProvideSpeed; }
+<<<<<<< HEAD:WebCore/page/Coordinates.h
+=======
+
+>>>>>>> webkit.org at 49305:WebCore/page/Coordinates.h
private:
Coordinates(double latitude, double longitude, bool providesAltitude, double altitude, double accuracy, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed)
: m_latitude(latitude)
diff --git a/WebCore/page/DOMTimer.cpp b/WebCore/page/DOMTimer.cpp
index c42a0dc..dd1e842 100644
--- a/WebCore/page/DOMTimer.cpp
+++ b/WebCore/page/DOMTimer.cpp
@@ -47,6 +47,9 @@ DOMTimer::DOMTimer(ScriptExecutionContext* context, ScheduledAction* action, int
, m_action(action)
, m_nextFireInterval(0)
, m_repeatInterval(0)
+#if !ASSERT_DISABLED
+ , m_suspended(false)
+#endif
{
static int lastUsedTimeoutId = 0;
++lastUsedTimeoutId;
@@ -148,7 +151,10 @@ void DOMTimer::stop()
void DOMTimer::suspend()
{
- ASSERT(!m_nextFireInterval && !m_repeatInterval);
+#if !ASSERT_DISABLED
+ ASSERT(!m_suspended);
+ m_suspended = true;
+#endif
m_nextFireInterval = nextFireInterval();
m_repeatInterval = repeatInterval();
TimerBase::stop();
@@ -156,9 +162,11 @@ void DOMTimer::suspend()
void DOMTimer::resume()
{
+#if !ASSERT_DISABLED
+ ASSERT(m_suspended);
+ m_suspended = false;
+#endif
start(m_nextFireInterval, m_repeatInterval);
- m_nextFireInterval = 0;
- m_repeatInterval = 0;
}
diff --git a/WebCore/page/DOMTimer.h b/WebCore/page/DOMTimer.h
index 6d6271f..3c65258 100644
--- a/WebCore/page/DOMTimer.h
+++ b/WebCore/page/DOMTimer.h
@@ -66,6 +66,9 @@ namespace WebCore {
OwnPtr<ScheduledAction> m_action;
double m_nextFireInterval;
double m_repeatInterval;
+#if !ASSERT_DISABLED
+ bool m_suspended;
+#endif
static double s_minTimerInterval;
};
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index e50b488..e80ce87 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -34,8 +34,11 @@
#include "CString.h"
#include "Chrome.h"
#include "Console.h"
+#include "Database.h"
+#include "DOMApplicationCache.h"
#include "DOMSelection.h"
#include "DOMTimer.h"
+#include "PageTransitionEvent.h"
#include "Document.h"
#include "Element.h"
#include "EventException.h"
@@ -54,32 +57,23 @@
#include "Media.h"
#include "MessageEvent.h"
#include "Navigator.h"
+#include "NotificationCenter.h"
#include "Page.h"
#include "PageGroup.h"
#include "PlatformScreen.h"
#include "PlatformString.h"
#include "Screen.h"
#include "SecurityOrigin.h"
+#include "SerializedScriptValue.h"
#include "Settings.h"
+#include "Storage.h"
+#include "StorageArea.h"
+#include "StorageNamespace.h"
#include "SuddenTermination.h"
#include "WebKitPoint.h"
#include <algorithm>
#include <wtf/MathExtras.h>
-#if ENABLE(DATABASE)
-#include "Database.h"
-#endif
-
-#if ENABLE(DOM_STORAGE)
-#include "Storage.h"
-#include "StorageArea.h"
-#include "StorageNamespace.h"
-#endif
-
-#if ENABLE(OFFLINE_WEB_APPLICATIONS)
-#include "DOMApplicationCache.h"
-#endif
-
using std::min;
using std::max;
@@ -87,24 +81,20 @@ namespace WebCore {
class PostMessageTimer : public TimerBase {
public:
- PostMessageTimer(DOMWindow* window, const String& message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortChannel> channel, SecurityOrigin* targetOrigin)
+ PostMessageTimer(DOMWindow* window, PassRefPtr<SerializedScriptValue> message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortChannelArray> channels, SecurityOrigin* targetOrigin)
: m_window(window)
, m_message(message)
, m_origin(sourceOrigin)
, m_source(source)
- , m_channel(channel)
+ , m_channels(channels)
, m_targetOrigin(targetOrigin)
{
}
PassRefPtr<MessageEvent> event(ScriptExecutionContext* context)
{
- RefPtr<MessagePort> messagePort;
- if (m_channel) {
- messagePort = MessagePort::create(*context);
- messagePort->entangle(m_channel.release());
- }
- return MessageEvent::create(m_message, m_origin, "", m_source, messagePort.release());
+ OwnPtr<MessagePortArray> messagePorts = MessagePort::entanglePorts(*context, m_channels.release());
+ return MessageEvent::create(messagePorts.release(), m_message, m_origin, "", m_source);
}
SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); }
@@ -115,90 +105,103 @@ private:
}
RefPtr<DOMWindow> m_window;
- String m_message;
+ RefPtr<SerializedScriptValue> m_message;
String m_origin;
RefPtr<DOMWindow> m_source;
- OwnPtr<MessagePortChannel> m_channel;
+ OwnPtr<MessagePortChannelArray> m_channels;
RefPtr<SecurityOrigin> m_targetOrigin;
};
-typedef HashMap<DOMWindow*, RegisteredEventListenerVector*> DOMWindowRegisteredEventListenerMap;
+typedef HashCountedSet<DOMWindow*> DOMWindowSet;
-static DOMWindowRegisteredEventListenerMap& pendingUnloadEventListenerMap()
+static DOMWindowSet& windowsWithUnloadEventListeners()
{
- DEFINE_STATIC_LOCAL(DOMWindowRegisteredEventListenerMap, eventListenerMap, ());
- return eventListenerMap;
+ DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithUnloadEventListeners, ());
+ return windowsWithUnloadEventListeners;
}
-static DOMWindowRegisteredEventListenerMap& pendingBeforeUnloadEventListenerMap()
+static DOMWindowSet& windowsWithBeforeUnloadEventListeners()
{
- DEFINE_STATIC_LOCAL(DOMWindowRegisteredEventListenerMap, eventListenerMap, ());
- return eventListenerMap;
+ DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithBeforeUnloadEventListeners, ());
+ return windowsWithBeforeUnloadEventListeners;
}
-static bool allowsPendingBeforeUnloadListeners(DOMWindow* window)
+static void addUnloadEventListener(DOMWindow* domWindow)
{
- ASSERT_ARG(window, window);
- Frame* frame = window->frame();
- Page* page = frame->page();
- return page && frame == page->mainFrame();
+ DOMWindowSet& set = windowsWithUnloadEventListeners();
+ if (set.isEmpty())
+ disableSuddenTermination();
+ set.add(domWindow);
}
-static void addPendingEventListener(DOMWindowRegisteredEventListenerMap& map, DOMWindow* window, RegisteredEventListener* listener)
+static void removeUnloadEventListener(DOMWindow* domWindow)
{
- ASSERT_ARG(window, window);
- ASSERT_ARG(listener, listener);
-
- if (map.isEmpty())
- disableSuddenTermination();
-
- pair<DOMWindowRegisteredEventListenerMap::iterator, bool> result = map.add(window, 0);
- if (result.second)
- result.first->second = new RegisteredEventListenerVector;
- result.first->second->append(listener);
+ DOMWindowSet& set = windowsWithUnloadEventListeners();
+ DOMWindowSet::iterator it = set.find(domWindow);
+ if (it == set.end())
+ return;
+ set.remove(it);
+ if (set.isEmpty())
+ enableSuddenTermination();
}
-static void removePendingEventListener(DOMWindowRegisteredEventListenerMap& map, DOMWindow* window, RegisteredEventListener* listener)
+static void removeAllUnloadEventListeners(DOMWindow* domWindow)
{
- ASSERT_ARG(window, window);
- ASSERT_ARG(listener, listener);
-
- DOMWindowRegisteredEventListenerMap::iterator it = map.find(window);
- ASSERT(it != map.end());
-
- RegisteredEventListenerVector* listeners = it->second;
- size_t index = listeners->find(listener);
- ASSERT(index != WTF::notFound);
- listeners->remove(index);
-
- if (!listeners->isEmpty())
+ DOMWindowSet& set = windowsWithUnloadEventListeners();
+ DOMWindowSet::iterator it = set.find(domWindow);
+ if (it == set.end())
return;
-
- map.remove(it);
- delete listeners;
-
- if (map.isEmpty())
+ set.removeAll(it);
+ if (set.isEmpty())
enableSuddenTermination();
}
-static void removePendingEventListeners(DOMWindowRegisteredEventListenerMap& map, DOMWindow* window)
+static void addBeforeUnloadEventListener(DOMWindow* domWindow)
{
- ASSERT_ARG(window, window);
+ DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
+ if (set.isEmpty())
+ disableSuddenTermination();
+ set.add(domWindow);
+}
- RegisteredEventListenerVector* listeners = map.take(window);
- if (!listeners)
+static void removeBeforeUnloadEventListener(DOMWindow* domWindow)
+{
+ DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
+ DOMWindowSet::iterator it = set.find(domWindow);
+ if (it == set.end())
return;
+ set.remove(it);
+ if (set.isEmpty())
+ enableSuddenTermination();
+}
- delete listeners;
-
- if (map.isEmpty())
+static void removeAllBeforeUnloadEventListeners(DOMWindow* domWindow)
+{
+ DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
+ DOMWindowSet::iterator it = set.find(domWindow);
+ if (it == set.end())
+ return;
+ set.removeAll(it);
+ if (set.isEmpty())
enableSuddenTermination();
}
+static bool allowsBeforeUnloadListeners(DOMWindow* window)
+{
+ ASSERT_ARG(window, window);
+ Frame* frame = window->frame();
+ if (!frame)
+ return false;
+ Page* page = frame->page();
+ if (!page)
+ return false;
+ return frame == page->mainFrame();
+}
+
bool DOMWindow::dispatchAllPendingBeforeUnloadEvents()
{
- DOMWindowRegisteredEventListenerMap& map = pendingBeforeUnloadEventListenerMap();
- if (map.isEmpty())
+ DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
+ if (set.isEmpty())
return true;
static bool alreadyDispatched = false;
@@ -207,20 +210,21 @@ bool DOMWindow::dispatchAllPendingBeforeUnloadEvents()
return true;
Vector<RefPtr<DOMWindow> > windows;
- DOMWindowRegisteredEventListenerMap::iterator mapEnd = map.end();
- for (DOMWindowRegisteredEventListenerMap::iterator it = map.begin(); it != mapEnd; ++it)
+ DOMWindowSet::iterator end = set.end();
+ for (DOMWindowSet::iterator it = set.begin(); it != end; ++it)
windows.append(it->first);
size_t size = windows.size();
for (size_t i = 0; i < size; ++i) {
DOMWindow* window = windows[i].get();
- RegisteredEventListenerVector* listeners = map.get(window);
- if (!listeners)
+ if (!set.contains(window))
continue;
- RegisteredEventListenerVector listenersCopy = *listeners;
Frame* frame = window->frame();
- if (!frame->shouldClose(&listenersCopy))
+ if (!frame)
+ continue;
+
+ if (!frame->shouldClose())
return false;
}
@@ -233,14 +237,13 @@ bool DOMWindow::dispatchAllPendingBeforeUnloadEvents()
unsigned DOMWindow::pendingUnloadEventListeners() const
{
- RegisteredEventListenerVector* listeners = pendingUnloadEventListenerMap().get(const_cast<DOMWindow*>(this));
- return listeners ? listeners->size() : 0;
+ return windowsWithUnloadEventListeners().count(const_cast<DOMWindow*>(this));
}
void DOMWindow::dispatchAllPendingUnloadEvents()
{
- DOMWindowRegisteredEventListenerMap& map = pendingUnloadEventListenerMap();
- if (map.isEmpty())
+ DOMWindowSet& set = windowsWithUnloadEventListeners();
+ if (set.isEmpty())
return;
static bool alreadyDispatched = false;
@@ -249,18 +252,18 @@ void DOMWindow::dispatchAllPendingUnloadEvents()
return;
Vector<RefPtr<DOMWindow> > windows;
- DOMWindowRegisteredEventListenerMap::iterator mapEnd = map.end();
- for (DOMWindowRegisteredEventListenerMap::iterator it = map.begin(); it != mapEnd; ++it)
+ DOMWindowSet::iterator end = set.end();
+ for (DOMWindowSet::iterator it = set.begin(); it != end; ++it)
windows.append(it->first);
size_t size = windows.size();
for (size_t i = 0; i < size; ++i) {
DOMWindow* window = windows[i].get();
- RegisteredEventListenerVector* listeners = map.get(window);
- if (!listeners)
+ if (!set.contains(window))
continue;
- RegisteredEventListenerVector listenersCopy = *listeners;
- window->dispatchUnloadEvent(&listenersCopy);
+
+ window->dispatchEvent(PageTransitionEvent::create(EventNames().pagehideEvent, false), window->document());
+ window->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), window->document());
}
enableSuddenTermination();
@@ -374,8 +377,8 @@ DOMWindow::~DOMWindow()
if (m_frame)
m_frame->clearFormerDOMWindow(this);
- removePendingEventListeners(pendingUnloadEventListenerMap(), this);
- removePendingEventListeners(pendingBeforeUnloadEventListenerMap(), this);
+ removeAllUnloadEventListeners(this);
+ removeAllBeforeUnloadEventListeners(this);
}
ScriptExecutionContext* DOMWindow::scriptExecutionContext() const
@@ -454,8 +457,22 @@ void DOMWindow::clear()
m_applicationCache->disconnectFrame();
m_applicationCache = 0;
#endif
+
+#if ENABLE(NOTIFICATIONS)
+ m_notifications = 0;
+#endif
}
+#if ENABLE(ORIENTATION_EVENTS)
+int DOMWindow::orientation() const
+{
+ if (!m_frame)
+ return 0;
+
+ return m_frame->orientation();
+}
+#endif
+
Screen* DOMWindow::screen() const
{
if (!m_screen)
@@ -522,7 +539,7 @@ Console* DOMWindow::console() const
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
DOMApplicationCache* DOMWindow::applicationCache() const
{
- if (!m_applicationCache && m_frame && m_frame->settings() && m_frame->settings()->offlineWebApplicationCacheEnabled())
+ if (!m_applicationCache)
m_applicationCache = DOMApplicationCache::create(m_frame);
return m_applicationCache.get();
}
@@ -560,7 +577,9 @@ Storage* DOMWindow::sessionStorage() const
return 0;
RefPtr<StorageArea> storageArea = page->sessionStorage()->storageArea(document->securityOrigin());
+#if ENABLE(INSPECTOR)
page->inspectorController()->didUseDOMStorage(storageArea.get(), false, m_frame);
+#endif
m_sessionStorage = Storage::create(m_frame, storageArea.release());
return m_sessionStorage.get();
@@ -582,18 +601,50 @@ Storage* DOMWindow::localStorage() const
if (!page->settings()->localStorageEnabled())
return 0;
- StorageNamespace* localStorage = page->group().localStorage();
- RefPtr<StorageArea> storageArea = localStorage ? localStorage->storageArea(document->securityOrigin()) : 0;
- if (storageArea) {
- page->inspectorController()->didUseDOMStorage(storageArea.get(), true, m_frame);
- m_localStorage = Storage::create(m_frame, storageArea.release());
- }
+ RefPtr<StorageArea> storageArea = page->group().localStorage()->storageArea(document->securityOrigin());
+#if ENABLE(INSPECTOR)
+ page->inspectorController()->didUseDOMStorage(storageArea.get(), true, m_frame);
+#endif
+ m_localStorage = Storage::create(m_frame, storageArea.release());
return m_localStorage.get();
}
#endif
-void DOMWindow::postMessage(const String& message, MessagePort* messagePort, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec)
+#if ENABLE(NOTIFICATIONS)
+NotificationCenter* DOMWindow::webkitNotifications() const
+{
+ if (m_notifications)
+ return m_notifications.get();
+
+ Document* document = this->document();
+ if (!document)
+ return 0;
+
+ Page* page = document->page();
+ if (!page)
+ return 0;
+
+ if (!page->settings()->experimentalNotificationsEnabled())
+ return 0;
+
+ NotificationPresenter* provider = page->chrome()->notificationPresenter();
+ if (provider)
+ m_notifications = NotificationCenter::create(document, provider);
+
+ return m_notifications.get();
+}
+#endif
+
+void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort* port, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec)
+{
+ MessagePortArray ports;
+ if (port)
+ ports.append(port);
+ postMessage(message, &ports, targetOrigin, source, ec);
+}
+
+void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec)
{
if (!m_frame)
return;
@@ -609,9 +660,7 @@ void DOMWindow::postMessage(const String& message, MessagePort* messagePort, con
}
}
- OwnPtr<MessagePortChannel> channel;
- if (messagePort)
- channel = messagePort->disentangle(ec);
+ OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, ec);
if (ec)
return;
@@ -623,7 +672,7 @@ void DOMWindow::postMessage(const String& message, MessagePort* messagePort, con
String sourceOrigin = sourceDocument->securityOrigin()->toString();
// Schedule the message.
- PostMessageTimer* timer = new PostMessageTimer(this, message, sourceOrigin, source, channel.release(), target.get());
+ PostMessageTimer* timer = new PostMessageTimer(this, message, sourceOrigin, source, channels.release(), target.get());
timer->startOneShot(0);
}
@@ -644,8 +693,7 @@ void DOMWindow::postMessageTimerFired(PostMessageTimer* t)
}
}
- ExceptionCode ec = 0;
- dispatchEvent(timer->event(document()), ec);
+ dispatchEvent(timer->event(document()));
}
DOMSelection* DOMWindow::getSelection()
@@ -692,12 +740,9 @@ void DOMWindow::close()
return;
Settings* settings = m_frame->settings();
- bool allowScriptsToCloseWindows =
- settings && settings->allowScriptsToCloseWindows();
+ bool allowScriptsToCloseWindows = settings && settings->allowScriptsToCloseWindows();
- if (m_frame->loader()->openedByDOM()
- || m_frame->loader()->getHistoryLength() <= 1
- || allowScriptsToCloseWindows)
+ if (page->openedByDOM() || page->getHistoryLength() <= 1 || allowScriptsToCloseWindows)
m_frame->scheduleClose();
}
@@ -1214,104 +1259,38 @@ void DOMWindow::clearInterval(int timeoutId)
DOMTimer::removeById(scriptExecutionContext(), timeoutId);
}
-void DOMWindow::handleEvent(Event* event, bool useCapture, RegisteredEventListenerVector* alternateListeners)
+bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
{
- RegisteredEventListenerVector& listeners = (alternateListeners ? *alternateListeners : m_eventListeners);
- if (listeners.isEmpty())
- return;
-
- // If any HTML event listeners are registered on the window, dispatch them here.
- RegisteredEventListenerVector listenersCopy = listeners;
- size_t size = listenersCopy.size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *listenersCopy[i];
- if (r.eventType() == event->type() && r.useCapture() == useCapture && !r.removed())
- r.listener()->handleEvent(event, true);
- }
-}
+ if (!EventTarget::addEventListener(eventType, listener, useCapture))
+ return false;
-void DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-{
- // Remove existing identical listener set with identical arguments.
- // The DOM 2 spec says that "duplicate instances are discarded" in this case.
- removeEventListener(eventType, listener.get(), useCapture);
if (Document* document = this->document())
document->addListenerTypeIfNeeded(eventType);
- RefPtr<RegisteredEventListener> registeredListener = RegisteredEventListener::create(eventType, listener, useCapture);
- m_eventListeners.append(registeredListener);
-
if (eventType == eventNames().unloadEvent)
- addPendingEventListener(pendingUnloadEventListenerMap(), this, registeredListener.get());
- else if (eventType == eventNames().beforeunloadEvent && allowsPendingBeforeUnloadListeners(this))
- addPendingEventListener(pendingBeforeUnloadEventListenerMap(), this, registeredListener.get());
-}
+ addUnloadEventListener(this);
+ else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this))
+ addBeforeUnloadEventListener(this);
-void DOMWindow::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
-{
- size_t size = m_eventListeners.size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *m_eventListeners[i];
- if (r.eventType() == eventType && r.listener() == listener && r.useCapture() == useCapture) {
- if (eventType == eventNames().unloadEvent)
- removePendingEventListener(pendingUnloadEventListenerMap(), this, &r);
- else if (eventType == eventNames().beforeunloadEvent && allowsPendingBeforeUnloadListeners(this))
- removePendingEventListener(pendingBeforeUnloadEventListenerMap(), this, &r);
- r.setRemoved(true);
- m_eventListeners.remove(i);
- return;
- }
- }
-}
-
-bool DOMWindow::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec)
-{
- ASSERT(!eventDispatchForbidden());
-
- RefPtr<Event> event = e;
- if (!event || event->type().isEmpty()) {
- ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
- return true;
- }
-
- RefPtr<DOMWindow> protect(this);
-
- event->setTarget(this);
- event->setCurrentTarget(this);
-
- handleEvent(event.get(), true);
- handleEvent(event.get(), false);
-
- return !event->defaultPrevented();
-}
-
-void DOMWindow::dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable)
-{
- ASSERT(!eventDispatchForbidden());
- ExceptionCode ec = 0;
- dispatchEvent(Event::create(eventType, canBubble, cancelable), ec);
+ return true;
}
-// This function accommodates the Firefox quirk of dispatching the load, unload and
-// beforeunload events on the window, but setting event.target to be the Document.
-inline void DOMWindow::dispatchEventWithDocumentAsTarget(PassRefPtr<Event> e, RegisteredEventListenerVector* alternateEventListeners)
+bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
{
- ASSERT(!eventDispatchForbidden());
-
- RefPtr<Event> event = e;
- RefPtr<DOMWindow> protect(this);
- RefPtr<Document> document = this->document();
+ if (!EventTarget::removeEventListener(eventType, listener, useCapture))
+ return false;
- event->setTarget(document);
- event->setCurrentTarget(this);
+ if (eventType == eventNames().unloadEvent)
+ removeUnloadEventListener(this);
+ else if (eventType == eventNames().beforeunloadEvent && allowsBeforeUnloadListeners(this))
+ removeBeforeUnloadEventListener(this);
- handleEvent(event.get(), true, alternateEventListeners);
- handleEvent(event.get(), false, alternateEventListeners);
+ return true;
}
void DOMWindow::dispatchLoadEvent()
{
- dispatchEventWithDocumentAsTarget(Event::create(eventNames().loadEvent, false, false));
+ dispatchEvent(Event::create(eventNames().loadEvent, false, false), document());
// For load events, send a separate load event to the enclosing frame only.
// This is a DOM extension and is independent of bubbling/capturing rules of
@@ -1322,704 +1301,54 @@ void DOMWindow::dispatchLoadEvent()
ownerEvent->setTarget(ownerElement);
ownerElement->dispatchGenericEvent(ownerEvent.release());
}
-}
-
-void DOMWindow::dispatchUnloadEvent(RegisteredEventListenerVector* alternateEventListeners)
-{
- dispatchEventWithDocumentAsTarget(Event::create(eventNames().unloadEvent, false, false), alternateEventListeners);
-}
-PassRefPtr<BeforeUnloadEvent> DOMWindow::dispatchBeforeUnloadEvent(RegisteredEventListenerVector* alternateEventListeners)
-{
- RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
- dispatchEventWithDocumentAsTarget(beforeUnloadEvent.get(), alternateEventListeners);
- return beforeUnloadEvent.release();
-}
-
-void DOMWindow::removeAllEventListeners()
-{
- size_t size = m_eventListeners.size();
- for (size_t i = 0; i < size; ++i)
- m_eventListeners[i]->setRemoved(true);
- m_eventListeners.clear();
-
- removePendingEventListeners(pendingUnloadEventListenerMap(), this);
- removePendingEventListeners(pendingBeforeUnloadEventListenerMap(), this);
-}
-
-bool DOMWindow::hasEventListener(const AtomicString& eventType)
-{
- size_t size = m_eventListeners.size();
- for (size_t i = 0; i < size; ++i) {
- if (m_eventListeners[i]->eventType() == eventType)
- return true;
- }
- return false;
-}
-
-void DOMWindow::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
-{
- clearAttributeEventListener(eventType);
- if (listener)
- addEventListener(eventType, listener, false);
-}
-
-void DOMWindow::clearAttributeEventListener(const AtomicString& eventType)
-{
- size_t size = m_eventListeners.size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *m_eventListeners[i];
- if (r.eventType() == eventType && r.listener()->isAttribute()) {
- if (eventType == eventNames().unloadEvent)
- removePendingEventListener(pendingUnloadEventListenerMap(), this, &r);
- else if (eventType == eventNames().beforeunloadEvent && allowsPendingBeforeUnloadListeners(this))
- removePendingEventListener(pendingBeforeUnloadEventListenerMap(), this, &r);
- r.setRemoved(true);
- m_eventListeners.remove(i);
- return;
- }
- }
-}
-
-EventListener* DOMWindow::getAttributeEventListener(const AtomicString& eventType) const
-{
- size_t size = m_eventListeners.size();
- for (size_t i = 0; i < size; ++i) {
- RegisteredEventListener& r = *m_eventListeners[i];
- if (r.eventType() == eventType && r.listener()->isAttribute())
- return r.listener();
- }
- return 0;
-}
-
-EventListener* DOMWindow::onabort() const
-{
- return getAttributeEventListener(eventNames().abortEvent);
-}
-
-void DOMWindow::setOnabort(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().abortEvent, eventListener);
-}
-
-EventListener* DOMWindow::onblur() const
-{
- return getAttributeEventListener(eventNames().blurEvent);
-}
-
-void DOMWindow::setOnblur(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().blurEvent, eventListener);
-}
-
-EventListener* DOMWindow::onchange() const
-{
- return getAttributeEventListener(eventNames().changeEvent);
-}
-
-void DOMWindow::setOnchange(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().changeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onclick() const
-{
- return getAttributeEventListener(eventNames().clickEvent);
-}
-
-void DOMWindow::setOnclick(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().clickEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondblclick() const
-{
- return getAttributeEventListener(eventNames().dblclickEvent);
-}
-
-void DOMWindow::setOndblclick(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dblclickEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondrag() const
-{
- return getAttributeEventListener(eventNames().dragEvent);
-}
-
-void DOMWindow::setOndrag(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragend() const
-{
- return getAttributeEventListener(eventNames().dragendEvent);
-}
-
-void DOMWindow::setOndragend(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragendEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragenter() const
-{
- return getAttributeEventListener(eventNames().dragenterEvent);
-}
-
-void DOMWindow::setOndragenter(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragenterEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragleave() const
-{
- return getAttributeEventListener(eventNames().dragleaveEvent);
-}
-
-void DOMWindow::setOndragleave(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragleaveEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragover() const
-{
- return getAttributeEventListener(eventNames().dragoverEvent);
-}
-
-void DOMWindow::setOndragover(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragoverEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondragstart() const
-{
- return getAttributeEventListener(eventNames().dragstartEvent);
-}
-
-void DOMWindow::setOndragstart(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dragstartEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondrop() const
-{
- return getAttributeEventListener(eventNames().dropEvent);
-}
-
-void DOMWindow::setOndrop(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().dropEvent, eventListener);
-}
-
-EventListener* DOMWindow::onerror() const
-{
- return getAttributeEventListener(eventNames().errorEvent);
-}
-
-void DOMWindow::setOnerror(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().errorEvent, eventListener);
-}
-
-EventListener* DOMWindow::onfocus() const
-{
- return getAttributeEventListener(eventNames().focusEvent);
-}
-
-void DOMWindow::setOnfocus(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().focusEvent, eventListener);
-}
-
-EventListener* DOMWindow::onkeydown() const
-{
- return getAttributeEventListener(eventNames().keydownEvent);
-}
-
-void DOMWindow::setOnkeydown(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().keydownEvent, eventListener);
-}
-
-EventListener* DOMWindow::onkeypress() const
-{
- return getAttributeEventListener(eventNames().keypressEvent);
-}
-
-void DOMWindow::setOnkeypress(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().keypressEvent, eventListener);
-}
-
-EventListener* DOMWindow::onkeyup() const
-{
- return getAttributeEventListener(eventNames().keyupEvent);
-}
-
-void DOMWindow::setOnkeyup(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().keyupEvent, eventListener);
-}
-
-EventListener* DOMWindow::onload() const
-{
- return getAttributeEventListener(eventNames().loadEvent);
-}
-
-void DOMWindow::setOnload(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().loadEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmousedown() const
-{
- return getAttributeEventListener(eventNames().mousedownEvent);
-}
-
-void DOMWindow::setOnmousedown(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mousedownEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmousemove() const
-{
- return getAttributeEventListener(eventNames().mousemoveEvent);
-}
-
-void DOMWindow::setOnmousemove(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mousemoveEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmouseout() const
-{
- return getAttributeEventListener(eventNames().mouseoutEvent);
-}
-
-void DOMWindow::setOnmouseout(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mouseoutEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmouseover() const
-{
- return getAttributeEventListener(eventNames().mouseoverEvent);
-}
-
-void DOMWindow::setOnmouseover(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mouseoverEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmouseup() const
-{
- return getAttributeEventListener(eventNames().mouseupEvent);
-}
-
-void DOMWindow::setOnmouseup(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mouseupEvent, eventListener);
-}
-
-EventListener* DOMWindow::onmousewheel() const
-{
- return getAttributeEventListener(eventNames().mousewheelEvent);
-}
-
-void DOMWindow::setOnmousewheel(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().mousewheelEvent, eventListener);
-}
-
-EventListener* DOMWindow::onoffline() const
-{
- return getAttributeEventListener(eventNames().offlineEvent);
-}
-
-void DOMWindow::setOnoffline(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().offlineEvent, eventListener);
-}
-
-EventListener* DOMWindow::ononline() const
-{
- return getAttributeEventListener(eventNames().onlineEvent);
-}
-
-void DOMWindow::setOnonline(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().onlineEvent, eventListener);
-}
-
-EventListener* DOMWindow::onreset() const
-{
- return getAttributeEventListener(eventNames().resetEvent);
-}
-
-void DOMWindow::setOnreset(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().resetEvent, eventListener);
-}
-
-EventListener* DOMWindow::onresize() const
-{
- return getAttributeEventListener(eventNames().resizeEvent);
-}
-
-void DOMWindow::setOnresize(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().resizeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onscroll() const
-{
- return getAttributeEventListener(eventNames().scrollEvent);
-}
-
-void DOMWindow::setOnscroll(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().scrollEvent, eventListener);
-}
-
-EventListener* DOMWindow::onsearch() const
-{
- return getAttributeEventListener(eventNames().searchEvent);
-}
-
-void DOMWindow::setOnsearch(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().searchEvent, eventListener);
-}
-
-EventListener* DOMWindow::onselect() const
-{
- return getAttributeEventListener(eventNames().selectEvent);
-}
-
-void DOMWindow::setOnselect(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().selectEvent, eventListener);
-}
-
-EventListener* DOMWindow::onstorage() const
-{
- return getAttributeEventListener(eventNames().storageEvent);
-}
-
-void DOMWindow::setOnstorage(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().storageEvent, eventListener);
-}
-
-EventListener* DOMWindow::onsubmit() const
-{
- return getAttributeEventListener(eventNames().submitEvent);
-}
-
-void DOMWindow::setOnsubmit(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().submitEvent, eventListener);
-}
-
-EventListener* DOMWindow::onunload() const
-{
- return getAttributeEventListener(eventNames().unloadEvent);
-}
-
-void DOMWindow::setOnunload(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().unloadEvent, eventListener);
-}
-
-EventListener* DOMWindow::onbeforeunload() const
-{
- return getAttributeEventListener(eventNames().beforeunloadEvent);
-}
-
-void DOMWindow::setOnbeforeunload(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().beforeunloadEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwebkitanimationstart() const
-{
- return getAttributeEventListener(eventNames().webkitAnimationStartEvent);
-}
-
-void DOMWindow::setOnwebkitanimationstart(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().webkitAnimationStartEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwebkitanimationiteration() const
-{
- return getAttributeEventListener(eventNames().webkitAnimationIterationEvent);
-}
-
-void DOMWindow::setOnwebkitanimationiteration(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().webkitAnimationIterationEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwebkitanimationend() const
-{
- return getAttributeEventListener(eventNames().webkitAnimationEndEvent);
-}
-
-void DOMWindow::setOnwebkitanimationend(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().webkitAnimationEndEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwebkittransitionend() const
-{
- return getAttributeEventListener(eventNames().webkitTransitionEndEvent);
-}
-
-void DOMWindow::setOnwebkittransitionend(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().webkitTransitionEndEvent, eventListener);
-}
-
-EventListener* DOMWindow::oncanplay() const
-{
- return getAttributeEventListener(eventNames().canplayEvent);
-}
-
-void DOMWindow::setOncanplay(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().canplayEvent, eventListener);
-}
-
-EventListener* DOMWindow::oncanplaythrough() const
-{
- return getAttributeEventListener(eventNames().canplaythroughEvent);
-}
-
-void DOMWindow::setOncanplaythrough(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().canplaythroughEvent, eventListener);
-}
-
-EventListener* DOMWindow::ondurationchange() const
-{
- return getAttributeEventListener(eventNames().durationchangeEvent);
-}
-
-void DOMWindow::setOndurationchange(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().durationchangeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onemptied() const
-{
- return getAttributeEventListener(eventNames().emptiedEvent);
-}
-
-void DOMWindow::setOnemptied(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().emptiedEvent, eventListener);
-}
-
-EventListener* DOMWindow::onended() const
-{
- return getAttributeEventListener(eventNames().endedEvent);
-}
-
-void DOMWindow::setOnended(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().endedEvent, eventListener);
-}
-
-EventListener* DOMWindow::onloadeddata() const
-{
- return getAttributeEventListener(eventNames().loadeddataEvent);
-}
-
-void DOMWindow::setOnloadeddata(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().loadeddataEvent, eventListener);
-}
-
-EventListener* DOMWindow::onloadedmetadata() const
-{
- return getAttributeEventListener(eventNames().loadedmetadataEvent);
-}
-
-void DOMWindow::setOnloadedmetadata(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().loadedmetadataEvent, eventListener);
-}
-
-EventListener* DOMWindow::onpause() const
-{
- return getAttributeEventListener(eventNames().pauseEvent);
-}
-
-void DOMWindow::setOnpause(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().pauseEvent, eventListener);
-}
-
-EventListener* DOMWindow::onplay() const
-{
- return getAttributeEventListener(eventNames().playEvent);
-}
-
-void DOMWindow::setOnplay(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().playEvent, eventListener);
-}
-
-EventListener* DOMWindow::onplaying() const
-{
- return getAttributeEventListener(eventNames().playingEvent);
-}
-
-void DOMWindow::setOnplaying(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().playingEvent, eventListener);
-}
-
-EventListener* DOMWindow::onratechange() const
-{
- return getAttributeEventListener(eventNames().ratechangeEvent);
-}
-
-void DOMWindow::setOnratechange(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().ratechangeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onseeked() const
-{
- return getAttributeEventListener(eventNames().seekedEvent);
-}
-
-void DOMWindow::setOnseeked(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().seekedEvent, eventListener);
-}
-
-EventListener* DOMWindow::onseeking() const
-{
- return getAttributeEventListener(eventNames().seekingEvent);
-}
-
-void DOMWindow::setOnseeking(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().seekingEvent, eventListener);
-}
-
-EventListener* DOMWindow::ontimeupdate() const
-{
- return getAttributeEventListener(eventNames().timeupdateEvent);
-}
-
-void DOMWindow::setOntimeupdate(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().timeupdateEvent, eventListener);
-}
-
-EventListener* DOMWindow::onvolumechange() const
-{
- return getAttributeEventListener(eventNames().volumechangeEvent);
-}
-
-void DOMWindow::setOnvolumechange(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().volumechangeEvent, eventListener);
-}
-
-EventListener* DOMWindow::onwaiting() const
-{
- return getAttributeEventListener(eventNames().waitingEvent);
-}
-
-void DOMWindow::setOnwaiting(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().waitingEvent, eventListener);
-}
-
-EventListener* DOMWindow::onloadstart() const
-{
- return getAttributeEventListener(eventNames().loadstartEvent);
-}
-
-void DOMWindow::setOnloadstart(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().loadstartEvent, eventListener);
-}
-
-EventListener* DOMWindow::onprogress() const
-{
- return getAttributeEventListener(eventNames().progressEvent);
-}
-
-void DOMWindow::setOnprogress(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().progressEvent, eventListener);
-}
-
-EventListener* DOMWindow::onstalled() const
-{
- return getAttributeEventListener(eventNames().stalledEvent);
-}
-
-void DOMWindow::setOnstalled(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().stalledEvent, eventListener);
-}
+#if ENABLE(INSPECTOR)
+ if (!frame() || !frame()->page())
+ return;
-EventListener* DOMWindow::onsuspend() const
-{
- return getAttributeEventListener(eventNames().suspendEvent);
+ if (InspectorController* controller = frame()->page()->inspectorController())
+ controller->mainResourceFiredLoadEvent(frame()->loader()->documentLoader(), url());
+#endif
}
-void DOMWindow::setOnsuspend(PassRefPtr<EventListener> eventListener)
+bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget)
{
- setAttributeEventListener(eventNames().suspendEvent, eventListener);
-}
+ RefPtr<EventTarget> protect = this;
+ RefPtr<Event> event = prpEvent;
-EventListener* DOMWindow::oninput() const
-{
- return getAttributeEventListener(eventNames().inputEvent);
-}
+ event->setTarget(prpTarget ? prpTarget : this);
+ event->setCurrentTarget(this);
+ event->setEventPhase(Event::AT_TARGET);
-void DOMWindow::setOninput(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().inputEvent, eventListener);
+ return fireEventListeners(event.get());
}
-EventListener* DOMWindow::onmessage() const
+void DOMWindow::removeAllEventListeners()
{
- return getAttributeEventListener(eventNames().messageEvent);
-}
+ EventTarget::removeAllEventListeners();
-void DOMWindow::setOnmessage(PassRefPtr<EventListener> eventListener)
-{
- setAttributeEventListener(eventNames().messageEvent, eventListener);
+ removeAllUnloadEventListeners(this);
+ removeAllBeforeUnloadEventListeners(this);
}
-EventListener* DOMWindow::oncontextmenu() const
+void DOMWindow::captureEvents()
{
- return getAttributeEventListener(eventNames().contextmenuEvent);
+ // Not implemented.
}
-void DOMWindow::setOncontextmenu(PassRefPtr<EventListener> eventListener)
+void DOMWindow::releaseEvents()
{
- setAttributeEventListener(eventNames().contextmenuEvent, eventListener);
+ // Not implemented.
}
-void DOMWindow::captureEvents()
+EventTargetData* DOMWindow::eventTargetData()
{
- // Not implemented.
+ return &m_eventTargetData;
}
-void DOMWindow::releaseEvents()
+EventTargetData* DOMWindow::ensureEventTargetData()
{
- // Not implemented.
+ return &m_eventTargetData;
}
#if ENABLE(TOUCH_EVENTS) // Android
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index 12caf7e..3e3cbb4 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -28,6 +28,7 @@
#include "EventTarget.h"
#include "KURL.h"
+#include "MessagePort.h"
#include "PlatformString.h"
#include "RegisteredEventListener.h"
#include "SecurityOrigin.h"
@@ -53,11 +54,12 @@ namespace WebCore {
class History;
class Location;
class Media;
- class MessagePort;
class Navigator;
class Node;
+ class NotificationCenter;
class PostMessageTimer;
class ScheduledAction;
+ class SerializedScriptValue;
class Screen;
class WebKitPoint;
@@ -84,6 +86,13 @@ namespace WebCore {
void clear();
+#if ENABLE(ORIENTATION_EVENTS)
+ // This is the interface orientation in degrees. Some examples are:
+ // 0 is straight up; -90 is when the device is rotated 90 clockwise;
+ // 90 is when rotated counter clockwise.
+ int orientation() const;
+#endif
+
void setSecurityOrigin(SecurityOrigin* securityOrigin) { m_securityOrigin = securityOrigin; }
SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); }
@@ -205,7 +214,13 @@ namespace WebCore {
DOMApplicationCache* applicationCache() const;
#endif
- void postMessage(const String& message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&);
+#if ENABLE(NOTIFICATIONS)
+ NotificationCenter* webkitNotifications() 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&);
void postMessageTimerFired(PostMessageTimer*);
void scrollBy(int x, int y) const;
@@ -226,17 +241,20 @@ namespace WebCore {
// Events
// EventTarget API
- virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
- virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&);
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+ virtual void removeAllEventListeners();
- void handleEvent(Event*, bool useCapture, RegisteredEventListenerVector* = 0);
-
- void dispatchEvent(const AtomicString& eventType, bool canBubble, bool cancelable);
+ using EventTarget::dispatchEvent;
+ bool dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget);
void dispatchLoadEvent();
+<<<<<<< HEAD:WebCore/page/DOMWindow.h
void dispatchUnloadEvent(RegisteredEventListenerVector* = 0);
PassRefPtr<BeforeUnloadEvent> dispatchBeforeUnloadEvent(RegisteredEventListenerVector* = 0);
+=======
+>>>>>>> webkit.org at 49305:WebCore/page/DOMWindow.h
+<<<<<<< HEAD:WebCore/page/DOMWindow.h
// Used for legacy "onEvent" property APIs.
void setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
void clearAttributeEventListener(const AtomicString& eventType);
@@ -333,7 +351,74 @@ namespace WebCore {
void setOntouchmove(PassRefPtr<EventListener>);
EventListener* ontouchcancel() const;
void setOntouchcancel(PassRefPtr<EventListener>);
+=======
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(abort);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(blur);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(click);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(drag);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragenter);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragleave);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(drop);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(focus);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(hashchange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(load);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseover);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseup);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(mousewheel);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(offline);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(online);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pagehide);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pageshow);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(reset);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(resize);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(select);
+ 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(timeupdate);
+ 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);
+#if ENABLE(ORIENTATION_EVENTS)
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
+>>>>>>> webkit.org at 49305:WebCore/page/DOMWindow.h
#endif
+<<<<<<< HEAD:WebCore/page/DOMWindow.h
EventListener* oncanplay() const;
void setOncanplay(PassRefPtr<EventListener>);
@@ -381,6 +466,13 @@ namespace WebCore {
void setOnmessage(PassRefPtr<EventListener>);
EventListener* oncontextmenu() const;
void setOncontextmenu(PassRefPtr<EventListener>);
+=======
+
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, webkitAnimationStart);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration, webkitAnimationIteration);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd);
+>>>>>>> webkit.org at 49305:WebCore/page/DOMWindow.h
void captureEvents();
void releaseEvents();
@@ -415,8 +507,8 @@ namespace WebCore {
virtual void refEventTarget() { ref(); }
virtual void derefEventTarget() { deref(); }
-
- void dispatchEventWithDocumentAsTarget(PassRefPtr<Event>, RegisteredEventListenerVector* = 0);
+ virtual EventTargetData* eventTargetData();
+ virtual EventTargetData* ensureEventTargetData();
RefPtr<SecurityOrigin> m_securityOrigin;
KURL m_url;
@@ -441,8 +533,11 @@ namespace WebCore {
#if ENABLE(OFFLINE_WEB_APPLICATIONS)
mutable RefPtr<DOMApplicationCache> m_applicationCache;
#endif
+#if ENABLE(NOTIFICATIONS)
+ mutable RefPtr<NotificationCenter> m_notifications;
+#endif
- RegisteredEventListenerVector m_eventListeners;
+ EventTargetData m_eventTargetData;
};
} // namespace WebCore
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index aba92f0..c8eafe6 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -39,6 +39,7 @@ module window {
CustomNativeConverter,
CustomPutFunction,
ExtendsDOMGlobalObject,
+ EventTarget,
GenerateNativeConverter,
LegacyParent=JSDOMWindowBase
] DOMWindow {
@@ -55,7 +56,7 @@ module window {
attribute [Replaceable] Navigator clientInformation;
attribute [DoNotCheckDomainSecurity, JSCCustom, V8CustomSetter, V8DisallowShadowing] Location location;
- attribute [Replaceable, CustomGetter] Event event;
+ attribute [Replaceable, CustomGetter, V8CustomSetter] Event event;
readonly attribute [Custom] Crypto crypto;
@@ -74,7 +75,7 @@ module window {
in DOMString name,
in [Optional] DOMString options);
- [Custom] DOMObject showModalDialog(in DOMString url,
+ [Custom] DOMObject showModalDialog(in DOMString url,
in [Optional] DOMObject dialogArgs,
in [Optional] DOMString featureArgs);
@@ -169,12 +170,28 @@ module window {
readonly attribute Storage sessionStorage;
readonly attribute Storage localStorage;
#endif
+#if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS
+ readonly attribute NotificationCenter webkitNotifications;
+#endif
+
+#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
+ // This is the interface orientation in degrees. Some examples are:
+ // 0 is straight up; -90 is when the device is rotated 90 clockwise;
+ // 90 is when rotated counter clockwise.
+ readonly attribute long orientation;
+#endif
attribute [Replaceable] Console console;
// cross-document messaging
- [DoNotCheckDomainSecurity, Custom] void postMessage(in DOMString message, in [Optional] MessagePort messagePort, in DOMString targetOrigin)
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ [DoNotCheckDomainSecurity, Custom] void postMessage(in SerializedScriptValue message, in [Optional] Array messagePorts, in DOMString targetOrigin)
raises(DOMException);
+#else
+ // There's no good way to expose an array via the ObjC bindings, so for now just allow passing in a single port.
+ [DoNotCheckDomainSecurity, Custom] void postMessage(in SerializedScriptValue message, in [Optional] MessagePort messagePort, in DOMString targetOrigin)
+ raises(DOMException);
+#endif
// Timers
[Custom] long setTimeout(in TimeoutHandler handler, in long timeout);
@@ -221,7 +238,9 @@ module window {
attribute EventListener onended;
attribute EventListener onerror;
attribute EventListener onfocus;
+ attribute EventListener onhashchange;
attribute EventListener oninput;
+ attribute EventListener oninvalid;
attribute EventListener onkeydown;
attribute EventListener onkeypress;
attribute EventListener onkeyup;
@@ -238,6 +257,8 @@ module window {
attribute EventListener onmousewheel;
attribute EventListener onoffline;
attribute EventListener ononline;
+ attribute EventListener onpagehide;
+ attribute EventListener onpageshow;
attribute EventListener onpause;
attribute EventListener onplay;
attribute EventListener onplaying;
@@ -262,8 +283,6 @@ module window {
// attribute EventListener onbeforeprint;
// attribute EventListener onformchange;
// attribute EventListener onforminput;
- // attribute EventListener onhashchange;
- // attribute EventListener oninvalid;
// attribute EventListener onpopstate;
// attribute EventListener onreadystatechange;
// attribute EventListener onredo;
@@ -277,6 +296,9 @@ module window {
attribute EventListener onwebkitanimationiteration;
attribute EventListener onwebkitanimationstart;
attribute EventListener onwebkittransitionend;
+#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
+ attribute EventListener onorientationchange;
+#endif
// EventTarget interface
[Custom] void addEventListener(in DOMString type,
@@ -419,13 +441,25 @@ module window {
attribute [CustomGetter] HTMLOptionElementConstructor Option; // Usable with new operator
attribute CanvasRenderingContext2DConstructor CanvasRenderingContext2D;
+ attribute [Conditional=3D_CANVAS] CanvasRenderingContext3DConstructor CanvasRenderingContext3D;
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 EventConstructor Event;
+ attribute BeforeLoadEventConstructor BeforeLoadEvent;
attribute KeyboardEventConstructor KeyboardEvent;
attribute MouseEventConstructor MouseEvent;
attribute MutationEventConstructor MutationEvent;
attribute OverflowEventConstructor OverflowEvent;
+ attribute PageTransitionEventConstructor PageTransitionEvent;
attribute ProgressEventConstructor ProgressEvent;
attribute TextEventConstructor TextEvent;
attribute UIEventConstructor UIEvent;
@@ -454,6 +488,10 @@ module window {
attribute RangeConstructor Range;
attribute RangeExceptionConstructor RangeException;
+#if ENABLE_EVENTSOURCE
+ attribute [JSCCustomGetter] EventSourceConstructor EventSource; // Usable with new the operator
+#endif
+
// Mozilla has a separate XMLDocument object for XML documents.
// We just use Document for this.
attribute DocumentConstructor XMLDocument;
@@ -465,9 +503,7 @@ module window {
attribute XMLHttpRequestUploadConstructor XMLHttpRequestUpload;
attribute XMLHttpRequestExceptionConstructor XMLHttpRequestException;
-#if defined(ENABLE_XSLT) && ENABLE_XSLT
- attribute [JSCCustomGetter] XSLTProcessorConstructor XSLTProcessor; // Usable with the new operator
-#endif
+ attribute [JSCCustomGetter,Conditional=XSLT] XSLTProcessorConstructor XSLTProcessor; // Usable with the new operator
#if defined(ENABLE_CHANNEL_MESSAGING) && ENABLE_CHANNEL_MESSAGING
attribute MessagePortConstructor MessagePort;
@@ -482,6 +518,10 @@ module window {
attribute [JSCCustomGetter] SharedWorkerConstructor SharedWorker; // Usable with the new operator
#endif
+#if defined(ENABLE_WEB_SOCKETS) && ENABLE_WEB_SOCKETS
+ attribute [JSCCustomGetter] WebSocketConstructor WebSocket; // Usable with the new operator
+#endif
+
attribute PluginConstructor Plugin;
attribute PluginArrayConstructor PluginArray;
diff --git a/WebCore/page/DragController.cpp b/WebCore/page/DragController.cpp
index 08fb872..634595a 100644
--- a/WebCore/page/DragController.cpp
+++ b/WebCore/page/DragController.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "DragController.h"
+#if ENABLE(DRAG_SUPPORT)
#include "CSSStyleDeclaration.h"
#include "Clipboard.h"
#include "ClipboardAccessPolicy.h"
@@ -46,6 +47,7 @@
#include "HTMLAnchorElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "Image.h"
#include "MoveSelectionCommand.h"
@@ -53,6 +55,7 @@
#include "Page.h"
#include "RenderFileUploadControl.h"
#include "RenderImage.h"
+#include "RenderView.h"
#include "ReplaceSelectionCommand.h"
#include "ResourceRequest.h"
#include "SelectionController.h"
@@ -107,7 +110,7 @@ static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragD
String title;
String url = dragData->asURL(&title);
if (!url.isEmpty()) {
- RefPtr<HTMLAnchorElement> anchor = new HTMLAnchorElement(document);
+ RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(document);
anchor->setHref(url);
ExceptionCode ec;
RefPtr<Node> anchorText = document->createTextNode(title);
@@ -253,6 +256,25 @@ static HTMLInputElement* asFileInput(Node* node)
return 0;
}
+static Element* elementUnderMouse(Document* documentUnderMouse, const IntPoint& p)
+{
+ float zoomFactor = documentUnderMouse->frame()->pageZoomFactor();
+ IntPoint point = roundedIntPoint(FloatPoint(p.x() * zoomFactor, p.y() * zoomFactor));
+
+ HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
+ HitTestResult result(point);
+ documentUnderMouse->renderView()->layer()->hitTest(request, result);
+
+ Node* n = result.innerNode();
+ while (n && !n->isElementNode())
+ n = n->parentNode();
+ if (n)
+ n = n->shadowAncestorNode();
+
+ ASSERT(n);
+ return static_cast<Element*>(n);
+}
+
bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction actionMask, DragOperation& operation)
{
ASSERT(dragData);
@@ -287,10 +309,8 @@ bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction a
return true;
}
- IntPoint dragPos = dragData->clientPosition();
- IntPoint point = frameView->windowToContents(dragPos);
- Element* element = m_documentUnderMouse->elementFromPoint(point.x(), point.y());
- ASSERT(element);
+ IntPoint point = frameView->windowToContents(dragData->clientPosition());
+ Element* element = elementUnderMouse(m_documentUnderMouse, point);
if (!asFileInput(element)) {
VisibleSelection dragCaret = m_documentUnderMouse->frame()->visiblePositionForPoint(point);
m_page->dragCaretController()->setSelection(dragCaret);
@@ -340,8 +360,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
return false;
IntPoint point = m_documentUnderMouse->view()->windowToContents(dragData->clientPosition());
- Element* element = m_documentUnderMouse->elementFromPoint(point.x(), point.y());
- ASSERT(element);
+ Element* element = elementUnderMouse(m_documentUnderMouse, point);
Frame* innerFrame = element->ownerDocument()->frame();
ASSERT(innerFrame);
@@ -630,6 +649,12 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s
if (isDHTMLDrag)
dragImage = clipboard->createDragImage(dragImageOffset);
+ else {
+ // This drag operation is not a DHTML drag and may go outside the WebView.
+ // We provide a default set of allowed drag operations that follows from:
+ // http://trac.webkit.org/browser/trunk/WebKit/mac/WebView/WebHTMLView.mm?rev=48526#L3430
+ m_sourceDragOperation = (DragOperation)(DragOperationGeneric | DragOperationCopy);
+ }
// We allow DHTML/JS to set the drag image, even if its a link, image or text we're dragging.
// This is in the spirit of the IE API, which allows overriding of pasteboard data and DragOp.
@@ -785,3 +810,5 @@ void DragController::placeDragCaret(const IntPoint& windowPoint)
}
} // namespace WebCore
+
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 937f08f..6b4031e 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -87,6 +87,7 @@ namespace WebCore {
using namespace HTMLNames;
+#if ENABLE(DRAG_SUPPORT)
// The link drag hysteresis is much larger than the others because there
// needs to be enough space to cancel the link press without starting a link drag,
// and because dragging links is rare.
@@ -94,6 +95,7 @@ const int LinkDragHysteresis = 40;
const int ImageDragHysteresis = 5;
const int TextDragHysteresis = 3;
const int GeneralDragHysteresis = 3;
+#endif // ENABLE(DRAG_SUPPORT)
// Match key code of composition keydown event on windows.
// IE sends VK_PROCESSKEY which has value 229;
@@ -106,10 +108,9 @@ 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;
-static Frame* subframeForTargetNode(Node*);
static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
-static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node)
+static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node, Node** stopNode)
{
if (!delta)
return;
@@ -118,12 +119,13 @@ static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDir
RenderBox* enclosingBox = node->renderer()->enclosingBox();
if (e.granularity() == ScrollByPageWheelEvent) {
- if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1))
+ if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1, stopNode))
e.accept();
return;
- }
+ }
+
float pixelsToScroll = delta > 0 ? delta : -delta;
- if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll))
+ if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll, stopNode))
e.accept();
}
@@ -146,7 +148,9 @@ EventHandler::EventHandler(Frame* frame)
, m_mousePressed(false)
, m_capturesDragging(false)
, m_mouseDownMayStartSelect(false)
+#if ENABLE(DRAG_SUPPORT)
, m_mouseDownMayStartDrag(false)
+#endif
, m_mouseDownWasSingleClickInSelection(false)
, m_beganSelectingText(false)
, m_panScrollInProgress(false)
@@ -179,11 +183,13 @@ EventHandler::~EventHandler()
{
}
+#if ENABLE(DRAG_SUPPORT)
EventHandler::EventHandlerDragState& EventHandler::dragState()
{
DEFINE_STATIC_LOCAL(EventHandlerDragState, state, ());
return state;
}
+#endif // ENABLE(DRAG_SUPPORT)
void EventHandler::clear()
{
@@ -203,13 +209,16 @@ void EventHandler::clear()
m_touch = 0;
#endif
m_frameSetBeingResized = 0;
+#if ENABLE(DRAG_SUPPORT)
m_dragTarget = 0;
+#endif
m_currentMousePosition = IntPoint();
m_mousePressNode = 0;
m_mousePressed = false;
m_capturesDragging = false;
m_capturingMouseEventsNode = 0;
m_latchedWheelEventNode = 0;
+ m_previousWheelScrolledNode = 0;
}
void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
@@ -357,8 +366,10 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event)
{
+#if ENABLE(DRAG_SUPPORT)
// Reset drag state.
dragState().m_dragSrc = 0;
+#endif
if (ScrollView* scrollView = m_frame->view()) {
if (scrollView->isPointInScrollbarCorner(event.event().pos()))
@@ -371,8 +382,10 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
// so it's allowed to start a drag or selection.
m_mouseDownMayStartSelect = canMouseDownStartSelect(event.targetNode());
+#if ENABLE(DRAG_SUPPORT)
// Careful that the drag starting logic stays in sync with eventMayStartDrag()
m_mouseDownMayStartDrag = singleClick;
+#endif
m_mouseDownWasSingleClickInSelection = false;
@@ -400,7 +413,9 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
Node* innerNode = event.targetNode();
m_mousePressNode = innerNode;
+#if ENABLE(DRAG_SUPPORT)
m_dragStartPos = event.event().pos();
+#endif
bool swallowEvent = false;
m_frame->selection()->setCaretBlinkingSuspended(true);
@@ -420,6 +435,7 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
return swallowEvent;
}
+#if ENABLE(DRAG_SUPPORT)
bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event)
{
if (handleDrag(event))
@@ -442,7 +458,7 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
// If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
// Otherwise, let the bridge handle it so the view can scroll itself.
RenderObject* renderer = targetNode->renderer();
- while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeProgramaticallyScrolled(false))) {
+ while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) {
if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
renderer = renderer->document()->ownerElement()->renderer();
else
@@ -559,6 +575,7 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
m_frame->selection()->setSelection(newSelection);
}
}
+#endif // ENABLE(DRAG_SUPPORT)
bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event)
{
@@ -586,7 +603,9 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
m_frame->selection()->setCaretBlinkingSuspended(false);
m_mousePressed = false;
m_capturesDragging = false;
+#if ENABLE(DRAG_SUPPORT)
m_mouseDownMayStartDrag = false;
+#endif
m_mouseDownMayStartSelect = false;
m_mouseDownMayStartAutoscroll = false;
m_mouseDownWasInSubframe = false;
@@ -598,7 +617,9 @@ bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& e
// on the selection, the selection goes away. However, if we are
// editing, place the caret.
if (m_mouseDownWasSingleClickInSelection && !m_beganSelectingText
+#if ENABLE(DRAG_SUPPORT)
&& m_dragStartPos == event.event().pos()
+#endif
&& m_frame->selection()->isRange()
&& event.event().button() != RightButton) {
VisibleSelection newSelection;
@@ -732,7 +753,7 @@ void EventHandler::updateAutoscrollRenderer()
if (Node* nodeAtPoint = hitTest.innerNode())
m_autoscrollRenderer = nodeAtPoint->renderer();
- while (m_autoscrollRenderer && (!m_autoscrollRenderer->isBox() || !toRenderBox(m_autoscrollRenderer)->canBeProgramaticallyScrolled(false)))
+ while (m_autoscrollRenderer && (!m_autoscrollRenderer->isBox() || !toRenderBox(m_autoscrollRenderer)->canBeScrolledAndHasScrollableArea()))
m_autoscrollRenderer = m_autoscrollRenderer->parent();
}
@@ -741,6 +762,7 @@ void EventHandler::setAutoscrollRenderer(RenderObject* renderer)
m_autoscrollRenderer = renderer;
}
+#if ENABLE(DRAG_SUPPORT)
void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const
{
flagDHTML = false;
@@ -761,6 +783,7 @@ void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const
flagDHTML = (mask & DragSourceActionDHTML) != DragSourceActionNone;
flagUA = ((mask & DragSourceActionImage) || (mask & DragSourceActionLink) || (mask & DragSourceActionSelection));
}
+#endif // ENABLE(DRAG_SUPPORT)
HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars)
{
@@ -883,8 +906,10 @@ bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity g
if (node) {
RenderObject* r = node->renderer();
- if (r && !r->isListBox())
- return r->enclosingBox()->scroll(direction, granularity);
+ if (r && !r->isListBox() && r->enclosingBox()->scroll(direction, granularity)) {
+ setFrameWasScrolledByUser();
+ return true;
+ }
}
return false;
@@ -914,10 +939,10 @@ Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResul
{
if (!hitTestResult.isOverWidget())
return 0;
- return subframeForTargetNode(hitTestResult.targetNode());
+ return EventHandler::subframeForTargetNode(hitTestResult.targetNode());
}
-Frame* subframeForTargetNode(Node* node)
+Frame* EventHandler::subframeForTargetNode(Node* node)
{
if (!node)
return 0;
@@ -1117,7 +1142,9 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
m_capturesDragging = true;
m_currentMousePosition = mouseEvent.pos();
m_mouseDownTimestamp = mouseEvent.timestamp();
+#if ENABLE(DRAG_SUPPORT)
m_mouseDownMayStartDrag = false;
+#endif
m_mouseDownMayStartSelect = false;
m_mouseDownMayStartAutoscroll = false;
if (FrameView* view = m_frame->view())
@@ -1141,6 +1168,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
m_mousePressNode = mev.targetNode();
+#if ENABLE(INSPECTOR)
if (Page* page = m_frame->page()) {
InspectorController* inspector = page->inspectorController();
if (inspector && inspector->enabled() && inspector->searchingForNodeInPage()) {
@@ -1149,6 +1177,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
return true;
}
}
+#endif
Frame* subframe = subframeForHitTestResult(mev);
if (subframe && passMousePressEventToSubframe(mev, subframe)) {
@@ -1172,7 +1201,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) {
RenderObject* renderer = mev.targetNode()->renderer();
- while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeProgramaticallyScrolled(false))) {
+ while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) {
if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
renderer = renderer->document()->ownerElement()->renderer();
else
@@ -1393,8 +1422,10 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
return true;
swallowEvent = dispatchMouseEvent(eventNames().mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true);
+#if ENABLE(DRAG_SUPPORT)
if (!swallowEvent)
swallowEvent = handleMouseDraggedEvent(mev);
+#endif // ENABLE(DRAG_SUPPORT)
return swallowEvent;
}
@@ -1464,6 +1495,7 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
}
+#if ENABLE(DRAG_SUPPORT)
bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTarget, const PlatformMouseEvent& event, Clipboard* clipboard)
{
FrameView* view = m_frame->view();
@@ -1508,15 +1540,15 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
// it is sometimes incorrect when dragging within subframes, as seen with
// LayoutTests/fast/events/drag-in-frames.html.
if (newTarget) {
- if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
- accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);
+ 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);
}
if (m_dragTarget) {
- Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag))
- ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
+ 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
@@ -1524,8 +1556,9 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
}
} else {
if (newTarget) {
- if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
- accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);
+ 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);
}
@@ -1571,6 +1604,7 @@ void EventHandler::clearDragState()
m_sendingEventToSubview = false;
#endif
}
+#endif // ENABLE(DRAG_SUPPORT)
void EventHandler::setCapturingMouseEventsNode(PassRefPtr<Node> n)
{
@@ -1692,12 +1726,15 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
swallowEvent = m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount);
if (!swallowEvent && eventType == eventNames().mousedownEvent) {
+ // The layout needs to be up to date to determine if an element is focusable.
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
+
// Blur current focus node when a link/button is clicked; this
// is expected by some sites that rely on onChange handlers running
// from form fields before the button click is processed.
Node* node = m_nodeUnderMouse.get();
RenderObject* renderer = node ? node->renderer() : 0;
-
+
// Walk up the render tree to search for a node to focus.
// Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
while (renderer) {
@@ -1736,6 +1773,13 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
return swallowEvent;
}
+#if !PLATFORM(GTK)
+bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&) const
+{
+ return false;
+}
+#endif
+
bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
{
Document* doc = m_frame->document();
@@ -1749,35 +1793,39 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
FrameView* view = m_frame->view();
if (!view)
return false;
+ setFrameWasScrolledByUser();
IntPoint vPoint = view->windowToContents(e.pos());
Node* node;
bool isOverWidget;
bool didSetLatchedNode = false;
-
+
+ HitTestRequest request(HitTestRequest::ReadOnly);
+ HitTestResult result(vPoint);
+ doc->renderView()->layer()->hitTest(request, result);
+
if (m_useLatchedWheelEventNode) {
if (!m_latchedWheelEventNode) {
- HitTestRequest request(HitTestRequest::ReadOnly);
- HitTestResult result(vPoint);
- doc->renderView()->layer()->hitTest(request, result);
m_latchedWheelEventNode = result.innerNode();
m_widgetIsLatched = result.isOverWidget();
didSetLatchedNode = true;
}
-
+
node = m_latchedWheelEventNode.get();
isOverWidget = m_widgetIsLatched;
} else {
if (m_latchedWheelEventNode)
m_latchedWheelEventNode = 0;
-
- HitTestRequest request(HitTestRequest::ReadOnly);
- HitTestResult result(vPoint);
- doc->renderView()->layer()->hitTest(request, result);
+ if (m_previousWheelScrolledNode)
+ m_previousWheelScrolledNode = 0;
+
node = result.innerNode();
isOverWidget = result.isOverWidget();
}
-
+
+ if (shouldTurnVerticalTicksIntoHorizontal(result))
+ e.turnVerticalTicksIntoHorizontal();
+
if (node) {
// Figure out which view to send the event to.
RenderObject* target = node->renderer();
@@ -1794,17 +1842,20 @@ 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).
- scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node);
- scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node);
+ 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;
}
}
@@ -1819,6 +1870,7 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
return e.isAccepted();
}
+#if ENABLE(CONTEXT_MENUS)
bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
{
Document* doc = m_frame->document();
@@ -1849,6 +1901,7 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
return swallowEvent;
}
+#endif // ENABLE(CONTEXT_MENUS)
void EventHandler::scheduleHoverStateUpdate()
{
@@ -1868,12 +1921,13 @@ bool EventHandler::canMouseDownStartSelect(Node* node)
for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
if (Node* node = curr->node())
- return node->dispatchEvent(eventNames().selectstartEvent, true, true);
+ return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
}
return true;
}
+#if ENABLE(DRAG_SUPPORT)
bool EventHandler::canMouseDragExtendSelect(Node* node)
{
if (!node || !node->renderer())
@@ -1881,11 +1935,12 @@ bool EventHandler::canMouseDragExtendSelect(Node* node)
for (RenderObject* curr = node->renderer(); curr; curr = curr->parent()) {
if (Node* node = curr->node())
- return node->dispatchEvent(eventNames().selectstartEvent, true, true);
+ return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
}
return true;
}
+#endif // ENABLE(DRAG_SUPPORT)
void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
{
@@ -2109,6 +2164,7 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
}
}
+#if ENABLE(DRAG_SUPPORT)
bool EventHandler::dragHysteresisExceeded(const FloatPoint& floatDragViewportLocation) const
{
IntPoint dragViewportLocation((int)floatDragViewportLocation.x(), (int)floatDragViewportLocation.y());
@@ -2142,7 +2198,7 @@ void EventHandler::freeClipboard()
bool EventHandler::shouldDragAutoNode(Node* node, const IntPoint& point) const
{
- if (!node || node->hasChildNodes() || !m_frame->view())
+ if (!node || !m_frame->view())
return false;
Page* page = m_frame->page();
return page && page->dragController()->mayStartDragAtEventLocation(m_frame, point);
@@ -2308,6 +2364,7 @@ cleanupDrag:
// No more default handling (like selection), whether we're past the hysteresis bounds or not
return true;
}
+#endif // ENABLE(DRAG_SUPPORT)
bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent, bool isLineBreak, bool isBackTab)
{
@@ -2339,7 +2396,7 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
}
-#if !PLATFORM(MAC) && !PLATFORM(QT)
+#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(HAIKU)
bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent*) const
{
return false;
@@ -2440,22 +2497,28 @@ void EventHandler::capsLockStateMayHaveChanged()
void EventHandler::sendResizeEvent()
{
- m_frame->document()->dispatchWindowEvent(eventNames().resizeEvent, false, false);
+ m_frame->document()->dispatchWindowEvent(Event::create(eventNames().resizeEvent, false, false));
}
void EventHandler::sendScrollEvent()
{
+ setFrameWasScrolledByUser();
+ if (m_frame->view())
+ m_frame->document()->dispatchEvent(Event::create(eventNames().scrollEvent, true, false));
+}
+
+void EventHandler::setFrameWasScrolledByUser()
+{
FrameView* v = m_frame->view();
- if (!v)
- return;
- v->setWasScrolledByUser(true);
- m_frame->document()->dispatchEvent(eventNames().scrollEvent, true, false);
+ if (v)
+ v->setWasScrolledByUser(true);
}
bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, Scrollbar* scrollbar)
{
if (!scrollbar || !scrollbar->enabled())
return false;
+ setFrameWasScrolledByUser();
return scrollbar->mouseDown(mev.event());
}
diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h
index 7fe64ad..3348366 100644
--- a/WebCore/page/EventHandler.h
+++ b/WebCore/page/EventHandler.h
@@ -66,10 +66,12 @@ class PlatformTouchEvent;
class Touch;
#endif
+#if ENABLE(DRAG_SUPPORT)
extern const int LinkDragHysteresis;
extern const int ImageDragHysteresis;
extern const int TextDragHysteresis;
extern const int GeneralDragHysteresis;
+#endif // ENABLE(DRAG_SUPPORT)
enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars };
@@ -80,7 +82,9 @@ public:
void clear();
+#if ENABLE(DRAG_SUPPORT)
void updateSelectionForMouseDrag();
+#endif
Node* mousePressNode() const;
void setMousePressNode(PassRefPtr<Node>);
@@ -99,9 +103,11 @@ public:
void setCapturingMouseEventsNode(PassRefPtr<Node>);
+#if ENABLE(DRAG_SUPPORT)
bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
+#endif
void scheduleHoverStateUpdate();
@@ -113,11 +119,17 @@ public:
void setIgnoreWheelEvents(bool);
+ static Frame* subframeForTargetNode(Node*);
+
bool scrollOverflow(ScrollDirection, ScrollGranularity);
bool scrollRecursively(ScrollDirection, ScrollGranularity);
+#if ENABLE(DRAG_SUPPORT)
bool shouldDragAutoNode(Node*, const IntPoint&) const; // -webkit-user-drag == auto
+#endif
+
+ bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&) const;
bool tabsToLinks(KeyboardEvent*) const;
bool tabsToAllControls(KeyboardEvent*) const;
@@ -131,11 +143,16 @@ public:
bool handleMouseReleaseEvent(const PlatformMouseEvent&);
bool handleWheelEvent(PlatformWheelEvent&);
+<<<<<<< HEAD:WebCore/page/EventHandler.h
#if ENABLE(TOUCH_EVENTS) // Android
bool handleTouchEvent(const PlatformTouchEvent&);
#endif
+=======
+#if ENABLE(CONTEXT_MENUS)
+>>>>>>> webkit.org at 49305:WebCore/page/EventHandler.h
bool sendContextMenuEvent(const PlatformMouseEvent&);
+#endif
void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
@@ -150,10 +167,12 @@ public:
bool isLineBreak = false, bool isBackTab = false);
void defaultTextInputEventHandler(TextEvent*);
+#if ENABLE(DRAG_SUPPORT)
bool eventMayStartDrag(const PlatformMouseEvent&) const;
void dragSourceMovedTo(const PlatformMouseEvent&);
void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
+#endif
void focusDocumentView();
@@ -172,7 +191,9 @@ public:
bool keyEvent(NSEvent *);
bool wheelEvent(NSEvent *);
+#if ENABLE(CONTEXT_MENUS)
bool sendContextMenuEvent(NSEvent *);
+#endif
bool eventMayStartDrag(NSEvent *);
void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
@@ -183,6 +204,7 @@ public:
#endif
private:
+#if ENABLE(DRAG_SUPPORT)
struct EventHandlerDragState {
RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
bool m_dragSrcIsLink;
@@ -197,6 +219,7 @@ private:
static const double TextDragDelay;
PassRefPtr<Clipboard> createDraggingClipboard() const;
+#endif // ENABLE(DRAG_SUPPORT)
bool eventActivatedView(const PlatformMouseEvent&) const;
void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
@@ -208,7 +231,9 @@ private:
bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
+#if ENABLE(DRAG_SUPPORT)
bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
+#endif
bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
void handleKeyboardSelectionMovement(KeyboardEvent*);
@@ -221,7 +246,9 @@ private:
void hoverTimerFired(Timer<EventHandler>*);
static bool canMouseDownStartSelect(Node*);
+#if ENABLE(DRAG_SUPPORT)
static bool canMouseDragExtendSelect(Node*);
+#endif
void handleAutoscroll(RenderObject*);
void startAutoscrollTimer();
@@ -238,18 +265,22 @@ private:
MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
+#if ENABLE(DRAG_SUPPORT)
bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
void freeClipboard();
bool handleDrag(const MouseEventWithHitTestResults&);
+#endif
bool handleMouseUp(const MouseEventWithHitTestResults&);
+#if ENABLE(DRAG_SUPPORT)
void clearDragState();
bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
bool dragHysteresisExceeded(const FloatPoint&) const;
bool dragHysteresisExceeded(const IntPoint&) const;
+#endif // ENABLE(DRAG_SUPPORT)
bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
@@ -268,18 +299,26 @@ private:
void defaultSpaceEventHandler(KeyboardEvent*);
void defaultTabEventHandler(KeyboardEvent*);
+#if ENABLE(DRAG_SUPPORT)
void allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const;
+#endif
// The following are called at the beginning of handleMouseUp and handleDrag.
// If they return true it indicates that they have consumed the event.
bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
+#if ENABLE(DRAG_SUPPORT)
bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
+#endif
bool invertSenseOfTabsToLinks(KeyboardEvent*) const;
+#if ENABLE(DRAG_SUPPORT)
void updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint);
+#endif
void updateLastScrollbarUnderMouse(Scrollbar*, bool);
+
+ void setFrameWasScrolledByUser();
bool capturesDragging() const { return m_capturesDragging; }
@@ -296,11 +335,15 @@ private:
RefPtr<Node> m_mousePressNode;
bool m_mouseDownMayStartSelect;
+#if ENABLE(DRAG_SUPPORT)
bool m_mouseDownMayStartDrag;
+#endif
bool m_mouseDownWasSingleClickInSelection;
bool m_beganSelectingText;
+#if ENABLE(DRAG_SUPPORT)
IntPoint m_dragStartPos;
+#endif
IntPoint m_panScrollStartPos;
bool m_panScrollInProgress;
@@ -337,7 +380,9 @@ private:
RefPtr<Touch> m_touch;
#endif
+#if ENABLE(DRAG_SUPPORT)
RefPtr<Node> m_dragTarget;
+#endif
RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
@@ -351,7 +396,9 @@ private:
bool m_useLatchedWheelEventNode;
RefPtr<Node> m_latchedWheelEventNode;
bool m_widgetIsLatched;
-
+
+ RefPtr<Node> m_previousWheelScrolledNode;
+
#if PLATFORM(MAC)
NSView *m_mouseDownView;
bool m_sendingEventToSubview;
diff --git a/WebCore/page/EventSource.cpp b/WebCore/page/EventSource.cpp
new file mode 100644
index 0000000..2c9a343
--- /dev/null
+++ b/WebCore/page/EventSource.cpp
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2009 Ericsson AB
+ * 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.
+ * 3. Neither the name of Ericsson nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(EVENTSOURCE)
+
+#include "EventSource.h"
+
+#include "Cache.h"
+#include "DOMWindow.h"
+#include "Event.h"
+#include "EventException.h"
+#include "PlatformString.h"
+#include "MessageEvent.h"
+#include "ResourceError.h"
+#include "ResourceRequest.h"
+#include "ResourceResponse.h"
+#include "ScriptExecutionContext.h"
+#include "SerializedScriptValue.h"
+#include "TextResourceDecoder.h"
+#include "ThreadableLoader.h"
+
+namespace WebCore {
+
+const unsigned long long EventSource::defaultReconnectDelay = 3000;
+
+EventSource::EventSource(const String& url, ScriptExecutionContext* context, ExceptionCode& ec)
+ : ActiveDOMObject(context, this)
+ , m_state(CONNECTING)
+ , m_reconnectTimer(this, &EventSource::reconnectTimerFired)
+ , m_failSilently(false)
+ , m_requestInFlight(false)
+ , m_reconnectDelay(defaultReconnectDelay)
+{
+ if (url.isEmpty() || !(m_url = context->completeURL(url)).isValid()) {
+ ec = SYNTAX_ERR;
+ return;
+ }
+ // FIXME: should support cross-origin requests
+ if (!scriptExecutionContext()->securityOrigin()->canRequest(m_url)) {
+ ec = SECURITY_ERR;
+ return;
+ }
+
+ m_origin = scriptExecutionContext()->securityOrigin()->toString();
+ m_decoder = TextResourceDecoder::create("text/plain", "UTF-8");
+
+ setPendingActivity(this);
+ connect();
+}
+
+EventSource::~EventSource()
+{
+}
+
+void EventSource::connect()
+{
+ ResourceRequest request(m_url);
+ request.setHTTPMethod("GET");
+ request.setHTTPHeaderField("Accept", "text/event-stream");
+ request.setHTTPHeaderField("Cache-Control", "no-cache");
+ if (!m_lastEventId.isEmpty())
+ request.setHTTPHeaderField("Last-Event-ID", m_lastEventId);
+
+ ThreadableLoaderOptions options;
+ options.sendLoadCallbacks = true;
+ options.sniffContent = false;
+ options.allowCredentials = true;
+
+ m_loader = ThreadableLoader::create(scriptExecutionContext(), this, request, options);
+
+ m_requestInFlight = true;
+
+ if (!scriptExecutionContext()->isWorkerContext())
+ cache()->loader()->nonCacheRequestInFlight(m_url);
+}
+
+void EventSource::endRequest()
+{
+ m_requestInFlight = false;
+
+ if (!m_failSilently)
+ dispatchEvent(Event::create(eventNames().errorEvent, false, false));
+
+ if (!scriptExecutionContext()->isWorkerContext())
+ cache()->loader()->nonCacheRequestComplete(m_url);
+
+ if (m_state != CLOSED)
+ scheduleReconnect();
+ else
+ unsetPendingActivity(this);
+}
+
+void EventSource::scheduleReconnect()
+{
+ m_state = CONNECTING;
+ m_reconnectTimer.startOneShot(m_reconnectDelay / 1000);
+}
+
+void EventSource::reconnectTimerFired(Timer<EventSource>*)
+{
+ connect();
+}
+
+String EventSource::url() const
+{
+ return m_url.string();
+}
+
+EventSource::State EventSource::readyState() const
+{
+ return m_state;
+}
+
+void EventSource::close()
+{
+ if (m_state == CLOSED)
+ return;
+
+ if (m_reconnectTimer.isActive()) {
+ m_reconnectTimer.stop();
+ unsetPendingActivity(this);
+ }
+
+ m_state = CLOSED;
+ m_failSilently = true;
+
+ if (m_requestInFlight)
+ m_loader->cancel();
+}
+
+ScriptExecutionContext* EventSource::scriptExecutionContext() const
+{
+ return ActiveDOMObject::scriptExecutionContext();
+}
+
+void EventSource::didReceiveResponse(const ResourceResponse& response)
+{
+ int statusCode = response.httpStatusCode();
+ if (statusCode == 200 && response.httpHeaderField("Content-Type") == "text/event-stream") {
+ m_state = OPEN;
+ dispatchEvent(Event::create(eventNames().openEvent, false, false));
+ } else {
+ if (statusCode <= 200 || statusCode > 299)
+ m_state = CLOSED;
+ m_loader->cancel();
+ }
+}
+
+void EventSource::didReceiveData(const char* data, int length)
+{
+ append(m_receiveBuf, m_decoder->decode(data, length));
+ parseEventStream();
+}
+
+void EventSource::didFinishLoading(unsigned long)
+{
+ if (m_receiveBuf.size() > 0 || m_data.size() > 0) {
+ append(m_receiveBuf, "\n\n");
+ parseEventStream();
+ }
+ m_state = CONNECTING;
+ endRequest();
+}
+
+void EventSource::didFail(const ResourceError& error)
+{
+ int canceled = error.isCancellation();
+ if (((m_state == CONNECTING) && !canceled) || ((m_state == OPEN) && canceled))
+ m_state = CLOSED;
+ endRequest();
+}
+
+void EventSource::didFailRedirectCheck()
+{
+ m_state = CLOSED;
+ m_loader->cancel();
+}
+
+void EventSource::parseEventStream()
+{
+ unsigned int bufPos = 0;
+ unsigned int bufSize = m_receiveBuf.size();
+ for (;;) {
+ 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 '\n':
+ if (i > bufPos && m_receiveBuf[i - 1] == '\r') {
+ carriageReturn++;
+ i--;
+ }
+ lineLength = i - bufPos;
+ break;
+ }
+ }
+
+ if (lineLength < 0)
+ break;
+
+ parseEventStreamLine(bufPos, fieldLength, lineLength);
+ bufPos += lineLength + carriageReturn + 1;
+ }
+
+ if (bufPos == bufSize)
+ m_receiveBuf.clear();
+ else if (bufPos)
+ m_receiveBuf.remove(0, bufPos);
+}
+
+void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int lineLength)
+{
+ if (!lineLength) {
+ if (!m_data.isEmpty())
+ dispatchEvent(createMessageEvent());
+ if (!m_eventName.isEmpty())
+ m_eventName = "";
+ } else if (fieldLength) {
+ bool noValue = fieldLength < 0;
+
+ String field(&m_receiveBuf[bufPos], noValue ? lineLength : fieldLength);
+ int step;
+ if (noValue)
+ step = lineLength;
+ else if (m_receiveBuf[bufPos + fieldLength + 1] != ' ')
+ step = fieldLength + 1;
+ else
+ step = fieldLength + 2;
+ bufPos += step;
+ 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);
+ } else if (field == "event")
+ m_eventName = valueLength ? String(&m_receiveBuf[bufPos], valueLength) : "";
+ else if (field == "id")
+ m_lastEventId = valueLength ? String(&m_receiveBuf[bufPos], valueLength) : "";
+ else if (field == "retry") {
+ if (!valueLength)
+ m_reconnectDelay = defaultReconnectDelay;
+ else {
+ String value(&m_receiveBuf[bufPos], valueLength);
+ bool ok;
+ unsigned long long retry = value.toUInt64(&ok);
+ if (ok)
+ m_reconnectDelay = retry;
+ }
+ }
+ }
+}
+
+void EventSource::stop()
+{
+ close();
+}
+
+PassRefPtr<MessageEvent> EventSource::createMessageEvent()
+{
+ RefPtr<MessageEvent> event = MessageEvent::create();
+ event->initMessageEvent(m_eventName.isEmpty() ? eventNames().messageEvent : AtomicString(m_eventName), false, false, SerializedScriptValue::create(String::adopt(m_data)), m_origin, m_lastEventId, 0, 0);
+ return event.release();
+}
+
+EventTargetData* EventSource::eventTargetData()
+{
+ return &m_eventTargetData;
+}
+
+EventTargetData* EventSource::ensureEventTargetData()
+{
+ return &m_eventTargetData;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(EVENTSOURCE)
diff --git a/WebCore/page/EventSource.h b/WebCore/page/EventSource.h
new file mode 100644
index 0000000..5b037a4
--- /dev/null
+++ b/WebCore/page/EventSource.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2009 Ericsson AB
+ * 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.
+ * 3. Neither the name of Ericsson 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 EventSource_h
+#define EventSource_h
+
+#if ENABLE(EVENTSOURCE)
+
+#include "ActiveDOMObject.h"
+#include "AtomicStringHash.h"
+#include "EventListener.h"
+#include "EventNames.h"
+#include "EventTarget.h"
+#include "KURL.h"
+#include "ThreadableLoaderClient.h"
+#include "Timer.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class MessageEvent;
+ class ResourceResponse;
+ class TextResourceDecoder;
+ class ThreadableLoader;
+
+ class EventSource : public RefCounted<EventSource>, public EventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
+ public:
+ static PassRefPtr<EventSource> create(const String& url, ScriptExecutionContext* context, ExceptionCode& ec) { return adoptRef(new EventSource(url, context, ec)); }
+ virtual ~EventSource();
+
+ static const unsigned long long defaultReconnectDelay;
+
+ String url() const;
+
+ enum State {
+ CONNECTING = 0,
+ OPEN = 1,
+ CLOSED = 2,
+ };
+
+ State readyState() const;
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(open);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+
+ void close();
+
+ using RefCounted<EventSource>::ref;
+ using RefCounted<EventSource>::deref;
+
+ virtual EventSource* toEventSource() { return this; }
+ virtual ScriptExecutionContext* scriptExecutionContext() const;
+
+ virtual void stop();
+
+ private:
+ EventSource(const String& url, ScriptExecutionContext* context, ExceptionCode& ec);
+
+ virtual void refEventTarget() { ref(); }
+ virtual void derefEventTarget() { deref(); }
+ virtual EventTargetData* eventTargetData();
+ virtual EventTargetData* ensureEventTargetData();
+
+ virtual void didReceiveResponse(const ResourceResponse& response);
+ virtual void didReceiveData(const char* data, int length);
+ virtual void didFinishLoading(unsigned long);
+ virtual void didFail(const ResourceError& error);
+ virtual void didFailRedirectCheck();
+
+ void connect();
+ void endRequest();
+ void scheduleReconnect();
+ void reconnectTimerFired(Timer<EventSource>*);
+ void parseEventStream();
+ void parseEventStreamLine(unsigned int pos, int fieldLength, int lineLength);
+ PassRefPtr<MessageEvent> createMessageEvent();
+
+ KURL m_url;
+ State m_state;
+
+ RefPtr<TextResourceDecoder> m_decoder;
+ RefPtr<ThreadableLoader> m_loader;
+ Timer<EventSource> m_reconnectTimer;
+ Vector<UChar> m_receiveBuf;
+ bool m_failSilently;
+ bool m_requestInFlight;
+
+ String m_eventName;
+ Vector<UChar> m_data;
+ String m_lastEventId;
+ unsigned long long m_reconnectDelay;
+ String m_origin;
+
+ EventTargetData m_eventTargetData;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(EVENTSOURCE)
+
+#endif // EventSource_h
diff --git a/WebCore/page/EventSource.idl b/WebCore/page/EventSource.idl
new file mode 100644
index 0000000..561bd68
--- /dev/null
+++ b/WebCore/page/EventSource.idl
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 Ericsson AB
+ * 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.
+ * 3. Neither the name of Ericsson 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.
+ */
+
+module window {
+
+ interface [
+ Conditional=EVENTSOURCE,
+ EventTarget,
+ NoStaticTables
+ ] EventSource {
+
+ readonly attribute DOMString URL;
+
+ // ready state
+ const unsigned short CONNECTING = 0;
+ const unsigned short OPEN = 1;
+ const unsigned short CLOSED = 2;
+ readonly attribute unsigned short readyState;
+
+ // networking
+ attribute EventListener onopen;
+ attribute EventListener onmessage;
+ attribute EventListener onerror;
+ void close();
+
+ // EventTarget interface
+ [Custom] void addEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ [Custom] void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
+ boolean dispatchEvent(in Event evt)
+ raises(EventException);
+
+ };
+}
diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp
index 817801c..5e78c7d 100644
--- a/WebCore/page/FocusController.cpp
+++ b/WebCore/page/FocusController.cpp
@@ -36,6 +36,7 @@
#include "Event.h"
#include "EventHandler.h"
#include "EventNames.h"
+#include "ExceptionCode.h"
#include "Frame.h"
#include "FrameView.h"
#include "FrameTree.h"
@@ -55,6 +56,18 @@ namespace WebCore {
using namespace HTMLNames;
+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
+ if (!focused && document->focusedNode())
+ document->focusedNode()->dispatchBlurEvent();
+ document->dispatchWindowEvent(Event::create(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false));
+ if (focused && document->focusedNode())
+ document->focusedNode()->dispatchFocusEvent();
+}
+
FocusController::FocusController(Page* page)
: m_page(page)
, m_isActive(false)
@@ -75,12 +88,12 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
// Now that the frame is updated, fire events and update the selection focused states of both frames.
if (oldFrame && oldFrame->view()) {
oldFrame->selection()->setFocused(false);
- oldFrame->document()->dispatchWindowEvent(eventNames().blurEvent, false, false);
+ oldFrame->document()->dispatchWindowEvent(Event::create(eventNames().blurEvent, false, false));
}
if (newFrame && newFrame->view() && isFocused()) {
newFrame->selection()->setFocused(true);
- newFrame->document()->dispatchWindowEvent(eventNames().focusEvent, false, false);
+ newFrame->document()->dispatchWindowEvent(Event::create(eventNames().focusEvent, false, false));
}
}
@@ -100,7 +113,7 @@ void FocusController::setFocused(bool focused)
if (m_focusedFrame && m_focusedFrame->view()) {
m_focusedFrame->selection()->setFocused(focused);
- m_focusedFrame->document()->dispatchWindowEvent(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false);
+ dispatchEventsOnWindowAndFocusedNode(m_focusedFrame->document(), focused);
}
}
@@ -146,6 +159,8 @@ bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* even
if (caretBrowsing && !currentNode)
currentNode = frame->selection()->start().node();
+ document->updateLayoutIgnorePendingStylesheets();
+
Node* node = (direction == FocusDirectionForward)
? document->nextFocusableNode(currentNode, event)
: document->previousFocusableNode(currentNode, event);
@@ -341,7 +356,7 @@ void FocusController::setActive(bool active)
focusedOrMainFrame()->selection()->pageActivationChanged();
if (m_focusedFrame && isFocused())
- m_focusedFrame->document()->dispatchWindowEvent(active ? eventNames().focusEvent : eventNames().blurEvent, false, false);
+ dispatchEventsOnWindowAndFocusedNode(m_focusedFrame->document(), active);
}
} // namespace WebCore
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index 78cc25c..c03efb0 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -59,6 +59,7 @@
#include "Navigator.h"
#include "NodeList.h"
#include "Page.h"
+#include "PageGroup.h"
#include "RegularExpression.h"
#include "RenderPart.h"
#include "RenderTableCell.h"
@@ -66,9 +67,12 @@
#include "RenderTheme.h"
#include "RenderView.h"
#include "ScriptController.h"
+#include "ScriptSourceCode.h"
+#include "ScriptValue.h"
#include "Settings.h"
#include "TextIterator.h"
#include "TextResourceDecoder.h"
+#include "UserContentURLPattern.h"
#include "XMLNames.h"
#include "htmlediting.h"
#include "markup.h"
@@ -82,10 +86,6 @@
#include "runtime_root.h"
#endif
-#if FRAME_LOADS_USER_STYLESHEET
-#include "UserStyleSheetLoader.h"
-#endif
-
#if ENABLE(SVG)
#include "SVGDocument.h"
#include "SVGDocumentExtensions.h"
@@ -101,6 +101,10 @@
#include "WMLNames.h"
#endif
+#if ENABLE(MATHML)
+#include "MathMLNames.h"
+#endif
+
using namespace std;
namespace WebCore {
@@ -122,6 +126,7 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
: m_page(page)
, m_treeNode(this, parentFromOwnerElement(ownerElement))
, m_loader(this, frameLoaderClient)
+ , m_redirectScheduler(this)
, m_ownerElement(ownerElement)
, m_script(this)
, m_selectionGranularity(CharacterGranularity)
@@ -131,6 +136,9 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
, m_eventHandler(this)
, m_animationController(this)
, m_lifeSupportTimer(this, &Frame::lifeSupportTimerFired)
+#if ENABLE(ORIENTATION_EVENTS)
+ , m_orientation(0)
+#endif
, m_caretVisible(false)
, m_caretPaint(true)
, m_highlightTextMatches(false)
@@ -138,9 +146,6 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
, m_needsReapplyStyles(false)
, m_isDisconnected(false)
, m_excludeFromTextSearch(false)
-#if FRAME_LOADS_USER_STYLESHEET
- , m_userStyleSheetLoader(0)
-#endif
{
Frame* parent = parentFromOwnerElement(ownerElement);
m_zoomFactor = parent ? parent->m_zoomFactor : 1.0f;
@@ -159,6 +164,10 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
WMLNames::init();
#endif
+#if ENABLE(MATHML)
+ MathMLNames::init();
+#endif
+
XMLNames::init();
if (!ownerElement)
@@ -203,10 +212,6 @@ Frame::~Frame()
}
ASSERT(!m_lifeSupportTimer.isActive());
-
-#if FRAME_LOADS_USER_STYLESHEET
- delete m_userStyleSheetLoader;
-#endif
}
void Frame::init()
@@ -219,6 +224,11 @@ FrameLoader* Frame::loader() const
return &m_loader;
}
+RedirectScheduler* Frame::redirectScheduler() const
+{
+ return &m_redirectScheduler;
+}
+
FrameView* Frame::view() const
{
return m_view.get();
@@ -226,6 +236,12 @@ FrameView* Frame::view() const
void Frame::setView(PassRefPtr<FrameView> view)
{
+ // We the custom scroll bars as early as possible to prevent m_doc->detach()
+ // from messing with the view such that its scroll bars won't be torn down.
+ // FIXME: We should revisit this.
+ if (m_view)
+ m_view->detachCustomScrollbars();
+
// Detach the document now, so any onUnload handlers get run - if
// we wait until the view is destroyed, then things won't be
// hooked up enough for some JavaScript calls to work.
@@ -273,6 +289,15 @@ void Frame::setDocument(PassRefPtr<Document> newDoc)
m_script.updateDocument();
}
+#if ENABLE(ORIENTATION_EVENTS)
+void Frame::sendOrientationChangeEvent(int orientation)
+{
+ m_orientation = orientation;
+ if (Document* doc = document())
+ doc->dispatchWindowEvent(eventNames().orientationchangeEvent, false, false);
+}
+#endif // ENABLE(ORIENTATION_EVENTS)
+
Settings* Frame::settings() const
{
return m_page ? m_page->settings() : 0;
@@ -829,14 +854,6 @@ void Frame::reapplyStyles()
// We should probably eventually move it into its own function.
m_doc->docLoader()->setAutoLoadImages(m_page && m_page->settings()->loadsImagesAutomatically());
-#if FRAME_LOADS_USER_STYLESHEET
- const KURL userStyleSheetLocation = m_page ? m_page->settings()->userStyleSheetLocation() : KURL();
- if (!userStyleSheetLocation.isEmpty())
- setUserStyleSheetLocation(userStyleSheetLocation);
- else
- setUserStyleSheet(String());
-#endif
-
// FIXME: It's not entirely clear why the following is needed.
// The document automatically does this as required when you set the style sheet.
// But we had problems when this code was removed. Details are in
@@ -844,6 +861,39 @@ void Frame::reapplyStyles()
m_doc->updateStyleSelector();
}
+void Frame::injectUserScripts(UserScriptInjectionTime injectionTime)
+{
+ if (!m_page)
+ return;
+
+ // Walk the hashtable. Inject by world.
+ const UserScriptMap* userScripts = m_page->group().userScripts();
+ if (!userScripts)
+ return;
+ UserScriptMap::const_iterator end = userScripts->end();
+ for (UserScriptMap::const_iterator it = userScripts->begin(); it != end; ++it)
+ injectUserScriptsForWorld(it->first, *it->second, injectionTime);
+}
+
+void Frame::injectUserScriptsForWorld(unsigned worldID, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime)
+{
+ if (userScripts.isEmpty())
+ return;
+
+ Document* doc = document();
+ if (!doc)
+ return;
+
+ Vector<ScriptSourceCode> sourceCode;
+ unsigned count = userScripts.size();
+ 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()));
+ }
+ script()->evaluateInIsolatedWorld(worldID, sourceCode);
+}
+
bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const
{
return shouldChangeSelection(selection()->selection(), newSelection, newSelection.affinity(), false);
@@ -1559,6 +1609,11 @@ Page* Frame::page() const
return m_page;
}
+void Frame::detachFromPage()
+{
+ m_page = 0;
+}
+
EventHandler* Frame::eventHandler() const
{
return &m_eventHandler;
@@ -1579,7 +1634,7 @@ void Frame::pageDestroyed()
script()->clearScriptObjects();
script()->updatePlatformScriptObjects();
- m_page = 0;
+ detachFromPage();
}
void Frame::disconnectOwnerElement()
@@ -1624,7 +1679,7 @@ void Frame::unfocusWindow()
page()->chrome()->unfocus();
}
-bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners)
+bool Frame::shouldClose()
{
Chrome* chrome = page() ? page()->chrome() : 0;
if (!chrome || !chrome->canRunBeforeUnloadConfirmPanel())
@@ -1638,7 +1693,8 @@ bool Frame::shouldClose(RegisteredEventListenerVector* alternateEventListeners)
if (!body)
return true;
- RefPtr<BeforeUnloadEvent> beforeUnloadEvent = m_domWindow->dispatchBeforeUnloadEvent(alternateEventListeners);
+ RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
+ m_domWindow->dispatchEvent(beforeUnloadEvent.get(), m_domWindow->document());
if (!beforeUnloadEvent->defaultPrevented())
doc->defaultEventHandler(beforeUnloadEvent.get());
@@ -1759,7 +1815,6 @@ void Frame::createView(const IntSize& viewportSize,
frameView = FrameView::create(this);
frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode);
- frameView->updateDefaultScrollbarState();
setView(frameView);
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index 652269a..6208bbd 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -41,6 +41,7 @@
#include "ScrollBehavior.h"
#include "SelectionController.h"
#include "TextGranularity.h"
+#include "UserScriptTypes.h"
#if PLATFORM(WIN)
#include "FrameWin.h"
@@ -66,6 +67,7 @@ namespace WebCore {
class Editor;
class EventHandler;
class FrameLoader;
+ class RedirectScheduler;
class FrameLoaderClient;
class FrameTree;
class FrameView;
@@ -79,10 +81,6 @@ namespace WebCore {
class VisibleSelection;
class Widget;
-#if FRAME_LOADS_USER_STYLESHEET
- class UserStyleSheetLoader;
-#endif
-
template <typename T> class Timer;
class Frame : public RefCounted<Frame> {
@@ -97,6 +95,7 @@ namespace WebCore {
void init();
Page* page() const;
+ void detachFromPage();
HTMLFrameOwnerElement* ownerElement() const;
void pageDestroyed();
@@ -112,6 +111,7 @@ namespace WebCore {
Editor* editor() const;
EventHandler* eventHandler() const;
FrameLoader* loader() const;
+ RedirectScheduler* redirectScheduler() const;
SelectionController* selection() const;
FrameTree* tree() const;
AnimationController* animation() const;
@@ -128,6 +128,10 @@ namespace WebCore {
void createView(const IntSize&, const Color&, bool, const IntSize &, bool,
ScrollbarMode = ScrollbarAuto, ScrollbarMode = ScrollbarAuto);
+ void injectUserScripts(UserScriptInjectionTime);
+
+ private:
+ void injectUserScriptsForWorld(unsigned worldID, const UserScriptVector&, UserScriptInjectionTime);
private:
Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*);
@@ -139,11 +143,6 @@ namespace WebCore {
Settings* settings() const; // can be NULL
- #if FRAME_LOADS_USER_STYLESHEET
- void setUserStyleSheetLocation(const KURL&);
- void setUserStyleSheet(const String& styleSheetData);
- #endif
-
void setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize);
bool inViewSourceMode() const;
@@ -156,6 +155,14 @@ namespace WebCore {
void setDocument(PassRefPtr<Document>);
+#if ENABLE(ORIENTATION_EVENTS)
+ // Orientation is the interface orientation in degrees. Some examples are:
+ // 0 is straight up; -90 is when the device is rotated 90 clockwise;
+ // 90 is when rotated counter clockwise.
+ void sendOrientationChangeEvent(int orientation);
+ int orientation() const { return m_orientation; }
+#endif
+
void clearTimers();
static void clearTimers(FrameView*, Document*);
@@ -193,7 +200,7 @@ namespace WebCore {
public:
void focusWindow();
void unfocusWindow();
- bool shouldClose(RegisteredEventListenerVector* alternateEventListeners = 0);
+ bool shouldClose();
void scheduleClose();
void setJSStatusBarText(const String&);
@@ -329,6 +336,7 @@ namespace WebCore {
Page* m_page;
mutable FrameTree m_treeNode;
mutable FrameLoader m_loader;
+ mutable RedirectScheduler m_redirectScheduler;
mutable RefPtr<DOMWindow> m_domWindow;
HashSet<DOMWindow*> m_liveFormerWindows;
@@ -357,6 +365,10 @@ namespace WebCore {
Timer<Frame> m_lifeSupportTimer;
+#if ENABLE(ORIENTATION_EVENTS)
+ int m_orientation;
+#endif
+
bool m_caretVisible;
bool m_caretPaint;
@@ -365,11 +377,6 @@ namespace WebCore {
bool m_needsReapplyStyles;
bool m_isDisconnected;
bool m_excludeFromTextSearch;
-
- #if FRAME_LOADS_USER_STYLESHEET
- UserStyleSheetLoader* m_userStyleSheetLoader;
- #endif
-
};
} // namespace WebCore
diff --git a/WebCore/page/FrameTree.cpp b/WebCore/page/FrameTree.cpp
index 24f125d..41caa9c 100644
--- a/WebCore/page/FrameTree.cpp
+++ b/WebCore/page/FrameTree.cpp
@@ -91,7 +91,7 @@ void FrameTree::removeChild(Frame* child)
RefPtr<Frame>& newLocationForNext = m_firstChild == child ? m_firstChild : child->tree()->m_previousSibling->tree()->m_nextSibling;
Frame*& newLocationForPrevious = m_lastChild == child ? m_lastChild : child->tree()->m_nextSibling->tree()->m_previousSibling;
swap(newLocationForNext, child->tree()->m_nextSibling);
- // For some inexplicable reason, the following line does not compile without the explicit std:: namepsace
+ // For some inexplicable reason, the following line does not compile without the explicit std:: namespace
std::swap(newLocationForPrevious, child->tree()->m_previousSibling);
child->tree()->m_previousSibling = 0;
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index ed91587..e7006ed 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -42,11 +42,12 @@
#include "HTMLFrameElement.h"
#include "HTMLFrameSetElement.h"
#include "HTMLNames.h"
+#include "InspectorTimelineAgent.h"
#include "OverflowEvent.h"
-#include "Page.h"
#include "RenderPart.h"
#include "RenderPartObject.h"
#include "RenderScrollbar.h"
+#include "RenderScrollbarPart.h"
#include "RenderTheme.h"
#include "RenderView.h"
#include "Settings.h"
@@ -96,13 +97,10 @@ struct ScheduledEvent {
FrameView::FrameView(Frame* frame)
: m_frame(frame)
- , m_vmode(ScrollbarAuto)
- , m_hmode(ScrollbarAuto)
, m_slowRepaintObjectCount(0)
, m_layoutTimer(this, &FrameView::layoutTimerFired)
, m_layoutRoot(0)
, m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
- , m_needToInitScrollbars(true)
, m_isTransparent(false)
, m_baseBackgroundColor(Color::white)
, m_mediaType("screen")
@@ -115,6 +113,7 @@ FrameView::FrameView(Frame* frame)
, m_shouldUpdateWhileOffscreen(true)
, m_deferSetNeedsLayouts(0)
, m_setNeedsLayoutWasDeferred(false)
+ , m_scrollCorner(0)
{
init();
}
@@ -143,9 +142,15 @@ FrameView::~FrameView()
}
resetScrollbars();
+
+ // Custom scrollbars should already be destroyed at this point
+ ASSERT(!horizontalScrollbar() || !horizontalScrollbar()->isCustomScrollbar());
+ ASSERT(!verticalScrollbar() || !verticalScrollbar()->isCustomScrollbar());
+
setHasHorizontalScrollbar(false); // Remove native scrollbars now before we lose the connection to the HostWindow.
setHasVerticalScrollbar(false);
+ ASSERT(!m_scrollCorner);
ASSERT(m_scheduledEvents.isEmpty());
ASSERT(!m_enqueueEvents);
@@ -206,7 +211,7 @@ void FrameView::resetScrollbars()
// Reset the document's scrollbars back to our defaults before we yield the floor.
m_firstLayout = true;
setScrollbarsSuppressed(true);
- setScrollbarModes(m_hmode, m_vmode);
+ setScrollbarModes(ScrollbarAuto, ScrollbarAuto);
setScrollbarsSuppressed(false);
}
@@ -237,23 +242,18 @@ void FrameView::detachCustomScrollbars()
if (!m_frame)
return;
- Document* document = m_frame->document();
- if (!document)
- return;
-
- Element* body = document->body();
- if (!body)
- return;
-
- RenderBox* renderBox = body->renderBox();
-
Scrollbar* horizontalBar = horizontalScrollbar();
- if (horizontalBar && horizontalBar->isCustomScrollbar() && toRenderScrollbar(horizontalBar)->owningRenderer() == renderBox)
+ if (horizontalBar && horizontalBar->isCustomScrollbar() && !toRenderScrollbar(horizontalBar)->owningRenderer()->isRenderPart())
setHasHorizontalScrollbar(false);
Scrollbar* verticalBar = verticalScrollbar();
- if (verticalBar && verticalBar->isCustomScrollbar() && toRenderScrollbar(verticalBar)->owningRenderer() == renderBox)
+ if (verticalBar && verticalBar->isCustomScrollbar() && !toRenderScrollbar(verticalBar)->owningRenderer()->isRenderPart())
setHasVerticalScrollbar(false);
+
+ if (m_scrollCorner) {
+ m_scrollCorner->destroy();
+ m_scrollCorner = 0;
+ }
}
void FrameView::clear()
@@ -275,21 +275,6 @@ bool FrameView::didFirstLayout() const
return !m_firstLayout;
}
-void FrameView::initScrollbars()
-{
- if (!m_needToInitScrollbars)
- return;
- m_needToInitScrollbars = false;
- updateDefaultScrollbarState();
-}
-
-void FrameView::updateDefaultScrollbarState()
-{
- m_hmode = horizontalScrollbarMode();
- m_vmode = verticalScrollbarMode();
- setScrollbarModes(m_hmode, m_vmode);
-}
-
void FrameView::invalidateRect(const IntRect& rect)
{
if (!parent()) {
@@ -323,12 +308,6 @@ void FrameView::setMarginHeight(int h)
m_margins.setHeight(h);
}
-void FrameView::setCanHaveScrollbars(bool canScroll)
-{
- ScrollView::setCanHaveScrollbars(canScroll);
- scrollbarModes(m_hmode, m_vmode);
-}
-
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).
@@ -377,7 +356,7 @@ void FrameView::adjustViewSize()
RenderView* root = m_frame->contentRenderer();
if (!root)
return;
- setContentsSize(IntSize(root->overflowWidth(), root->overflowHeight()));
+ setContentsSize(IntSize(root->rightLayoutOverflow(), root->bottomLayoutOverflow()));
}
void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
@@ -517,6 +496,12 @@ void FrameView::layout(bool allowSubtree)
if (isPainting())
return;
+#if ENABLE(INSPECTOR)
+ InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
+ if (timelineAgent)
+ timelineAgent->willLayout();
+#endif
+
if (!allowSubtree && m_layoutRoot) {
m_layoutRoot->markContainingBlocksForLayout(false);
m_layoutRoot = 0;
@@ -573,8 +558,9 @@ void FrameView::layout(bool allowSubtree)
m_nestedLayoutCount++;
- ScrollbarMode hMode = m_hmode;
- ScrollbarMode vMode = m_vmode;
+ ScrollbarMode hMode;
+ ScrollbarMode vMode;
+ scrollbarModes(hMode, vMode);
if (!subtree) {
RenderObject* rootRenderer = document->documentElement() ? document->documentElement()->renderer() : 0;
@@ -674,7 +660,7 @@ void FrameView::layout(bool allowSubtree)
#if PLATFORM(MAC)
if (AXObjectCache::accessibilityEnabled())
- root->document()->axObjectCache()->postNotification(root, "AXLayoutComplete", true);
+ root->document()->axObjectCache()->postNotification(root, AXObjectCache::AXLayoutComplete, true);
#endif
#if ENABLE(DASHBOARD_SUPPORT)
updateDashboardRegions();
@@ -709,6 +695,11 @@ void FrameView::layout(bool allowSubtree)
ASSERT(m_enqueueEvents);
}
+#if ENABLE(INSPECTOR)
+ if (timelineAgent)
+ timelineAgent->didLayout();
+#endif
+
m_nestedLayoutCount--;
}
@@ -825,6 +816,22 @@ void FrameView::setScrollPosition(const IntPoint& scrollPoint)
m_inProgrammaticScroll = wasInProgrammaticScroll;
}
+void FrameView::scrollPositionChanged()
+{
+ frame()->eventHandler()->sendScrollEvent();
+
+#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);
+#endif
+}
+
HostWindow* FrameView::hostWindow() const
{
Page* page = frame() ? frame()->page() : 0;
@@ -857,9 +864,9 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
m_repaintRects.append(unionedRect);
}
if (m_repaintCount < cRepaintRectUnionThreshold)
- m_repaintRects.append(r);
+ m_repaintRects.append(visibleContent);
else
- m_repaintRects[0].unite(r);
+ m_repaintRects[0].unite(visibleContent);
m_repaintCount++;
if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive())
@@ -997,7 +1004,8 @@ void FrameView::layoutTimerFired(Timer<FrameView>*)
void FrameView::scheduleRelayout()
{
- ASSERT(!m_frame->document()->inPageCache());
+ // FIXME: We should assert the page is not in the page cache, but that is causing
+ // too many false assertions. See <rdar://problem/7218118>.
ASSERT(m_frame->view() == this);
if (m_layoutRoot) {
@@ -1221,6 +1229,9 @@ void FrameView::scrollToAnchor()
// Align to the top and to the closest side (this matches other browsers).
anchorNode->renderer()->enclosingLayer()->scrollRectToVisible(rect, true, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
+ if (AXObjectCache::accessibilityEnabled())
+ m_frame->document()->axObjectCache()->handleScrolledToAnchor(anchorNode.get());
+
// scrollRectToVisible can call into scrollRectIntoViewRecursively(), which resets m_maintainScrollPositionAnchor.
m_maintainScrollPositionAnchor = anchorNode;
}
@@ -1427,6 +1438,86 @@ void FrameView::updateDashboardRegions()
}
#endif
+void FrameView::invalidateScrollCorner()
+{
+ invalidateRect(scrollCornerRect());
+}
+
+void FrameView::updateScrollCorner()
+{
+ RenderObject* renderer = 0;
+ RefPtr<RenderStyle> cornerStyle;
+
+ if (!scrollCornerRect().isEmpty()) {
+ // Try the <body> element first as a scroll corner source.
+ Document* doc = m_frame->document();
+ Element* body = doc ? doc->body() : 0;
+ if (body && body->renderer()) {
+ renderer = body->renderer();
+ cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
+ }
+
+ if (!cornerStyle) {
+ // If the <body> didn't have a custom style, then the root element might.
+ Element* docElement = doc ? doc->documentElement() : 0;
+ if (docElement && docElement->renderer()) {
+ renderer = docElement->renderer();
+ cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
+ }
+ }
+
+ if (!cornerStyle) {
+ // If we have an owning iframe/frame element, then it can set the custom scrollbar also.
+ if (RenderPart* renderer = m_frame->ownerRenderer())
+ cornerStyle = renderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, renderer->style());
+ }
+ }
+
+ if (cornerStyle) {
+ if (!m_scrollCorner)
+ m_scrollCorner = new (renderer->renderArena()) RenderScrollbarPart(renderer->document());
+ m_scrollCorner->setStyle(cornerStyle.release());
+ invalidateRect(scrollCornerRect());
+ } else if (m_scrollCorner) {
+ m_scrollCorner->destroy();
+ m_scrollCorner = 0;
+ }
+}
+
+void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
+{
+ if (context->updatingControlTints()) {
+ updateScrollCorner();
+ return;
+ }
+
+ if (m_scrollCorner) {
+ m_scrollCorner->paintIntoRect(context, cornerRect.x(), cornerRect.y(), cornerRect);
+ return;
+ }
+
+ ScrollView::paintScrollCorner(context, cornerRect);
+}
+
+bool FrameView::hasCustomScrollbars() const
+{
+ const HashSet<RefPtr<Widget> >* viewChildren = children();
+ HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end();
+ for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) {
+ Widget* widget = current->get();
+ if (widget->isFrameView()) {
+ if (static_cast<FrameView*>(widget)->hasCustomScrollbars())
+ return true;
+ } else if (widget->isScrollbar()) {
+ Scrollbar* scrollbar = static_cast<Scrollbar*>(widget);
+ if (scrollbar->isCustomScrollbar())
+ return true;
+ }
+ }
+
+ return false;
+}
+
void FrameView::updateControlTints()
{
// This is called when control tints are changed from aqua/graphite to clear and vice versa.
@@ -1438,7 +1529,7 @@ void FrameView::updateControlTints()
if (!m_frame || m_frame->loader()->url().isEmpty())
return;
- if (m_frame->contentRenderer() && m_frame->contentRenderer()->theme()->supportsControlTints()) {
+ if ((m_frame->contentRenderer() && m_frame->contentRenderer()->theme()->supportsControlTints()) || hasCustomScrollbars()) {
if (needsLayout())
layout();
PlatformGraphicsContext* const noContext = 0;
@@ -1468,7 +1559,13 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
{
if (!frame())
return;
-
+
+#if ENABLE(INSPECTOR)
+ InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
+ if (timelineAgent)
+ timelineAgent->willPaint();
+#endif
+
Document* document = frame()->document();
#ifndef NDEBUG
@@ -1532,6 +1629,11 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
if (isTopLevelPainter)
sCurrentPaintTimeStamp = 0;
+
+#if ENABLE(INSPECTOR)
+ if (timelineAgent)
+ timelineAgent->didPaint();
+#endif
}
void FrameView::setPaintRestriction(PaintRestriction pr)
@@ -1573,10 +1675,15 @@ void FrameView::layoutIfNeededRecursive()
// layoutIfNeededRecursive is called when we need to make sure layout is up-to-date before
// painting, so we need to flush out any deferred repaints too.
- if (m_deferredRepaintTimer.isActive()) {
- m_deferredRepaintTimer.stop();
- doDeferredRepaints();
- }
+ flushDeferredRepaints();
+}
+
+void FrameView::flushDeferredRepaints()
+{
+ if (!m_deferredRepaintTimer.isActive())
+ return;
+ m_deferredRepaintTimer.stop();
+ doDeferredRepaints();
}
void FrameView::forceLayout(bool allowSubtree)
@@ -1626,7 +1733,7 @@ void FrameView::adjustPageHeight(float *newBottom, float oldTop, float oldBottom
// Use a context with painting disabled.
GraphicsContext context((PlatformGraphicsContext*)0);
root->setTruncatedAt((int)floorf(oldBottom));
- IntRect dirtyRect(0, (int)floorf(oldTop), root->overflowWidth(), (int)ceilf(oldBottom - oldTop));
+ IntRect dirtyRect(0, (int)floorf(oldTop), root->rightLayoutOverflow(), (int)ceilf(oldBottom - oldTop));
root->layer()->paint(&context, dirtyRect);
*newBottom = root->bestTruncatedAt();
if (*newBottom == 0)
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index 1bdcfb3..4c900ae 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -25,7 +25,9 @@
#ifndef FrameView_h
#define FrameView_h
+#include "Frame.h"
#include "IntSize.h"
+#include "Page.h"
#include "RenderLayer.h"
#include "ScrollView.h"
#include <wtf/Forward.h>
@@ -37,6 +39,7 @@ class Color;
class Event;
class Frame;
class FrameViewPrivate;
+class InspectorTimelineAgent;
class IntRect;
class Node;
class PlatformMouseEvent;
@@ -69,8 +72,6 @@ public:
void setMarginWidth(int);
void setMarginHeight(int);
- virtual void setCanHaveScrollbars(bool);
-
virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
virtual void setContentsSize(const IntSize&);
@@ -122,8 +123,6 @@ public:
void setShouldUpdateWhileOffscreen(bool);
void adjustViewSize();
- void initScrollbars();
- void updateDefaultScrollbarState();
virtual IntRect windowClipRect(bool clipToContents = true) const;
IntRect windowClipRectForLayer(const RenderLayer*, bool clipToLayerContents) const;
@@ -132,6 +131,7 @@ public:
virtual void scrollRectIntoViewRecursively(const IntRect&);
virtual void setScrollPosition(const IntPoint&);
+ void scrollPositionChanged();
String mediaType() const;
void setMediaType(const String&);
@@ -174,6 +174,7 @@ public:
static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting
void layoutIfNeededRecursive();
+ void flushDeferredRepaints();
void setIsVisuallyNonEmpty() { m_isVisuallyNonEmpty = true; }
@@ -190,6 +191,9 @@ public:
virtual IntPoint convertFromRenderer(const RenderObject*, const IntPoint&) const;
virtual IntPoint convertToRenderer(const RenderObject*, const IntPoint&) const;
+ bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
+ void invalidateScrollCorner();
+
private:
FrameView(Frame*);
@@ -232,7 +236,16 @@ private:
bool updateWidgets();
void scrollToAnchor();
+
+#if ENABLE(INSPECTOR)
+ InspectorTimelineAgent* inspectorTimelineAgent() const;
+#endif
+ bool hasCustomScrollbars() const;
+
+ virtual void updateScrollCorner();
+ virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
+
static double sCurrentPaintTimeStamp; // used for detecting decoded resource thrash in the cache
IntSize m_size;
@@ -242,8 +255,6 @@ private:
bool m_doFullRepaint;
- ScrollbarMode m_vmode;
- ScrollbarMode m_hmode;
bool m_useSlowRepaints;
bool m_isOverlapped;
bool m_contentIsOpaque;
@@ -263,7 +274,6 @@ private:
bool m_firstLayoutCallbackPending;
bool m_firstLayout;
- bool m_needToInitScrollbars;
bool m_isTransparent;
Color m_baseBackgroundColor;
IntSize m_lastLayoutSize;
@@ -302,8 +312,18 @@ private:
bool m_firstVisuallyNonEmptyLayoutCallbackPending;
RefPtr<Node> m_maintainScrollPositionAnchor;
+
+ // Renderer to hold our custom scroll corner.
+ RenderScrollbarPart* m_scrollCorner;
};
+#if ENABLE(INSPECTOR)
+inline InspectorTimelineAgent* FrameView::inspectorTimelineAgent() const
+{
+ return m_frame->page() ? m_frame->page()->inspectorTimelineAgent() : 0;
+}
+#endif
+
} // namespace WebCore
#endif // FrameView_h
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index bf877e6..1ded2af 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -41,8 +41,11 @@
namespace WebCore {
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
static const char* permissionDeniedErrorMessage = "User denied Geolocation";
+=======
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
Geolocation::GeoNotifier::GeoNotifier(Geolocation* geolocation, PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
: m_geolocation(geolocation)
, m_successCallback(successCallback)
@@ -60,15 +63,30 @@ Geolocation::GeoNotifier::GeoNotifier(Geolocation* geolocation, PassRefPtr<Posit
void Geolocation::GeoNotifier::setFatalError(PassRefPtr<PositionError> error)
{
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
m_fatalError = error;
m_timer.startOneShot(0);
+=======
+ ASSERT(m_successCallback);
+ // If no options were supplied from JS, we should have created a default set
+ // of options in JSGeolocationCustom.cpp.
+ ASSERT(m_options);
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
}
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
void Geolocation::GeoNotifier::setCachedPosition(Geoposition* cachedPosition)
+=======
+bool Geolocation::GeoNotifier::hasZeroTimeout() const
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
{
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
// We do not take owenership from the caller, but add our own ref count.
m_cachedPosition = cachedPosition;
m_timer.startOneShot(0);
+=======
+ return m_options->hasTimeout() && m_options->timeout() == 0;
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
}
void Geolocation::GeoNotifier::startTimerIfNeeded()
@@ -81,6 +99,7 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
{
m_timer.stop();
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
if (m_fatalError) {
if (m_errorCallback)
m_errorCallback->handleEvent(m_fatalError.get());
@@ -95,8 +114,14 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*)
return;
}
+=======
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
if (m_errorCallback) {
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timed out");
+=======
+ RefPtr<PositionError> error = PositionError::create(PositionError::TIMEOUT, "Timeout expired");
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
m_errorCallback->handleEvent(error.get());
}
m_geolocation->requestTimedOut(this);
@@ -274,23 +299,55 @@ void Geolocation::disconnectFrame()
void Geolocation::getCurrentPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
{
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
RefPtr<GeoNotifier> notifier = makeRequest(successCallback, errorCallback, options);
ASSERT(notifier);
+=======
+ RefPtr<GeoNotifier> notifier = GeoNotifier::create(this, successCallback, errorCallback, options);
+
+ if (notifier->hasZeroTimeout() || m_service->startUpdating(notifier->m_options.get()))
+ 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;
+ }
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
m_oneShots.add(notifier);
}
int Geolocation::watchPosition(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
{
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
RefPtr<GeoNotifier> notifier = makeRequest(successCallback, errorCallback, options);
ASSERT(notifier);
+=======
+ RefPtr<GeoNotifier> notifier = GeoNotifier::create(this, successCallback, errorCallback, options);
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
+=======
+ if (notifier->hasZeroTimeout() || m_service->startUpdating(notifier->m_options.get()))
+ 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;
+ }
+
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
static int sIdentifier = 0;
m_watchers.set(++sIdentifier, notifier);
return sIdentifier;
}
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
PassRefPtr<Geolocation::GeoNotifier> Geolocation::makeRequest(PassRefPtr<PositionCallback> successCallback, PassRefPtr<PositionErrorCallback> errorCallback, PassRefPtr<PositionOptions> options)
{
RefPtr<GeoNotifier> notifier = GeoNotifier::create(this, successCallback, errorCallback, options);
@@ -334,6 +391,8 @@ void Geolocation::fatalErrorOccurred(Geolocation::GeoNotifier* notifier)
m_service->stopUpdating();
}
+=======
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
void Geolocation::requestTimedOut(GeoNotifier* notifier)
{
// If this is a one-shot request, stop it.
@@ -343,6 +402,7 @@ void Geolocation::requestTimedOut(GeoNotifier* notifier)
m_service->stopUpdating();
}
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
void Geolocation::requestReturnedCachedPosition(GeoNotifier* notifier)
{
// If this is a one-shot request, stop it.
@@ -372,6 +432,8 @@ bool Geolocation::haveSuitableCachedPosition(PositionOptions* options)
return m_cachedPositionManager->cachedPosition()->timestamp() > currentTimeMillis - options->maximumAge();
}
+=======
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
void Geolocation::clearWatch(int watchId)
{
m_watchers.remove(watchId);
@@ -397,9 +459,17 @@ 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;
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
if (!isAllowed()) {
RefPtr<WebCore::PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage);
+=======
+
+ if (isAllowed())
+ makeSuccessCallbacks();
+ else {
+ RefPtr<PositionError> error = PositionError::create(PositionError::PERMISSION_DENIED, "User disallowed Geolocation");
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
error->setIsFatal(true);
handleError(error.get());
return;
@@ -436,7 +506,10 @@ void Geolocation::sendPosition(Vector<RefPtr<GeoNotifier> >& notifiers, Geoposit
RefPtr<GeoNotifier> notifier = *it;
ASSERT(notifier->m_successCallback);
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
notifier->m_timer.stop();
+=======
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
notifier->m_successCallback->handleEvent(position);
}
}
@@ -475,15 +548,29 @@ void Geolocation::stopTimers()
void Geolocation::handleError(PositionError* error)
{
ASSERT(error);
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
+=======
+
+ Vector<RefPtr<GeoNotifier> > oneShotsCopy;
+ copyToVector(m_oneShots, oneShotsCopy);
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
Vector<RefPtr<GeoNotifier> > oneShotsCopy;
copyToVector(m_oneShots, oneShotsCopy);
+=======
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
Vector<RefPtr<GeoNotifier> > watchersCopy;
copyValuesToVector(m_watchers, watchersCopy);
// Clear the lists before we make the callbacks, to avoid clearing notifiers
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
// added by calls to Geolocation methods from the callbacks.
+=======
+ // added by calls to Geolocation methods from the callbacks, and to prevent
+ // further callbacks to these notifiers.
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
m_oneShots.clear();
if (error->isFatal())
m_watchers.clear();
@@ -515,17 +602,32 @@ void Geolocation::requestPermission()
void Geolocation::geolocationServicePositionChanged(GeolocationService*)
{
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
+=======
+ ASSERT_UNUSED(service, service == m_service);
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
ASSERT(m_service->lastPosition());
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
m_cachedPositionManager->setCachedPosition(m_service->lastPosition());
+=======
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
// Stop all currently running timers.
stopTimers();
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
+=======
+
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
if (!isAllowed()) {
// requestPermission() will ask the chrome for permission. This may be
// implemented synchronously or asynchronously. In both cases,
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
// makeSucessCallbacks() will be called if permission is granted, so
+=======
+ // makeSuccessCallbacks() will be called if permission is granted, so
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
// there's nothing more to do here.
requestPermission();
return;
@@ -538,15 +640,32 @@ void Geolocation::makeSuccessCallbacks()
{
ASSERT(m_service->lastPosition());
ASSERT(isAllowed());
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
+=======
+
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
Vector<RefPtr<GeoNotifier> > oneShotsCopy;
copyToVector(m_oneShots, oneShotsCopy);
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
+=======
+
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
Vector<RefPtr<GeoNotifier> > watchersCopy;
copyValuesToVector(m_watchers, watchersCopy);
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
+=======
+
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
// Clear the lists before we make the callbacks, to avoid clearing notifiers
+<<<<<<< HEAD:WebCore/page/Geolocation.cpp
// added by calls to Geolocation methods from the callbacks.
+=======
+ // added by calls to Geolocation methods from the callbacks, and to prevent
+ // further callbacks to these notifiers.
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.cpp
m_oneShots.clear();
sendPosition(oneShotsCopy, m_service->lastPosition());
diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h
index 9b3b43f..5b3d156 100644
--- a/WebCore/page/Geolocation.h
+++ b/WebCore/page/Geolocation.h
@@ -82,8 +82,12 @@ private:
public:
static PassRefPtr<GeoNotifier> create(Geolocation* geolocation, PassRefPtr<PositionCallback> positionCallback, PassRefPtr<PositionErrorCallback> positionErrorCallback, PassRefPtr<PositionOptions> options) { return adoptRef(new GeoNotifier(geolocation, positionCallback, positionErrorCallback, options)); }
+<<<<<<< HEAD:WebCore/page/Geolocation.h
void setFatalError(PassRefPtr<PositionError> error);
void setCachedPosition(Geoposition* cachedPosition);
+=======
+ bool hasZeroTimeout() const;
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.h
void startTimerIfNeeded();
void timerFired(Timer<GeoNotifier>*);
@@ -96,14 +100,22 @@ private:
RefPtr<Geoposition> m_cachedPosition;
private:
+<<<<<<< HEAD:WebCore/page/Geolocation.h
GeoNotifier(Geolocation* geolocation, PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
+=======
+ GeoNotifier(Geolocation*, PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.h
};
bool hasListeners() const { return !m_oneShots.isEmpty() || !m_watchers.isEmpty(); }
void sendError(Vector<RefPtr<GeoNotifier> >&, PositionError*);
void sendPosition(Vector<RefPtr<GeoNotifier> >&, Geoposition*);
+<<<<<<< HEAD:WebCore/page/Geolocation.h
+=======
+
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.h
static void stopTimer(Vector<RefPtr<GeoNotifier> >&);
void stopTimersForOneShots();
void stopTimersForWatchers();
@@ -119,13 +131,20 @@ private:
virtual void geolocationServicePositionChanged(GeolocationService*);
virtual void geolocationServiceErrorOccurred(GeolocationService*);
+<<<<<<< HEAD:WebCore/page/Geolocation.h
// EventListener
virtual void handleEvent(Event*, bool isWindowEvent);
+=======
+<<<<<<< HEAD:WebCore/page/Geolocation.h
+>>>>>>> Merge webkit.org at R49305 : Automatic merge by git.:WebCore/page/Geolocation.h
void fatalErrorOccurred(GeoNotifier* notifier);
void requestTimedOut(GeoNotifier* notifier);
void requestReturnedCachedPosition(GeoNotifier* notifier);
bool haveSuitableCachedPosition(PositionOptions*);
+=======
+ void requestTimedOut(GeoNotifier*);
+>>>>>>> webkit.org at 49305:WebCore/page/Geolocation.h
typedef HashSet<RefPtr<GeoNotifier> > GeoNotifierSet;
typedef HashMap<int, RefPtr<GeoNotifier> > GeoNotifierMap;
diff --git a/WebCore/page/HaltablePlugin.h b/WebCore/page/HaltablePlugin.h
new file mode 100644
index 0000000..a5fe0f4
--- /dev/null
+++ b/WebCore/page/HaltablePlugin.h
@@ -0,0 +1,44 @@
+/*
+ * 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. ``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
+ * 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 HaltablePlugin_h
+#define HaltablePlugin_h
+
+namespace WebCore {
+
+class Node;
+
+class HaltablePlugin {
+public:
+ virtual ~HaltablePlugin() { }
+
+ virtual void halt() = 0;
+ virtual void restart() = 0;
+ virtual Node* node() const = 0;
+};
+
+} // namespace WebCore
+
+#endif // HaltablePlugin_h
diff --git a/WebCore/page/History.cpp b/WebCore/page/History.cpp
index 2527132..9a27f1c 100644
--- a/WebCore/page/History.cpp
+++ b/WebCore/page/History.cpp
@@ -50,28 +50,30 @@ unsigned History::length() const
{
if (!m_frame)
return 0;
- return m_frame->loader()->getHistoryLength();
+ if (!m_frame->page())
+ return 0;
+ return m_frame->page()->getHistoryLength();
}
void History::back()
{
if (!m_frame)
return;
- m_frame->loader()->scheduleHistoryNavigation(-1);
+ m_frame->redirectScheduler()->scheduleHistoryNavigation(-1);
}
void History::forward()
{
if (!m_frame)
return;
- m_frame->loader()->scheduleHistoryNavigation(1);
+ m_frame->redirectScheduler()->scheduleHistoryNavigation(1);
}
void History::go(int distance)
{
if (!m_frame)
return;
- m_frame->loader()->scheduleHistoryNavigation(distance);
+ m_frame->redirectScheduler()->scheduleHistoryNavigation(distance);
}
} // namespace WebCore
diff --git a/WebCore/page/Navigator.cpp b/WebCore/page/Navigator.cpp
index 3603b86..4922860 100644
--- a/WebCore/page/Navigator.cpp
+++ b/WebCore/page/Navigator.cpp
@@ -31,11 +31,13 @@
#include "Language.h"
#include "MimeTypeArray.h"
#include "Page.h"
+#include "PageGroup.h"
#include "PlatformString.h"
#include "PluginArray.h"
#include "PluginData.h"
#include "ScriptController.h"
#include "Settings.h"
+#include "StorageNamespace.h"
namespace WebCore {
@@ -150,5 +152,21 @@ Geolocation* Navigator::geolocation() const
m_geolocation = Geolocation::create(m_frame);
return m_geolocation.get();
}
-
+
+#if ENABLE(DOM_STORAGE)
+void Navigator::getStorageUpdates()
+{
+ if (!m_frame)
+ return;
+
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
+ StorageNamespace* localStorage = page->group().localStorage();
+ if (localStorage)
+ localStorage->unlock();
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/page/Navigator.h b/WebCore/page/Navigator.h
index d50721e..4adebe1 100644
--- a/WebCore/page/Navigator.h
+++ b/WebCore/page/Navigator.h
@@ -55,6 +55,11 @@ namespace WebCore {
// This is used for GC marking.
Geolocation* optionalGeolocation() const { return m_geolocation.get(); }
+#if ENABLE(DOM_STORAGE)
+ // Relinquishes the storage lock, if one exists.
+ void getStorageUpdates();
+#endif
+
private:
Navigator(Frame*);
Frame* m_frame;
diff --git a/WebCore/page/Navigator.idl b/WebCore/page/Navigator.idl
index 8048ff3..80ef4fb 100644
--- a/WebCore/page/Navigator.idl
+++ b/WebCore/page/Navigator.idl
@@ -42,6 +42,10 @@ module window {
#if defined(ENABLE_GEOLOCATION) && ENABLE_GEOLOCATION
readonly attribute Geolocation geolocation;
#endif
+
+#if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE
+ void getStorageUpdates();
+#endif
};
}
diff --git a/WebCore/page/OriginAccessEntry.cpp b/WebCore/page/OriginAccessEntry.cpp
new file mode 100644
index 0000000..98c280c
--- /dev/null
+++ b/WebCore/page/OriginAccessEntry.cpp
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "OriginAccessEntry.h"
+
+#include "SecurityOrigin.h"
+
+namespace WebCore {
+
+OriginAccessEntry::OriginAccessEntry(const String& protocol, const String& host, SubdomainSetting subdomainSetting)
+ : m_protocol(protocol.lower())
+ , m_host(host.lower())
+ , m_subdomainSettings(subdomainSetting)
+{
+ ASSERT(m_protocol == "http" || m_protocol == "https");
+ ASSERT(subdomainSetting == AllowSubdomains || subdomainSetting == DisallowSubdomains);
+
+ // Assume that any host that ends with a digit is trying to be an IP address.
+ m_hostIsIPAddress = !m_host.isEmpty() && isASCIIDigit(m_host[m_host.length() - 1]);
+}
+
+bool OriginAccessEntry::matchesOrigin(const SecurityOrigin& origin) const
+{
+ ASSERT(origin.host() == origin.host().lower());
+ ASSERT(origin.protocol() == origin.protocol().lower());
+
+ if (m_protocol != origin.protocol())
+ return false;
+
+ // Special case: Include subdomains and empty host means "all hosts, including ip addresses".
+ if (m_subdomainSettings == AllowSubdomains && m_host.isEmpty())
+ return true;
+
+ // Exact match.
+ if (m_host == origin.host())
+ return true;
+
+ // Otherwise we can only match if we're matching subdomains.
+ if (m_subdomainSettings == DisallowSubdomains)
+ return false;
+
+ // Don't try to do subdomain matching on IP addresses.
+ if (m_hostIsIPAddress)
+ return false;
+
+ // Match subdomains.
+ if (origin.host().length() > m_host.length() && origin.host()[origin.host().length() - m_host.length() - 1] == '.' && origin.host().endsWith(m_host))
+ return true;
+
+ return false;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/OriginAccessEntry.h b/WebCore/page/OriginAccessEntry.h
new file mode 100644
index 0000000..767d75f
--- /dev/null
+++ b/WebCore/page/OriginAccessEntry.h
@@ -0,0 +1,61 @@
+/*
+ * 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 CrossOriginAccess_h
+#define CrossOriginAccess_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class SecurityOrigin;
+
+class OriginAccessEntry {
+public:
+ enum SubdomainSetting {
+ AllowSubdomains,
+ DisallowSubdomains
+ };
+
+ // If host is empty string and SubdomainSetting is AllowSubdomains, the entry will match all domains in the specified protocol.
+ OriginAccessEntry(const String& protocol, const String& host, SubdomainSetting);
+ bool matchesOrigin(const SecurityOrigin&) const;
+
+private:
+ String m_protocol;
+ String m_host;
+ SubdomainSetting m_subdomainSettings;
+ bool m_hostIsIPAddress;
+
+};
+
+} // namespace WebCore
+
+#endif // CrossOriginAccess_h
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index a13496b..397cb72 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "Page.h"
+#include "Base64.h"
#include "CSSStyleSelector.h"
#include "Chrome.h"
#include "ChromeClient.h"
@@ -28,8 +29,10 @@
#include "ContextMenuController.h"
#include "DOMWindow.h"
#include "DragController.h"
+#include "ExceptionCode.h"
#include "EditorClient.h"
#include "EventNames.h"
+#include "Event.h"
#include "FileSystem.h"
#include "FocusController.h"
#include "Frame.h"
@@ -40,11 +43,13 @@
#include "HTMLElement.h"
#include "HistoryItem.h"
#include "InspectorController.h"
+#include "InspectorTimelineAgent.h"
#include "Logging.h"
#include "Navigator.h"
#include "NetworkStateNotifier.h"
#include "PageGroup.h"
#include "PluginData.h"
+#include "PluginHalter.h"
#include "ProgressTracker.h"
#include "RenderWidget.h"
#include "RenderTheme.h"
@@ -92,22 +97,29 @@ static void networkStateChanged()
AtomicString eventName = networkStateNotifier().onLine() ? eventNames().onlineEvent : eventNames().offlineEvent;
for (unsigned i = 0; i < frames.size(); i++)
- frames[i]->document()->dispatchWindowEvent(eventName, false, false);
+ frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false));
}
-Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient, DragClient* dragClient, InspectorClient* inspectorClient)
+Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, EditorClient* editorClient, DragClient* dragClient, InspectorClient* inspectorClient, PluginHalterClient* pluginHalterClient)
: m_chrome(new Chrome(this, chromeClient))
, m_dragCaretController(new SelectionController(0, true))
+#if ENABLE(DRAG_SUPPORT)
, m_dragController(new DragController(this, dragClient))
+#endif
, m_focusController(new FocusController(this))
+#if ENABLE(CONTEXT_MENUS)
, m_contextMenuController(new ContextMenuController(this, contextMenuClient))
+#endif
+#if ENABLE(INSPECTOR)
, m_inspectorController(new InspectorController(this, inspectorClient))
+#endif
, m_settings(new Settings(this))
, m_progress(new ProgressTracker)
, m_backForwardList(BackForwardList::create(this))
, m_theme(RenderTheme::themeForPage(this))
, m_editorClient(editorClient)
, m_frameCount(0)
+ , m_openedByDOM(false)
, m_tabKeyCyclesThroughElements(true)
, m_defersLoading(false)
, m_inLowQualityInterpolationMode(false)
@@ -115,7 +127,9 @@ 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)
@@ -123,7 +137,17 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
, m_customHTMLTokenizerTimeDelay(-1)
, m_customHTMLTokenizerChunkSize(-1)
, m_canStartPlugins(true)
+ , m_pluginHalterClient(pluginHalterClient)
{
+#if !ENABLE(CONTEXT_MENUS)
+ UNUSED_PARAM(contextMenuClient);
+#endif
+#if !ENABLE(DRAG_SUPPORT)
+ UNUSED_PARAM(dragClient);
+#endif
+#if !ENABLE(INSPECTOR)
+ UNUSED_PARAM(inspectorClient);
+#endif
if (!allPages) {
allPages = new HashSet<Page*>;
@@ -133,6 +157,8 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
ASSERT(!allPages->contains(this));
allPages->add(this);
+ pluginHalterEnabledStateChanged();
+
#if ENABLE(JAVASCRIPT_DEBUGGER)
JavaScriptDebugServer::shared().pageCreated(this);
#endif
@@ -152,9 +178,11 @@ Page::~Page()
frame->pageDestroyed();
m_editorClient->pageDestroyed();
+#if ENABLE(INSPECTOR)
if (m_parentInspectorController)
m_parentInspectorController->pageDestroyed();
m_inspectorController->inspectedPageDestroyed();
+#endif
m_backForwardList->close();
@@ -174,6 +202,16 @@ void Page::setMainFrame(PassRefPtr<Frame> mainFrame)
m_mainFrame = mainFrame;
}
+bool Page::openedByDOM() const
+{
+ return m_openedByDOM;
+}
+
+void Page::setOpenedByDOM()
+{
+ m_openedByDOM = true;
+}
+
BackForwardList* Page::backForwardList()
{
return m_backForwardList.get();
@@ -201,6 +239,40 @@ bool Page::goForward()
return false;
}
+bool Page::canGoBackOrForward(int distance) const
+{
+ if (distance == 0)
+ return true;
+ if (distance > 0 && distance <= m_backForwardList->forwardListCount())
+ return true;
+ if (distance < 0 && -distance <= m_backForwardList->backListCount())
+ return true;
+ return false;
+}
+
+void Page::goBackOrForward(int distance)
+{
+ if (distance == 0)
+ return;
+
+ HistoryItem* item = m_backForwardList->itemAtIndex(distance);
+ if (!item) {
+ if (distance > 0) {
+ int forwardListCount = m_backForwardList->forwardListCount();
+ if (forwardListCount > 0)
+ item = m_backForwardList->itemAtIndex(forwardListCount);
+ } else {
+ int backListCount = m_backForwardList->backListCount();
+ if (backListCount > 0)
+ item = m_backForwardList->itemAtIndex(-backListCount);
+ }
+ }
+
+ ASSERT(item); // we should not reach this line with an empty back/forward list
+ if (item)
+ goToItem(item, FrameLoadTypeIndexedBackForward);
+}
+
void Page::goToItem(HistoryItem* item, FrameLoadType type)
{
// Abort any current load if we're going to a history item
@@ -220,6 +292,11 @@ void Page::goToItem(HistoryItem* item, FrameLoadType type)
m_mainFrame->loader()->goToItem(item, type);
}
+int Page::getHistoryLength()
+{
+ return m_backForwardList->backListCount() + 1;
+}
+
void Page::setGlobalHistoryItem(HistoryItem* item)
{
m_globalHistoryItem = item;
@@ -439,26 +516,43 @@ void Page::willMoveOffscreen()
void Page::userStyleSheetLocationChanged()
{
-#if !FRAME_LOADS_USER_STYLESHEET
- // FIXME: We should provide a way to load other types of URLs than just
- // file: (e.g., http:, data:).
- if (m_settings->userStyleSheetLocation().isLocalFile())
- m_userStyleSheetPath = m_settings->userStyleSheetLocation().fileSystemPath();
+ // FIXME: Eventually we will move to a model of just being handed the sheet
+ // text instead of loading the URL ourselves.
+ KURL url = m_settings->userStyleSheetLocation();
+ if (url.isLocalFile())
+ m_userStyleSheetPath = url.fileSystemPath();
else
m_userStyleSheetPath = String();
m_didLoadUserStyleSheet = false;
m_userStyleSheet = String();
m_userStyleSheetModificationTime = 0;
-#endif
+
+ // Data URLs with base64-encoded UTF-8 style sheets are common. We can process them
+ // synchronously and avoid using a loader.
+ if (url.protocolIs("data") && url.string().startsWith("data:text/css;charset=utf-8;base64,")) {
+ m_didLoadUserStyleSheet = true;
+
+ const unsigned prefixLength = 35;
+ Vector<char> encodedData(url.string().length() - prefixLength);
+ for (unsigned i = prefixLength; i < url.string().length(); ++i)
+ encodedData[i - prefixLength] = static_cast<char>(url.string()[i]);
+
+ Vector<char> styleSheetAsUTF8;
+ if (base64Decode(encodedData, styleSheetAsUTF8))
+ m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data());
+ }
+
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ if (frame->document())
+ frame->document()->clearPageUserSheet();
+ }
}
const String& Page::userStyleSheet() const
{
- if (m_userStyleSheetPath.isEmpty()) {
- ASSERT(m_userStyleSheet.isEmpty());
+ if (m_userStyleSheetPath.isEmpty())
return m_userStyleSheet;
- }
time_t modTime;
if (!getFileModificationTime(m_userStyleSheetPath, modTime)) {
@@ -632,4 +726,39 @@ bool Page::javaScriptURLsAreAllowed() const
return m_javaScriptURLsAreAllowed;
}
+#if ENABLE(INSPECTOR)
+InspectorTimelineAgent* Page::inspectorTimelineAgent() const
+{
+ return m_inspectorController->timelineAgent();
+}
+#endif
+
+void Page::pluginHalterEnabledStateChanged()
+{
+ if (m_settings->pluginHalterEnabled()) {
+ ASSERT(!m_pluginHalter);
+ m_pluginHalter.set(new PluginHalter(m_pluginHalterClient));
+ m_pluginHalter->setPluginAllowedRunTime(m_settings->pluginAllowedRunTime());
+ } else
+ m_pluginHalter = 0;
+}
+
+void Page::pluginAllowedRunTimeChanged()
+{
+ if (m_pluginHalter)
+ m_pluginHalter->setPluginAllowedRunTime(m_settings->pluginAllowedRunTime());
+}
+
+void Page::didStartPlugin(HaltablePlugin* obj)
+{
+ if (m_pluginHalter)
+ m_pluginHalter->didStartPlugin(obj);
+}
+
+void Page::didStopPlugin(HaltablePlugin* obj)
+{
+ if (m_pluginHalter)
+ m_pluginHalter->didStopPlugin(obj);
+}
+
} // namespace WebCore
diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h
index 9d9af86..cab075e 100644
--- a/WebCore/page/Page.h
+++ b/WebCore/page/Page.h
@@ -54,11 +54,15 @@ namespace WebCore {
class EditorClient;
class FocusController;
class Frame;
+ class HaltablePlugin;
class InspectorClient;
class InspectorController;
+ class InspectorTimelineAgent;
class Node;
class PageGroup;
class PluginData;
+ class PluginHalter;
+ class PluginHalterClient;
class PluginView;
class ProgressTracker;
class RenderTheme;
@@ -71,6 +75,9 @@ namespace WebCore {
#if ENABLE(WML)
class WMLPageState;
#endif
+#if ENABLE(NOTIFICATIONS)
+ class NotificationPresenter;
+#endif
enum FindDirection { FindDirectionForward, FindDirectionBackward };
@@ -78,7 +85,7 @@ namespace WebCore {
public:
static void setNeedsReapplyStyles();
- Page(ChromeClient*, ContextMenuClient*, EditorClient*, DragClient*, InspectorClient*);
+ Page(ChromeClient*, ContextMenuClient*, EditorClient*, DragClient*, InspectorClient*, PluginHalterClient*);
~Page();
RenderTheme* theme() const { return m_theme.get(); };
@@ -96,6 +103,9 @@ namespace WebCore {
void setMainFrame(PassRefPtr<Frame>);
Frame* mainFrame() const { return m_mainFrame.get(); }
+ bool openedByDOM() const;
+ void setOpenedByDOM();
+
BackForwardList* backForwardList();
// FIXME: The following three methods don't fall under the responsibilities of the Page object
@@ -104,7 +114,10 @@ namespace WebCore {
// makes more sense when that class exists.
bool goBack();
bool goForward();
+ bool canGoBackOrForward(int distance) const;
+ void goBackOrForward(int distance);
void goToItem(HistoryItem*, FrameLoadType);
+ int getHistoryLength();
HistoryItem* globalHistoryItem() const { return m_globalHistoryItem.get(); }
void setGlobalHistoryItem(HistoryItem*);
@@ -121,15 +134,23 @@ namespace WebCore {
Chrome* chrome() const { return m_chrome.get(); }
SelectionController* dragCaretController() const { return m_dragCaretController.get(); }
+#if ENABLE(DRAG_SUPPORT)
DragController* dragController() const { return m_dragController.get(); }
+#endif
FocusController* focusController() const { return m_focusController.get(); }
+#if ENABLE(CONTEXT_MENUS)
ContextMenuController* contextMenuController() const { return m_contextMenuController.get(); }
+#endif
+#if ENABLE(INSPECTOR)
InspectorController* inspectorController() const { return m_inspectorController.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; }
@@ -169,6 +190,11 @@ namespace WebCore {
void userStyleSheetLocationChanged();
const String& userStyleSheet() const;
+ void didStartPlugin(HaltablePlugin*);
+ void didStopPlugin(HaltablePlugin*);
+ void pluginAllowedRunTimeChanged();
+ void pluginHalterEnabledStateChanged();
+
static void setDebuggerForAllPages(JSC::Debugger*);
void setDebugger(JSC::Debugger*);
JSC::Debugger* debugger() const { return m_debugger; }
@@ -207,15 +233,24 @@ namespace WebCore {
void setJavaScriptURLsAreAllowed(bool);
bool javaScriptURLsAreAllowed() const;
+#if ENABLE(INSPECTOR)
+ InspectorTimelineAgent* inspectorTimelineAgent() const;
+#endif
private:
void initGroup();
OwnPtr<Chrome> m_chrome;
OwnPtr<SelectionController> m_dragCaretController;
+#if ENABLE(DRAG_SUPPORT)
OwnPtr<DragController> m_dragController;
+#endif
OwnPtr<FocusController> m_focusController;
+#if ENABLE(CONTEXT_MENUS)
OwnPtr<ContextMenuController> m_contextMenuController;
+#endif
+#if ENABLE(INSPECTOR)
OwnPtr<InspectorController> m_inspectorController;
+#endif
OwnPtr<Settings> m_settings;
OwnPtr<ProgressTracker> m_progress;
@@ -232,6 +267,7 @@ namespace WebCore {
int m_frameCount;
String m_groupName;
+ bool m_openedByDOM;
bool m_tabKeyCyclesThroughElements;
bool m_defersLoading;
@@ -243,7 +279,9 @@ namespace WebCore {
bool m_javaScriptURLsAreAllowed;
+#if ENABLE(INSPECTOR)
InspectorController* m_parentInspectorController;
+#endif
String m_userStyleSheetPath;
mutable String m_userStyleSheet;
@@ -261,6 +299,9 @@ namespace WebCore {
bool m_canStartPlugins;
HashSet<PluginView*> m_unstartedPlugins;
+ OwnPtr<PluginHalter> m_pluginHalter;
+ PluginHalterClient* m_pluginHalterClient;
+
#if ENABLE(DOM_STORAGE)
RefPtr<StorageNamespace> m_sessionStorage;
#endif
@@ -272,6 +313,10 @@ namespace WebCore {
#if ENABLE(WML)
OwnPtr<WMLPageState> m_wmlPageState;
#endif
+
+#if ENABLE(NOTIFICATIONS)
+ NotificationPresenter* m_notificationPresenter;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/page/PageGroup.cpp b/WebCore/page/PageGroup.cpp
index 5155be1..cf6ba37 100644
--- a/WebCore/page/PageGroup.cpp
+++ b/WebCore/page/PageGroup.cpp
@@ -28,6 +28,7 @@
#include "ChromeClient.h"
#include "Document.h"
+#include "Frame.h"
#include "Page.h"
#include "Settings.h"
@@ -66,6 +67,11 @@ PageGroup::PageGroup(Page* page)
addPage(page);
}
+PageGroup::~PageGroup()
+{
+ removeAllUserContent();
+}
+
typedef HashMap<String, PageGroup*> PageGroupMap;
static PageGroupMap* pageGroups = 0;
@@ -185,12 +191,139 @@ StorageNamespace* PageGroup::localStorage()
if (!m_localStorage) {
// Need a page in this page group to query the settings for the local storage database path.
Page* page = *m_pages.begin();
- ASSERT(page);
- m_localStorage = StorageNamespace::localStorageNamespace(page->settings()->localStorageDatabasePath());
+ const String& path = page->settings()->localStorageDatabasePath();
+ unsigned quota = page->settings()->localStorageQuota();
+ m_localStorage = StorageNamespace::localStorageNamespace(path, quota);
}
return m_localStorage.get();
}
#endif
+void PageGroup::addUserScript(const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist,
+ PassOwnPtr<Vector<String> > blacklist, unsigned worldID, UserScriptInjectionTime injectionTime)
+{
+ if (worldID == UINT_MAX)
+ return;
+ OwnPtr<UserScript> userScript(new UserScript(source, url, whitelist, blacklist, worldID, injectionTime));
+ if (!m_userScripts)
+ m_userScripts.set(new UserScriptMap);
+ UserScriptVector*& scriptsInWorld = m_userScripts->add(worldID, 0).first->second;
+ if (!scriptsInWorld)
+ scriptsInWorld = new UserScriptVector;
+ scriptsInWorld->append(userScript.release());
+}
+
+void PageGroup::addUserStyleSheet(const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist,
+ PassOwnPtr<Vector<String> > blacklist, unsigned worldID)
+{
+ if (worldID == UINT_MAX)
+ return;
+ OwnPtr<UserStyleSheet> userStyleSheet(new UserStyleSheet(source, url, whitelist, blacklist, worldID));
+ if (!m_userStyleSheets)
+ m_userStyleSheets.set(new UserStyleSheetMap);
+ UserStyleSheetVector*& styleSheetsInWorld = m_userStyleSheets->add(worldID, 0).first->second;
+ if (!styleSheetsInWorld)
+ styleSheetsInWorld = new UserStyleSheetVector;
+ styleSheetsInWorld->append(userStyleSheet.release());
+
+ // Clear our cached sheets and have them just reparse.
+ HashSet<Page*>::const_iterator end = m_pages.end();
+ for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ frame->document()->clearPageGroupUserSheets();
+ }
+}
+
+void PageGroup::removeUserContentWithURLForWorld(const KURL& url, unsigned worldID)
+{
+ if (m_userScripts) {
+ UserScriptMap::iterator it = m_userScripts->find(worldID);
+ if (it != m_userScripts->end()) {
+ UserScriptVector* scripts = it->second;
+ for (int i = scripts->size() - 1; i >= 0; --i) {
+ if (scripts->at(i)->url() == url)
+ scripts->remove(i);
+ }
+
+ if (scripts->isEmpty()) {
+ delete it->second;
+ m_userScripts->remove(it);
+ }
+ }
+ }
+
+ if (m_userStyleSheets) {
+ UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID);
+ bool sheetsChanged = false;
+ if (it != m_userStyleSheets->end()) {
+ UserStyleSheetVector* stylesheets = it->second;
+ for (int i = stylesheets->size() - 1; i >= 0; --i) {
+ if (stylesheets->at(i)->url() == url) {
+ stylesheets->remove(i);
+ sheetsChanged = true;
+ }
+ }
+
+ if (stylesheets->isEmpty()) {
+ delete it->second;
+ m_userStyleSheets->remove(it);
+ }
+ }
+
+ // Clear our cached sheets and have them just reparse.
+ if (sheetsChanged) {
+ HashSet<Page*>::const_iterator end = m_pages.end();
+ for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ frame->document()->clearPageGroupUserSheets();
+ }
+ }
+ }
+}
+
+void PageGroup::removeUserContentForWorld(unsigned worldID)
+{
+ if (m_userScripts) {
+ UserScriptMap::iterator it = m_userScripts->find(worldID);
+ if (it != m_userScripts->end()) {
+ delete it->second;
+ m_userScripts->remove(it);
+ }
+ }
+
+ if (m_userStyleSheets) {
+ bool sheetsChanged = false;
+ UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID);
+ if (it != m_userStyleSheets->end()) {
+ delete it->second;
+ m_userStyleSheets->remove(it);
+ sheetsChanged = true;
+ }
+
+ if (sheetsChanged) {
+ // Clear our cached sheets and have them just reparse.
+ HashSet<Page*>::const_iterator end = m_pages.end();
+ for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext())
+ frame->document()->clearPageGroupUserSheets();
+ }
+ }
+ }
+}
+
+void PageGroup::removeAllUserContent()
+{
+ if (m_userScripts) {
+ deleteAllValues(*m_userScripts);
+ m_userScripts.clear();
+ }
+
+
+ if (m_userStyleSheets) {
+ deleteAllValues(*m_userStyleSheets);
+ m_userStyleSheets.clear();
+ }
+}
+
} // namespace WebCore
diff --git a/WebCore/page/PageGroup.h b/WebCore/page/PageGroup.h
index f92c2e6..7ea2967 100644
--- a/WebCore/page/PageGroup.h
+++ b/WebCore/page/PageGroup.h
@@ -30,6 +30,8 @@
#include <wtf/Noncopyable.h>
#include "LinkHash.h"
#include "StringHash.h"
+#include "UserScript.h"
+#include "UserStyleSheet.h"
namespace WebCore {
@@ -41,6 +43,7 @@ namespace WebCore {
public:
PageGroup(const String& name);
PageGroup(Page*);
+ ~PageGroup();
static PageGroup* pageGroup(const String& groupName);
static void closeLocalStorage();
@@ -64,13 +67,26 @@ namespace WebCore {
#if ENABLE(DOM_STORAGE)
StorageNamespace* localStorage();
+ bool hasLocalStorage() { return m_localStorage; }
#endif
+ void addUserScript(const String& source, const KURL&,
+ PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist,
+ unsigned worldID, UserScriptInjectionTime);
+ const UserScriptMap* userScripts() const { return m_userScripts.get(); }
+
+ void addUserStyleSheet(const String& source, const KURL&,
+ PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist,
+ unsigned worldID);
+ const UserStyleSheetMap* userStyleSheets() const { return m_userStyleSheets.get(); }
+
+ void removeUserContentForWorld(unsigned);
+ void removeUserContentWithURLForWorld(const KURL&, unsigned);
+ void removeAllUserContent();
+
private:
void addVisitedLink(LinkHash stringHash);
-#if ENABLE(DOM_STORAGE)
- bool hasLocalStorage() { return m_localStorage; }
-#endif
+
String m_name;
HashSet<Page*> m_pages;
@@ -82,6 +98,9 @@ namespace WebCore {
#if ENABLE(DOM_STORAGE)
RefPtr<StorageNamespace> m_localStorage;
#endif
+
+ OwnPtr<UserScriptMap> m_userScripts;
+ OwnPtr<UserStyleSheetMap> m_userStyleSheets;
};
} // namespace WebCore
diff --git a/WebCore/page/PageGroupLoadDeferrer.cpp b/WebCore/page/PageGroupLoadDeferrer.cpp
index f274de3..122658b 100644
--- a/WebCore/page/PageGroupLoadDeferrer.cpp
+++ b/WebCore/page/PageGroupLoadDeferrer.cpp
@@ -41,10 +41,10 @@ PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
if (!otherPage->defersLoading())
m_deferredFrames.append(otherPage->mainFrame());
-#if !PLATFORM(MAC)
+ // This code is not logically part of load deferring, but we do not want JS code executed beneath modal
+ // windows or sheets, which is exactly when PageGroupLoadDeferrer is used.
for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree()->traverseNext())
frame->document()->suspendActiveDOMObjects();
-#endif
}
}
@@ -60,10 +60,8 @@ PageGroupLoadDeferrer::~PageGroupLoadDeferrer()
if (Page* page = m_deferredFrames[i]->page()) {
page->setDefersLoading(false);
-#if !PLATFORM(MAC)
for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext())
frame->document()->resumeActiveDOMObjects();
-#endif
}
}
}
diff --git a/WebCore/page/PluginHalter.cpp b/WebCore/page/PluginHalter.cpp
new file mode 100644
index 0000000..8025337
--- /dev/null
+++ b/WebCore/page/PluginHalter.cpp
@@ -0,0 +1,112 @@
+/*
+ * 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. ``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
+ * 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 "PluginHalter.h"
+
+#include "HaltablePlugin.h"
+#include "PluginHalterClient.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/Vector.h>
+
+using namespace std;
+
+namespace WebCore {
+
+PluginHalter::PluginHalter(PluginHalterClient* client)
+ : m_client(client)
+ , m_timer(this, &PluginHalter::timerFired)
+ , m_pluginAllowedRunTime(numeric_limits<unsigned>::max())
+{
+ ASSERT_ARG(client, client);
+}
+
+void PluginHalter::didStartPlugin(HaltablePlugin* obj)
+{
+ ASSERT_ARG(obj, obj);
+ ASSERT_ARG(obj, !m_plugins.contains(obj));
+
+ double currentTime = WTF::currentTime();
+
+ m_plugins.add(obj, currentTime);
+
+ if (m_plugins.size() == 1)
+ m_oldestStartTime = currentTime;
+
+ startTimerIfNecessary();
+}
+
+void PluginHalter::didStopPlugin(HaltablePlugin* obj)
+{
+ m_plugins.remove(obj);
+}
+
+void PluginHalter::timerFired(Timer<PluginHalter>*)
+{
+ if (m_plugins.isEmpty())
+ return;
+
+ Vector<HaltablePlugin*> plugins;
+ copyKeysToVector(m_plugins, plugins);
+
+ // Plug-ins older than this are candidates to be halted.
+ double pluginCutOffTime = WTF::currentTime() - m_pluginAllowedRunTime;
+
+ m_oldestStartTime = numeric_limits<double>::max();
+
+ for (size_t i = 0; i < plugins.size(); ++i) {
+ double thisStartTime = m_plugins.get(plugins[i]);
+ if (thisStartTime > pluginCutOffTime) {
+ // This plug-in is too young to be halted. We find the oldest
+ // plug-in that is not old enough to be halted and use it to set
+ // the timer's next fire time.
+ if (thisStartTime < m_oldestStartTime)
+ m_oldestStartTime = thisStartTime;
+ continue;
+ }
+
+ if (m_client->shouldHaltPlugin(plugins[i]->node()))
+ plugins[i]->halt();
+
+ m_plugins.remove(plugins[i]);
+ }
+
+ startTimerIfNecessary();
+}
+
+void PluginHalter::startTimerIfNecessary()
+{
+ if (m_timer.isActive())
+ return;
+
+ if (m_plugins.isEmpty())
+ return;
+
+ double nextFireInterval = static_cast<double>(m_pluginAllowedRunTime) - (currentTime() - m_oldestStartTime);
+ m_timer.startOneShot(nextFireInterval < 0 ? 0 : nextFireInterval);
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/PluginHalter.h b/WebCore/page/PluginHalter.h
new file mode 100644
index 0000000..26f5101
--- /dev/null
+++ b/WebCore/page/PluginHalter.h
@@ -0,0 +1,59 @@
+/*
+ * 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. ``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
+ * 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 PluginHalter_h
+#define PluginHalter_h
+
+#include "Timer.h"
+#include <wtf/HashMap.h>
+
+namespace WebCore {
+
+class HaltablePlugin;
+class PluginHalterClient;
+
+class PluginHalter {
+public:
+ PluginHalter(PluginHalterClient*);
+
+ void didStartPlugin(HaltablePlugin*);
+ void didStopPlugin(HaltablePlugin*);
+
+ void setPluginAllowedRunTime(unsigned runTime) { m_pluginAllowedRunTime = runTime; }
+
+private:
+ void timerFired(Timer<PluginHalter>*);
+ void startTimerIfNecessary();
+
+ PluginHalterClient* m_client;
+ Timer<PluginHalter> m_timer;
+ unsigned m_pluginAllowedRunTime;
+ double m_oldestStartTime;
+ HashMap<HaltablePlugin*, double> m_plugins;
+};
+
+} // namespace WebCore
+
+#endif // PluginHalter_h
diff --git a/WebCore/page/PluginHalterClient.h b/WebCore/page/PluginHalterClient.h
new file mode 100644
index 0000000..7ea460a
--- /dev/null
+++ b/WebCore/page/PluginHalterClient.h
@@ -0,0 +1,42 @@
+/*
+ * 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. ``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
+ * 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 PluginHalterClient_h
+#define PluginHalterClient_h
+
+namespace WebCore {
+
+class Node;
+
+class PluginHalterClient {
+public:
+ virtual ~PluginHalterClient() { }
+
+ virtual bool shouldHaltPlugin(Node*) const = 0;
+};
+
+} // namespace WebCore
+
+#endif // PluginHalterClient_h
diff --git a/WebCore/page/PositionCallback.h b/WebCore/page/PositionCallback.h
index f6bf139..30da2c1 100644
--- a/WebCore/page/PositionCallback.h
+++ b/WebCore/page/PositionCallback.h
@@ -36,7 +36,11 @@ namespace WebCore {
class PositionCallback : public RefCounted<PositionCallback> {
public:
virtual ~PositionCallback() { }
+<<<<<<< HEAD:WebCore/page/PositionCallback.h
virtual void handleEvent(Geoposition* position) = 0;
+=======
+ virtual void handleEvent(Geoposition*) = 0;
+>>>>>>> webkit.org at 49305:WebCore/page/PositionCallback.h
};
} // namespace WebCore
diff --git a/WebCore/page/PositionError.h b/WebCore/page/PositionError.h
index c309061..5c26fcc 100644
--- a/WebCore/page/PositionError.h
+++ b/WebCore/page/PositionError.h
@@ -46,7 +46,11 @@ public:
ErrorCode code() const { return m_code; }
const String& message() const { return m_message; }
void setIsFatal(bool isFatal) { m_isFatal = isFatal; }
+<<<<<<< HEAD:WebCore/page/PositionError.h
bool isFatal() { return m_isFatal; }
+=======
+ bool isFatal() const { return m_isFatal; }
+>>>>>>> webkit.org at 49305:WebCore/page/PositionError.h
private:
PositionError(ErrorCode code, const String& message)
diff --git a/WebCore/page/PositionOptions.h b/WebCore/page/PositionOptions.h
index 5900998..b1746a8 100644
--- a/WebCore/page/PositionOptions.h
+++ b/WebCore/page/PositionOptions.h
@@ -33,7 +33,11 @@ namespace WebCore {
class PositionOptions : public RefCounted<PositionOptions> {
public:
+<<<<<<< HEAD:WebCore/page/PositionOptions.h
static PassRefPtr<PositionOptions> create() { return adoptRef(new PositionOptions); }
+=======
+ static PassRefPtr<PositionOptions> create() { return adoptRef(new PositionOptions()); }
+>>>>>>> webkit.org at 49305:WebCore/page/PositionOptions.h
bool enableHighAccuracy() const { return m_highAccuracy; }
void setEnableHighAccuracy(bool enable) { m_highAccuracy = enable; }
diff --git a/WebCore/page/PrintContext.cpp b/WebCore/page/PrintContext.cpp
index b855ca5..4d3a839 100644
--- a/WebCore/page/PrintContext.cpp
+++ b/WebCore/page/PrintContext.cpp
@@ -67,7 +67,7 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig
float ratio = printRect.height() / printRect.width();
- float pageWidth = (float)root->overflowWidth();
+ float pageWidth = (float)root->rightLayoutOverflow();
float pageHeight = pageWidth * ratio;
outPageHeight = pageHeight; // this is the height of the page adjusted by margins
pageHeight -= headerHeight + footerHeight;
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
index 14a1b59..338bf9f 100644
--- a/WebCore/page/SecurityOrigin.cpp
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -30,16 +30,23 @@
#include "SecurityOrigin.h"
#include "CString.h"
-#include "FrameLoader.h"
+#include "Document.h"
#include "KURL.h"
-#include "PlatformString.h"
-#include "StringHash.h"
-#include <wtf/HashSet.h>
+#include "OriginAccessEntry.h"
#include <wtf/StdLibExtras.h>
namespace WebCore {
-typedef HashSet<String, CaseFoldingHash> URLSchemesMap;
+static SecurityOrigin::LocalLoadPolicy localLoadPolicy = SecurityOrigin::AllowLocalLoadsForLocalOnly;
+
+typedef Vector<OriginAccessEntry> OriginAccessWhiteList;
+typedef HashMap<String, OriginAccessWhiteList*> OriginAccessMap;
+
+static OriginAccessMap& originAccessMap()
+{
+ DEFINE_STATIC_LOCAL(OriginAccessMap, originAccessMap, ());
+ return originAccessMap;
+}
static URLSchemesMap& localSchemes()
{
@@ -68,7 +75,7 @@ static URLSchemesMap& noAccessSchemes()
return noAccessSchemes;
}
-static bool isDefaultPortForProtocol(unsigned short port, const String& protocol)
+bool SecurityOrigin::isDefaultPortForProtocol(unsigned short port, const String& protocol)
{
if (protocol.isEmpty())
return false;
@@ -111,9 +118,9 @@ SecurityOrigin::SecurityOrigin(const KURL& url)
}
SecurityOrigin::SecurityOrigin(const SecurityOrigin* other)
- : m_protocol(other->m_protocol.copy())
- , m_host(other->m_host.copy())
- , m_domain(other->m_domain.copy())
+ : m_protocol(other->m_protocol.threadsafeCopy())
+ , m_host(other->m_host.threadsafeCopy())
+ , m_domain(other->m_domain.threadsafeCopy())
, m_port(other->m_port)
, m_noAccess(other->m_noAccess)
, m_universalAccess(other->m_universalAccess)
@@ -139,7 +146,7 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createEmpty()
return create(KURL());
}
-PassRefPtr<SecurityOrigin> SecurityOrigin::copy()
+PassRefPtr<SecurityOrigin> SecurityOrigin::threadsafeCopy()
{
return adoptRef(new SecurityOrigin(this));
}
@@ -203,7 +210,47 @@ bool SecurityOrigin::canRequest(const KURL& url) const
// We call isSameSchemeHostPort here instead of canAccess because we want
// to ignore document.domain effects.
- return isSameSchemeHostPort(targetOrigin.get());
+ if (isSameSchemeHostPort(targetOrigin.get()))
+ return true;
+
+ if (OriginAccessWhiteList* list = originAccessMap().get(toString())) {
+ for (size_t i = 0; i < list->size(); ++i) {
+ if (list->at(i).matchesOrigin(*targetOrigin))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+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.
+ if (url.protocolIs("data"))
+ return false;
+
+ return true;
+}
+
+bool SecurityOrigin::canLoad(const KURL& url, const String& referrer, Document* document)
+{
+ if (!shouldTreatURLAsLocal(url.string()))
+ return true;
+
+ // If we were provided a document, we let its local file policy dictate the result,
+ // otherwise we allow local loads only if the supplied referrer is also local.
+ if (document)
+ return document->securityOrigin()->canLoadLocalResources();
+ if (!referrer.isEmpty())
+ return shouldTreatURLAsLocal(referrer);
+ return false;
}
void SecurityOrigin::grantLoadLocalResources()
@@ -213,7 +260,7 @@ void SecurityOrigin::grantLoadLocalResources()
// 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.
- ASSERT(FrameLoader::allowSubstituteDataAccessToLocal());
+ ASSERT(allowSubstituteDataAccessToLocal());
m_canLoadLocalResources = true;
}
@@ -339,13 +386,31 @@ bool SecurityOrigin::isSameSchemeHostPort(const SecurityOrigin* other) const
return true;
}
-// static
void SecurityOrigin::registerURLSchemeAsLocal(const String& scheme)
{
localSchemes().add(scheme);
}
-// static
+void SecurityOrigin::removeURLSchemeRegisteredAsLocal(const String& scheme)
+{
+ if (scheme == "file")
+ return;
+#if PLATFORM(MAC)
+ if (scheme == "applewebdata")
+ return;
+#endif
+#if PLATFORM(QT)
+ if (scheme == "qrc")
+ return;
+#endif
+ localSchemes().remove(scheme);
+}
+
+const URLSchemesMap& SecurityOrigin::localURLSchemes()
+{
+ return localSchemes();
+}
+
bool SecurityOrigin::shouldTreatURLAsLocal(const String& url)
{
// This avoids an allocation of another String and the HashSet contains()
@@ -366,7 +431,6 @@ bool SecurityOrigin::shouldTreatURLAsLocal(const String& url)
return localSchemes().contains(scheme);
}
-// static
bool SecurityOrigin::shouldTreatURLSchemeAsLocal(const String& scheme)
{
// This avoids an allocation of another String and the HashSet contains()
@@ -385,16 +449,69 @@ bool SecurityOrigin::shouldTreatURLSchemeAsLocal(const String& scheme)
return localSchemes().contains(scheme);
}
-// static
void SecurityOrigin::registerURLSchemeAsNoAccess(const String& scheme)
{
noAccessSchemes().add(scheme);
}
-// static
bool SecurityOrigin::shouldTreatURLSchemeAsNoAccess(const String& scheme)
{
return noAccessSchemes().contains(scheme);
}
+bool SecurityOrigin::shouldHideReferrer(const KURL& url, const String& referrer)
+{
+ bool referrerIsSecureURL = protocolIs(referrer, "https");
+ bool referrerIsWebURL = referrerIsSecureURL || protocolIs(referrer, "http");
+
+ if (!referrerIsWebURL)
+ return true;
+
+ if (!referrerIsSecureURL)
+ return false;
+
+ bool URLIsSecureURL = url.protocolIs("https");
+
+ return !URLIsSecureURL;
+}
+
+void SecurityOrigin::setLocalLoadPolicy(LocalLoadPolicy policy)
+{
+ localLoadPolicy = policy;
+}
+
+bool SecurityOrigin::restrictAccessToLocal()
+{
+ return localLoadPolicy != SecurityOrigin::AllowLocalLoadsForAll;
+}
+
+bool SecurityOrigin::allowSubstituteDataAccessToLocal()
+{
+ return localLoadPolicy != SecurityOrigin::AllowLocalLoadsForLocalOnly;
+}
+
+void SecurityOrigin::whiteListAccessFromOrigin(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains)
+{
+ ASSERT(isMainThread());
+ ASSERT(!sourceOrigin.isEmpty());
+ if (sourceOrigin.isEmpty())
+ return;
+
+ String sourceString = sourceOrigin.toString();
+ OriginAccessWhiteList* list = originAccessMap().get(sourceString);
+ if (!list) {
+ list = new OriginAccessWhiteList;
+ originAccessMap().set(sourceString, list);
+ }
+ list->append(OriginAccessEntry(destinationProtocol, destinationDomains, allowDestinationSubdomains ? OriginAccessEntry::AllowSubdomains : OriginAccessEntry::DisallowSubdomains));
+}
+
+void SecurityOrigin::resetOriginAccessWhiteLists()
+{
+ ASSERT(isMainThread());
+ OriginAccessMap& map = originAccessMap();
+ deleteAllValues(map);
+ map.clear();
+}
+
} // namespace WebCore
diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h
index ab92683..46e6fad 100644
--- a/WebCore/page/SecurityOrigin.h
+++ b/WebCore/page/SecurityOrigin.h
@@ -29,14 +29,19 @@
#ifndef SecurityOrigin_h
#define SecurityOrigin_h
+#include <wtf/HashSet.h>
#include <wtf/RefCounted.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Threading.h>
#include "PlatformString.h"
+#include "StringHash.h"
namespace WebCore {
+ typedef HashSet<String, CaseFoldingHash> URLSchemesMap;
+
+ class Document;
class KURL;
class SecurityOrigin : public ThreadSafeShared<SecurityOrigin> {
@@ -48,7 +53,7 @@ namespace WebCore {
// Create a deep copy of this SecurityOrigin. This method is useful
// when marshalling a SecurityOrigin to another thread.
- PassRefPtr<SecurityOrigin> copy();
+ 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
@@ -72,6 +77,16 @@ namespace WebCore {
// 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
@@ -129,12 +144,30 @@ namespace WebCore {
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*);
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index 9692707..98d08d2 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -48,6 +48,10 @@ static void setNeedsReapplyStylesInAllFrames(Page* page)
bool Settings::gShouldPaintNativeControls = true;
#endif
+#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX))
+bool Settings::gShouldUseHighResolutionTimers = true;
+#endif
+
Settings::Settings(Page* page)
: m_page(page)
#ifdef ANDROID_LAYOUT
@@ -69,6 +73,8 @@ Settings::Settings(Page* page)
, m_blockNetworkImage(false)
#endif
, m_maximumDecodedImageSize(numeric_limits<size_t>::max())
+ , m_localStorageQuota(5 * 1024 * 1024) // Suggested by the HTML5 spec.
+ , m_pluginAllowedRunTime(numeric_limits<unsigned>::max())
, m_isJavaEnabled(false)
, m_loadsImagesAutomatically(false)
, m_privateBrowsingEnabled(false)
@@ -110,7 +116,8 @@ Settings::Settings(Page* page)
, m_usesEncodingDetector(false)
, m_allowScriptsToCloseWindows(false)
, m_editingBehavior(
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN))
+ // (PLATFORM(MAC) is always false in Chromium, hence the extra condition.)
EditingMacBehavior
#else
EditingWindowsBehavior
@@ -121,6 +128,12 @@ Settings::Settings(Page* page)
, m_downloadableBinaryFontsEnabled(true)
, m_xssAuditorEnabled(false)
, m_acceleratedCompositingEnabled(true)
+ , m_experimentalNotificationsEnabled(false)
+ , m_pluginHalterEnabled(false)
+ , m_webGLEnabled(false)
+#if ENABLE(WEB_SOCKETS)
+ , m_experimentalWebSocketsEnabled(false)
+#endif
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
@@ -272,6 +285,11 @@ void Settings::setSessionStorageEnabled(bool sessionStorageEnabled)
m_sessionStorageEnabled = sessionStorageEnabled;
}
+void Settings::setLocalStorageQuota(unsigned localStorageQuota)
+{
+ m_localStorageQuota = localStorageQuota;
+}
+
void Settings::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
{
m_privateBrowsingEnabled = privateBrowsingEnabled;
@@ -295,7 +313,6 @@ void Settings::setUserStyleSheetLocation(const KURL& userStyleSheetLocation)
m_userStyleSheetLocation = userStyleSheetLocation;
m_page->userStyleSheetLocationChanged();
- setNeedsReapplyStylesInAllFrames(m_page);
}
void Settings::setShouldPrintBackgrounds(bool shouldPrintBackgrounds)
@@ -620,4 +637,44 @@ void Settings::setAcceleratedCompositingEnabled(bool enabled)
setNeedsReapplyStylesInAllFrames(m_page);
}
+void Settings::setExperimentalNotificationsEnabled(bool enabled)
+{
+ m_experimentalNotificationsEnabled = enabled;
+}
+
+void Settings::setPluginHalterEnabled(bool enabled)
+{
+ if (m_pluginHalterEnabled == enabled)
+ return;
+
+ m_pluginHalterEnabled = enabled;
+
+ m_page->pluginHalterEnabledStateChanged();
+}
+
+void Settings::setPluginAllowedRunTime(unsigned runTime)
+{
+ m_pluginAllowedRunTime = runTime;
+ m_page->pluginAllowedRunTimeChanged();
+}
+
+#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX))
+void Settings::setShouldUseHighResolutionTimers(bool shouldUseHighResolutionTimers)
+{
+ gShouldUseHighResolutionTimers = shouldUseHighResolutionTimers;
+}
+#endif
+
+void Settings::setWebGLEnabled(bool enabled)
+{
+ m_webGLEnabled = enabled;
+}
+
+#if ENABLE(WEB_SOCKETS)
+void Settings::setExperimentalWebSocketsEnabled(bool enabled)
+{
+ m_experimentalWebSocketsEnabled = enabled;
+}
+#endif
+
} // namespace WebCore
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index 162b21d..344746f 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -151,6 +151,9 @@ namespace WebCore {
void setSessionStorageEnabled(bool);
bool sessionStorageEnabled() const { return m_sessionStorageEnabled; }
+ void setLocalStorageQuota(unsigned);
+ unsigned localStorageQuota() const { return m_localStorageQuota; }
+
void setPrivateBrowsingEnabled(bool);
bool privateBrowsingEnabled() const { return m_privateBrowsingEnabled; }
@@ -295,6 +298,28 @@ namespace WebCore {
void setAcceleratedCompositingEnabled(bool);
bool acceleratedCompositingEnabled() const { return m_acceleratedCompositingEnabled; }
+ void setExperimentalNotificationsEnabled(bool);
+ bool experimentalNotificationsEnabled() const { return m_experimentalNotificationsEnabled; }
+
+#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX))
+ static void setShouldUseHighResolutionTimers(bool);
+ static bool shouldUseHighResolutionTimers() { return gShouldUseHighResolutionTimers; }
+#endif
+
+ void setPluginHalterEnabled(bool);
+ bool pluginHalterEnabled() const { return m_pluginHalterEnabled; }
+
+ void setPluginAllowedRunTime(unsigned);
+ unsigned pluginAllowedRunTime() const { return m_pluginAllowedRunTime; }
+
+ void setWebGLEnabled(bool);
+ bool webGLEnabled() const { return m_webGLEnabled; }
+
+#if ENABLE(WEB_SOCKETS)
+ void setExperimentalWebSocketsEnabled(bool);
+ bool experimentalWebSocketsEnabled() const { return m_experimentalWebSocketsEnabled; }
+#endif
+
private:
Page* m_page;
@@ -352,6 +377,8 @@ namespace WebCore {
bool m_blockNetworkImage : 1;
#endif
size_t m_maximumDecodedImageSize;
+ unsigned m_localStorageQuota;
+ unsigned m_pluginAllowedRunTime;
bool m_isJavaEnabled : 1;
bool m_loadsImagesAutomatically : 1;
bool m_privateBrowsingEnabled : 1;
@@ -396,10 +423,20 @@ namespace WebCore {
bool m_downloadableBinaryFontsEnabled : 1;
bool m_xssAuditorEnabled : 1;
bool m_acceleratedCompositingEnabled : 1;
+ bool m_experimentalNotificationsEnabled : 1;
+ bool m_pluginHalterEnabled : 1;
+ bool m_webGLEnabled : 1;
+
+#if ENABLE(WEB_SOCKETS)
+ bool m_experimentalWebSocketsEnabled : 1;
+#endif
#if USE(SAFARI_THEME)
static bool gShouldPaintNativeControls;
#endif
+#if PLATFORM(WIN) || (PLATFORM(WIN_OS) && PLATFORM(WX))
+ static bool gShouldUseHighResolutionTimers;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/page/UserContentURLPattern.cpp b/WebCore/page/UserContentURLPattern.cpp
new file mode 100644
index 0000000..5f0a311
--- /dev/null
+++ b/WebCore/page/UserContentURLPattern.cpp
@@ -0,0 +1,226 @@
+/*
+ * 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 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 "UserContentURLPattern.h"
+#include "KURL.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+bool UserContentURLPattern::matchesPatterns(const KURL& url, const Vector<String>* whitelist, const Vector<String>* blacklist)
+{
+ // In order for a URL to be a match it has to be present in the whitelist and not present in the blacklist.
+ // If there is no whitelist at all, then all URLs are assumed to be in the whitelist.
+ bool matchesWhitelist = !whitelist || whitelist->isEmpty();
+ if (!matchesWhitelist) {
+ for (unsigned i = 0; i < whitelist->size(); ++i) {
+ UserContentURLPattern contentPattern(whitelist->at(i));
+ if (contentPattern.matches(url)) {
+ matchesWhitelist = true;
+ break;
+ }
+ }
+ }
+
+ bool matchesBlacklist = false;
+ if (blacklist) {
+ for (unsigned i = 0; i < blacklist->size(); ++i) {
+ UserContentURLPattern contentPattern(blacklist->at(i));
+ if (contentPattern.matches(url)) {
+ matchesBlacklist = true;
+ break;
+ }
+ }
+ }
+
+ return matchesWhitelist && !matchesBlacklist;
+}
+
+bool UserContentURLPattern::parse(const String& pattern)
+{
+ DEFINE_STATIC_LOCAL(const String, schemeSeparator, ("://"));
+
+ int schemeEndPos = pattern.find(schemeSeparator);
+ if (schemeEndPos == -1)
+ return false;
+
+ m_scheme = pattern.left(schemeEndPos);
+
+ int hostStartPos = schemeEndPos + schemeSeparator.length();
+ if (hostStartPos >= static_cast<int>(pattern.length()))
+ return false;
+
+ int pathStartPos = 0;
+
+ if (m_scheme == "file")
+ pathStartPos = hostStartPos;
+ else {
+ int hostEndPos = pattern.find("/", hostStartPos);
+ if (hostEndPos == -1)
+ return false;
+
+ m_host = pattern.substring(hostStartPos, hostEndPos - hostStartPos);
+
+ // The first component can be '*', which means to match all subdomains.
+ Vector<String> hostComponents;
+ m_host.split(".", hostComponents);
+ if (hostComponents[0] == "*") {
+ m_matchSubdomains = true;
+ m_host = "";
+ for (unsigned i = 1; i < hostComponents.size(); ++i) {
+ m_host = m_host + hostComponents[i];
+ if (i < hostComponents.size() - 1)
+ m_host = m_host + ".";
+ }
+ }
+
+ // No other '*' can occur in the host.
+ if (m_host.find("*") != -1)
+ return false;
+
+ pathStartPos = hostEndPos;
+ }
+
+ m_path = pattern.right(pattern.length() - pathStartPos);
+
+ return true;
+}
+
+bool UserContentURLPattern::matches(const KURL& test) const
+{
+ if (m_invalid)
+ return false;
+
+ if (test.protocol() != m_scheme)
+ return false;
+
+ if (!matchesHost(test))
+ return false;
+
+ return matchesPath(test);
+}
+
+bool UserContentURLPattern::matchesHost(const KURL& test) const
+{
+ if (test.host() == m_host)
+ return true;
+
+ if (!m_matchSubdomains)
+ return false;
+
+ // If we're matching subdomains, and we have no host, that means the pattern
+ // was <scheme>://*/<whatever>, so we match anything.
+ if (!m_host.length())
+ return true;
+
+ // Check if the test host is a subdomain of our host.
+ return test.host().endsWith(m_host, false);
+}
+
+struct MatchTester
+{
+ const String m_pattern;
+ unsigned m_patternIndex;
+
+ const String m_test;
+ unsigned m_testIndex;
+
+ MatchTester(const String& pattern, const String& test)
+ : m_pattern(pattern)
+ , m_patternIndex(0)
+ , m_test(test)
+ , m_testIndex(0)
+ {
+ }
+
+ bool testStringFinished() const { return m_testIndex >= m_test.length(); }
+ bool patternStringFinished() const { return m_patternIndex >= m_pattern.length(); }
+
+ void eatWildcard()
+ {
+ while (!patternStringFinished()) {
+ if (m_pattern[m_patternIndex] != '*')
+ return;
+ m_patternIndex++;
+ }
+ }
+
+ void eatSameChars()
+ {
+ while (!patternStringFinished() && !testStringFinished()) {
+ if (m_pattern[m_patternIndex] == '*')
+ return;
+ if (m_pattern[m_patternIndex] != m_test[m_testIndex])
+ return;
+ m_patternIndex++;
+ m_testIndex++;
+ }
+ }
+
+ bool test()
+ {
+ // Eat all the matching chars.
+ eatSameChars();
+
+ // If the string is finished, then the pattern must be empty too, or contains
+ // only wildcards.
+ if (testStringFinished()) {
+ eatWildcard();
+ if (patternStringFinished())
+ return true;
+ return false;
+ }
+
+ // Pattern is empty but not string, this is not a match.
+ if (patternStringFinished())
+ return false;
+
+ // If we don't encounter a *, then we're hosed.
+ if (m_pattern[m_patternIndex] != '*')
+ return false;
+
+ while (!testStringFinished()) {
+ MatchTester nextMatch(*this);
+ nextMatch.m_patternIndex++;
+ if (nextMatch.test())
+ return true;
+ m_testIndex++;
+ }
+
+ // We reached the end of the string. Let's see if the pattern contains only
+ // wildcards.
+ eatWildcard();
+ return patternStringFinished();
+ }
+};
+
+bool UserContentURLPattern::matchesPath(const KURL& test) const
+{
+ MatchTester match(m_path, test.path());
+ return match.test();
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/UserContentURLPattern.h b/WebCore/page/UserContentURLPattern.h
new file mode 100644
index 0000000..0b1a248
--- /dev/null
+++ b/WebCore/page/UserContentURLPattern.h
@@ -0,0 +1,72 @@
+/*
+ * 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 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.
+ */
+
+#ifndef UserContentURLPattern_h
+#define UserContentURLPattern_h
+
+#include "PlatformString.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class KURL;
+
+class UserContentURLPattern {
+public:
+ UserContentURLPattern(const String& pattern)
+ : m_matchSubdomains(false)
+ {
+ m_invalid = !parse(pattern);
+ }
+
+ bool matches(const KURL&) const;
+
+ const String& scheme() const { return m_scheme; }
+ const String& host() const { return m_host; }
+ const String& path() const { return m_path; }
+
+ bool matchSubdomains() const { return m_matchSubdomains; }
+
+ static bool matchesPatterns(const KURL&, const Vector<String>* whitelist, const Vector<String>* blacklist);
+
+private:
+ bool parse(const String& pattern);
+
+ bool matchesHost(const KURL&) const;
+ bool matchesPath(const KURL&) const;
+
+ bool m_invalid;
+
+ String m_scheme;
+ String m_host;
+ String m_path;
+
+ bool m_matchSubdomains;
+};
+
+
+} // namespace WebCore
+
+#endif // UserContentURLPattern_h
diff --git a/WebCore/page/UserScript.h b/WebCore/page/UserScript.h
new file mode 100644
index 0000000..dbbb879
--- /dev/null
+++ b/WebCore/page/UserScript.h
@@ -0,0 +1,69 @@
+/*
+ * 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 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.
+ */
+
+#ifndef UserScript_h
+#define UserScript_h
+
+#include "KURL.h"
+#include "UserScriptTypes.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class UserScript {
+public:
+ UserScript(const String& source, const KURL& url,
+ PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist,
+ unsigned worldID, UserScriptInjectionTime injectionTime)
+ : m_source(source)
+ , m_url(url)
+ , m_whitelist(whitelist)
+ , m_blacklist(blacklist)
+ , m_worldID(worldID)
+ , m_injectionTime(injectionTime)
+ {
+ }
+
+ const String& source() const { return m_source; }
+ 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:
+ String m_source;
+ KURL m_url;
+ OwnPtr<Vector<String> > m_whitelist;
+ OwnPtr<Vector<String> > m_blacklist;
+ unsigned m_worldID;
+ UserScriptInjectionTime m_injectionTime;
+};
+
+} // namespace WebCore
+
+#endif // UserScript_h
diff --git a/WebCore/page/UserScriptTypes.h b/WebCore/page/UserScriptTypes.h
new file mode 100644
index 0000000..ac37662
--- /dev/null
+++ b/WebCore/page/UserScriptTypes.h
@@ -0,0 +1,43 @@
+/*
+ * 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 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.
+ */
+
+#ifndef UserScriptTypes_h
+#define UserScriptTypes_h
+
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+enum UserScriptInjectionTime { InjectAtDocumentStart, InjectAtDocumentEnd };
+
+class UserScript;
+
+typedef Vector<OwnPtr<UserScript> > UserScriptVector;
+typedef HashMap<unsigned, UserScriptVector*> UserScriptMap;
+
+} // namespace WebCore
+
+#endif // UserScriptTypes_h
diff --git a/WebCore/page/UserStyleSheet.h b/WebCore/page/UserStyleSheet.h
new file mode 100644
index 0000000..56bec40
--- /dev/null
+++ b/WebCore/page/UserStyleSheet.h
@@ -0,0 +1,66 @@
+/*
+ * 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 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.
+ */
+
+#ifndef UserStyleSheet_h
+#define UserStyleSheet_h
+
+#include "KURL.h"
+#include "UserStyleSheetTypes.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class UserStyleSheet {
+public:
+ UserStyleSheet(const String& source, const KURL& url,
+ PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist,
+ unsigned worldID)
+ : m_source(source)
+ , m_url(url)
+ , m_whitelist(whitelist)
+ , m_blacklist(blacklist)
+ , m_worldID(worldID)
+ {
+ }
+
+ const String& source() const { return m_source; }
+ 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
+
+#endif // UserStyleSheet_h
diff --git a/WebCore/page/UserStyleSheetTypes.h b/WebCore/page/UserStyleSheetTypes.h
new file mode 100644
index 0000000..094b2cf
--- /dev/null
+++ b/WebCore/page/UserStyleSheetTypes.h
@@ -0,0 +1,41 @@
+/*
+ * 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 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.
+ */
+
+#ifndef UserStyleSheetTypes_h
+#define UserStyleSheetTypes_h
+
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class UserStyleSheet;
+
+typedef Vector<OwnPtr<UserStyleSheet> > UserStyleSheetVector;
+typedef HashMap<unsigned, UserStyleSheetVector*> UserStyleSheetMap;
+
+} // namespace WebCore
+
+#endif // UserStyleSheetTypes_h
diff --git a/WebCore/page/XSSAuditor.cpp b/WebCore/page/XSSAuditor.cpp
index 70b691b..92ed896 100644
--- a/WebCore/page/XSSAuditor.cpp
+++ b/WebCore/page/XSSAuditor.cpp
@@ -48,12 +48,38 @@ namespace WebCore {
static bool isNonCanonicalCharacter(UChar c)
{
+ // We remove all non-ASCII characters, including non-printable ASCII characters.
+ //
// Note, we don't remove backslashes like PHP stripslashes(), which among other things converts "\\0" to the \0 character.
// Instead, we remove backslashes and zeros (since the string "\\0" =(remove backslashes)=> "0"). However, this has the
// adverse effect that we remove any legitimate zeros from a string.
//
// For instance: new String("http://localhost:8000") => new String("http://localhost:8").
- return (c == '\\' || c == '0' || c < ' ' || c == 127);
+ return (c == '\\' || c == '0' || c < ' ' || c >= 127);
+}
+
+static bool isIllegalURICharacter(UChar c)
+{
+ // The characters described in section 2.4.3 of RFC 2396 <http://www.faqs.org/rfcs/rfc2396.html> in addition to the
+ // single quote character "'" are considered illegal URI characters. That is, the following characters cannot appear
+ // in a valid URI: ', ", <, >
+ //
+ // If the request does not contain these characters then we can assume that no inline scripts have been injected
+ // into response page, because it is impossible to write an inline script of the form <script>...</script>
+ // without "<", ">".
+ return (c == '\'' || c == '"' || c == '<' || c == '>');
+}
+
+String XSSAuditor::CachingURLCanonicalizer::canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities)
+{
+ if (decodeEntities == m_decodeEntities && encoding == m_encoding && url == m_inputURL)
+ return m_cachedCanonicalizedURL;
+
+ m_cachedCanonicalizedURL = canonicalize(decodeURL(url, encoding, decodeEntities));
+ m_inputURL = url;
+ m_encoding = encoding;
+ m_decodeEntities = decodeEntities;
+ return m_cachedCanonicalizedURL;
}
XSSAuditor::XSSAuditor(Frame* frame)
@@ -76,7 +102,7 @@ bool XSSAuditor::canEvaluate(const String& code) const
if (!isEnabled())
return true;
- if (findInRequest(code, false)) {
+ if (findInRequest(code, false, true)) {
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;
@@ -102,7 +128,7 @@ bool XSSAuditor::canCreateInlineEventListener(const String&, const String& code)
if (!isEnabled())
return true;
- if (findInRequest(code)) {
+ if (findInRequest(code, true, true)) {
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;
@@ -156,22 +182,23 @@ String XSSAuditor::canonicalize(const String& string)
return result.removeCharacters(&isNonCanonicalCharacter);
}
-String XSSAuditor::decodeURL(const String& string, const TextEncoding& encoding, bool decodeHTMLentities)
+String XSSAuditor::decodeURL(const String& string, const TextEncoding& encoding, bool decodeEntities)
{
String result;
String url = string;
url.replace('+', ' ');
result = decodeURLEscapeSequences(url);
- String decodedResult = encoding.decode(result.utf8().data(), result.length());
+ CString utf8Url = result.utf8();
+ String decodedResult = encoding.decode(utf8Url.data(), utf8Url.length());
if (!decodedResult.isEmpty())
result = decodedResult;
- if (decodeHTMLentities)
+ if (decodeEntities)
result = decodeHTMLEntities(result);
return result;
}
-String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodableHTMLEntitiesUntouched)
+String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodableEntitiesUntouched)
{
SegmentedString source(string);
SegmentedString sourceShadow;
@@ -186,7 +213,7 @@ String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodabl
continue;
}
- if (leaveUndecodableHTMLEntitiesUntouched)
+ if (leaveUndecodableEntitiesUntouched)
sourceShadow = source;
bool notEnoughCharacters = false;
unsigned entity = PreloadScanner::consumeEntity(source, notEnoughCharacters);
@@ -196,11 +223,11 @@ String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodabl
if (entity > 0xFFFF) {
result.append(U16_LEAD(entity));
result.append(U16_TRAIL(entity));
- } else if (entity && (!leaveUndecodableHTMLEntitiesUntouched || entity != 0xFFFD)){
+ } else if (entity && (!leaveUndecodableEntitiesUntouched || entity != 0xFFFD)){
result.append(entity);
} else {
result.append('&');
- if (leaveUndecodableHTMLEntitiesUntouched)
+ if (leaveUndecodableEntitiesUntouched)
source = sourceShadow;
}
}
@@ -208,31 +235,48 @@ String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodabl
return String::adopt(result);
}
-bool XSSAuditor::findInRequest(const String& string, bool decodeHTMLentities) const
+bool XSSAuditor::findInRequest(const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters) const
{
bool result = false;
Frame* parentFrame = m_frame->tree()->parent();
if (parentFrame && m_frame->document()->url() == blankURL())
- result = findInRequest(parentFrame, string, decodeHTMLentities);
+ result = findInRequest(parentFrame, string, decodeEntities, allowRequestIfNoIllegalURICharacters);
if (!result)
- result = findInRequest(m_frame, string, decodeHTMLentities);
+ result = findInRequest(m_frame, string, decodeEntities, allowRequestIfNoIllegalURICharacters);
return result;
}
-bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeHTMLentities) const
+bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters) const
{
ASSERT(frame->document());
- String pageURL = frame->document()->url().string();
if (!frame->document()->decoder()) {
// Note, JavaScript URLs do not have a charset.
return false;
}
- if (protocolIs(pageURL, "data"))
+ if (string.isEmpty())
return false;
- if (string.isEmpty())
+ FormData* formDataObj = frame->loader()->documentLoader()->originalRequest().httpBody();
+ String pageURL = frame->document()->url().string();
+
+ if (!formDataObj && 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.
+ //
+ // Q: Why do we multiply by two here?
+ // A: We attempt to detect reflected XSS even when the server
+ // transforms the attacker's input with addSlashes. The best the
+ // 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;
+ }
+
+ if (frame->document()->url().protocolIs("data"))
return false;
String canonicalizedString = canonicalize(string);
@@ -241,12 +285,16 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeHT
if (string.length() < pageURL.length()) {
// The string can actually fit inside the pageURL.
- String decodedPageURL = canonicalize(decodeURL(pageURL, frame->document()->decoder()->encoding(), decodeHTMLentities));
+ String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), decodeEntities);
+
+ 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.
+
if (decodedPageURL.find(canonicalizedString, 0, false) != -1)
- return true; // We've found the smoking gun.
+ return true; // We've found the smoking gun.
}
- FormData* formDataObj = frame->loader()->documentLoader()->originalRequest().httpBody();
if (formDataObj && !formDataObj->isEmpty()) {
String formData = formDataObj->flattenToString();
if (string.length() < formData.length()) {
@@ -254,7 +302,7 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeHT
// 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 = canonicalize(decodeURL(formData, frame->document()->decoder()->encoding(), decodeHTMLentities));
+ String decodedFormData = m_cache.canonicalizeURL(formData, frame->document()->decoder()->encoding(), decodeEntities);
if (decodedFormData.find(canonicalizedString, 0, false) != -1)
return true; // We found the string in the POST data.
}
diff --git a/WebCore/page/XSSAuditor.h b/WebCore/page/XSSAuditor.h
index 26f10ab..d3d1ec9 100644
--- a/WebCore/page/XSSAuditor.h
+++ b/WebCore/page/XSSAuditor.h
@@ -99,18 +99,34 @@ namespace WebCore {
bool canSetBaseElementURL(const String& url) const;
private:
- static String canonicalize(const String&);
-
- static String decodeURL(const String& url, const TextEncoding& encoding = UTF8Encoding(), bool decodeHTMLentities = true);
-
- static String decodeHTMLEntities(const String&, bool leaveUndecodableHTMLEntitiesUntouched = true);
+ class CachingURLCanonicalizer
+ {
+ public:
+ CachingURLCanonicalizer() : m_decodeEntities(false) { }
+ String canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities);
+
+ private:
+ // The parameters we were called with last.
+ String m_inputURL;
+ TextEncoding m_encoding;
+ bool m_decodeEntities;
+
+ // The cached result.
+ String m_cachedCanonicalizedURL;
+ };
- bool findInRequest(const String&, bool decodeHTMLentities = true) const;
+ static String canonicalize(const String&);
+ static String decodeURL(const String& url, const TextEncoding& encoding, bool decodeEntities);
+ static String decodeHTMLEntities(const String&, bool leaveUndecodableEntitiesUntouched = true);
- bool findInRequest(Frame*, const String&, bool decodeHTMLentities = true) const;
+ bool findInRequest(const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false) const;
+ bool findInRequest(Frame*, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false) const;
// The frame to audit.
Frame* m_frame;
+
+ // A state store to help us avoid canonicalizing the same URL repeated.
+ mutable CachingURLCanonicalizer m_cache;
};
} // namespace WebCore
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp
index 7503f0a..ec0e284 100644
--- a/WebCore/page/animation/AnimationBase.cpp
+++ b/WebCore/page/animation/AnimationBase.cpp
@@ -302,11 +302,21 @@ public:
{
ShadowData* shadowA = (a->*m_getter)();
ShadowData* shadowB = (b->*m_getter)();
+
+ while (true) {
+ if (!shadowA && !shadowB) // end of both lists
+ return true;
+
+ if (!shadowA || !shadowB) // end of just one of the lists
+ return false;
+
+ if (*shadowA != *shadowB)
+ return false;
+
+ shadowA = shadowA->next;
+ shadowB = shadowB->next;
+ }
- if ((!shadowA && shadowB) || (shadowA && !shadowB))
- return false;
- if (shadowA && shadowB && (*shadowA != *shadowB))
- return false;
return true;
}
@@ -316,12 +326,22 @@ public:
ShadowData* shadowB = (b->*m_getter)();
ShadowData defaultShadowData(0, 0, 0, 0, Normal, Color::transparent);
- if (!shadowA)
- shadowA = &defaultShadowData;
- if (!shadowB)
- shadowB = &defaultShadowData;
+ ShadowData* newShadowData = 0;
+
+ while (shadowA || shadowB) {
+ ShadowData* srcShadow = shadowA ? shadowA : &defaultShadowData;
+ ShadowData* dstShadow = shadowB ? shadowB : &defaultShadowData;
+
+ if (!newShadowData)
+ newShadowData = blendFunc(anim, srcShadow, dstShadow, progress);
+ else
+ newShadowData->next = blendFunc(anim, srcShadow, dstShadow, progress);
- (dst->*m_setter)(blendFunc(anim, shadowA, shadowB, progress), false);
+ shadowA = shadowA ? shadowA->next : 0;
+ shadowB = shadowB ? shadowB->next : 0;
+ }
+
+ (dst->*m_setter)(newShadowData, false);
}
private:
@@ -341,6 +361,10 @@ public:
{
Color fromColor = (a->*m_getter)();
Color toColor = (b->*m_getter)();
+
+ if (!fromColor.isValid() && !toColor.isValid())
+ return true;
+
if (!fromColor.isValid())
fromColor = a->color();
if (!toColor.isValid())
@@ -353,6 +377,10 @@ public:
{
Color fromColor = (a->*m_getter)();
Color toColor = (b->*m_getter)();
+
+ if (!fromColor.isValid() && !toColor.isValid())
+ return;
+
if (!fromColor.isValid())
fromColor = a->color();
if (!toColor.isValid())
@@ -365,6 +393,124 @@ private:
void (RenderStyle::*m_setter)(const Color&);
};
+// Wrapper base class for an animatable property in a FillLayer
+class FillLayerPropertyWrapperBase {
+public:
+ FillLayerPropertyWrapperBase()
+ {
+ }
+
+ virtual ~FillLayerPropertyWrapperBase() { }
+
+ virtual bool equals(const FillLayer* a, const FillLayer* b) const = 0;
+ virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const = 0;
+};
+
+template <typename T>
+class FillLayerPropertyWrapperGetter : public FillLayerPropertyWrapperBase {
+public:
+ FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const)
+ : m_getter(getter)
+ {
+ }
+
+ virtual bool equals(const FillLayer* a, const FillLayer* b) const
+ {
+ // If the style pointers are the same, don't bother doing the test.
+ // If either is null, return false. If both are null, return true.
+ if ((!a && !b) || a == b)
+ return true;
+ if (!a || !b)
+ return false;
+ return (a->*m_getter)() == (b->*m_getter)();
+ }
+
+protected:
+ T (FillLayer::*m_getter)() const;
+};
+
+template <typename T>
+class FillLayerPropertyWrapper : public FillLayerPropertyWrapperGetter<T> {
+public:
+ FillLayerPropertyWrapper(T (FillLayer::*getter)() const, void (FillLayer::*setter)(T))
+ : FillLayerPropertyWrapperGetter<T>(getter)
+ , m_setter(setter)
+ {
+ }
+
+ virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const
+ {
+ (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<T>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<T>::m_getter)(), progress));
+ }
+
+protected:
+ void (FillLayer::*m_setter)(T);
+};
+
+
+class FillLayersPropertyWrapper : public PropertyWrapperBase {
+public:
+ typedef const FillLayer* (RenderStyle::*LayersGetter)() const;
+ typedef FillLayer* (RenderStyle::*LayersAccessor)();
+
+ FillLayersPropertyWrapper(int prop, LayersGetter getter, LayersAccessor accessor)
+ : PropertyWrapperBase(prop)
+ , m_layersGetter(getter)
+ , m_layersAccessor(accessor)
+ {
+ switch (prop) {
+ case CSSPropertyBackgroundPositionX:
+ case CSSPropertyWebkitMaskPositionX:
+ m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::xPosition, &FillLayer::setXPosition);
+ break;
+ case CSSPropertyBackgroundPositionY:
+ case CSSPropertyWebkitMaskPositionY:
+ m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::yPosition, &FillLayer::setYPosition);
+ break;
+ case CSSPropertyBackgroundSize:
+ case CSSPropertyWebkitMaskSize:
+ m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<LengthSize>(&FillLayer::sizeLength, &FillLayer::setSizeLength);
+ break;
+ }
+ }
+
+ virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
+ {
+ const FillLayer* fromLayer = (a->*m_layersGetter)();
+ const FillLayer* toLayer = (b->*m_layersGetter)();
+
+ while (fromLayer && toLayer) {
+ if (!m_fillLayerPropertyWrapper->equals(fromLayer, toLayer))
+ return false;
+
+ fromLayer = fromLayer->next();
+ toLayer = toLayer->next();
+ }
+
+ return true;
+ }
+
+ virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ const FillLayer* aLayer = (a->*m_layersGetter)();
+ const FillLayer* bLayer = (b->*m_layersGetter)();
+ FillLayer* dstLayer = (dst->*m_layersAccessor)();
+
+ while (aLayer && bLayer && dstLayer) {
+ m_fillLayerPropertyWrapper->blend(anim, dstLayer, aLayer, bLayer, progress);
+ aLayer = aLayer->next();
+ bLayer = bLayer->next();
+ dstLayer = dstLayer->next();
+ }
+ }
+
+private:
+ FillLayerPropertyWrapperBase* m_fillLayerPropertyWrapper;
+
+ LayersGetter m_layersGetter;
+ LayersAccessor m_layersAccessor;
+};
+
class ShorthandPropertyWrapper : public PropertyWrapperBase {
public:
ShorthandPropertyWrapper(int property, const CSSPropertyLonghand& longhand)
@@ -442,13 +588,14 @@ static void ensurePropertyMap()
gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor));
gPropertyWrappers->append(new PropertyWrapper<const Color&>(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundXPosition, &RenderStyle::setBackgroundXPosition));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundYPosition, &RenderStyle::setBackgroundYPosition));
- gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundSize, &RenderStyle::setBackgroundSize));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskXPosition, &RenderStyle::setMaskXPosition));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskYPosition, &RenderStyle::setMaskYPosition));
- gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyWebkitMaskSize, &RenderStyle::maskSize, &RenderStyle::setMaskSize));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
+
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers));
+ gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers));
gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyFontSize, &RenderStyle::fontSize, &RenderStyle::setBlendedFontSize));
gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth));
@@ -496,7 +643,7 @@ static void ensurePropertyMap()
gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyOutlineColor, &RenderStyle::outlineColor, &RenderStyle::setOutlineColor));
// These are for shadows
- gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow));
+ gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow));
gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow));
#if ENABLE(SVG)
@@ -685,7 +832,7 @@ void AnimationBase::setNeedsStyleRecalc(Node* node)
{
ASSERT(!node || (node->document() && !node->document()->inPageCache()));
if (node)
- node->setNeedsStyleRecalc(AnimationStyleChange);
+ node->setNeedsStyleRecalc(SyntheticStyleChange);
}
double AnimationBase::duration() const
diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp
index ed241e1..691932e 100644
--- a/WebCore/page/animation/AnimationController.cpp
+++ b/WebCore/page/animation/AnimationController.cpp
@@ -36,6 +36,8 @@
#include "EventNames.h"
#include "Frame.h"
#include "RenderView.h"
+#include "WebKitAnimationEvent.h"
+#include "WebKitTransitionEvent.h"
#include <wtf/CurrentTime.h>
#include <wtf/UnusedParam.h>
@@ -98,7 +100,7 @@ void AnimationControllerPrivate::updateAnimationTimer(bool callSetChanged/* = fa
if (callSetChanged) {
Node* node = it->first->node();
ASSERT(!node || (node->document() && !node->document()->inPageCache()));
- node->setNeedsStyleRecalc(AnimationStyleChange);
+ node->setNeedsStyleRecalc(SyntheticStyleChange);
calledSetChanged = true;
}
else
@@ -136,9 +138,9 @@ void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<Animat
Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = m_eventsToDispatch.end();
for (Vector<EventToDispatch>::const_iterator it = m_eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) {
if (it->eventType == eventNames().webkitTransitionEndEvent)
- it->element->dispatchWebKitTransitionEvent(it->eventType, it->name, it->elapsedTime);
+ it->element->dispatchEvent(WebKitTransitionEvent::create(it->eventType, it->name, it->elapsedTime));
else
- it->element->dispatchWebKitAnimationEvent(it->eventType, it->name, it->elapsedTime);
+ it->element->dispatchEvent(WebKitAnimationEvent::create(it->eventType, it->name, it->elapsedTime));
}
m_eventsToDispatch.clear();
@@ -146,7 +148,7 @@ void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<Animat
// call setChanged on all the elements
Vector<RefPtr<Node> >::const_iterator nodeChangesToDispatchEnd = m_nodeChangesToDispatch.end();
for (Vector<RefPtr<Node> >::const_iterator it = m_nodeChangesToDispatch.begin(); it != nodeChangesToDispatchEnd; ++it)
- (*it)->setNeedsStyleRecalc(AnimationStyleChange);
+ (*it)->setNeedsStyleRecalc(SyntheticStyleChange);
m_nodeChangesToDispatch.clear();
@@ -244,7 +246,7 @@ bool AnimationControllerPrivate::pauseAnimationAtTime(RenderObject* renderer, co
return false;
if (compAnim->pauseAnimationAtTime(name, t)) {
- renderer->node()->setNeedsStyleRecalc(AnimationStyleChange);
+ renderer->node()->setNeedsStyleRecalc(SyntheticStyleChange);
startUpdateStyleIfNeededDispatcher();
return true;
}
@@ -262,7 +264,7 @@ bool AnimationControllerPrivate::pauseTransitionAtTime(RenderObject* renderer, c
return false;
if (compAnim->pauseTransitionAtTime(cssPropertyID(property), t)) {
- renderer->node()->setNeedsStyleRecalc(AnimationStyleChange);
+ renderer->node()->setNeedsStyleRecalc(SyntheticStyleChange);
startUpdateStyleIfNeededDispatcher();
return true;
}
@@ -438,7 +440,7 @@ void AnimationController::cancelAnimations(RenderObject* renderer)
if (m_data->clear(renderer)) {
Node* node = renderer->node();
ASSERT(!node || (node->document() && !node->document()->inPageCache()));
- node->setNeedsStyleRecalc(AnimationStyleChange);
+ node->setNeedsStyleRecalc(SyntheticStyleChange);
}
}
diff --git a/WebCore/page/chromium/FrameChromium.cpp b/WebCore/page/chromium/FrameChromium.cpp
index 1372cd9..d79ae68 100644
--- a/WebCore/page/chromium/FrameChromium.cpp
+++ b/WebCore/page/chromium/FrameChromium.cpp
@@ -60,7 +60,7 @@ void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float head
float ratio = static_cast<float>(printRect.height()) / static_cast<float>(printRect.width());
- float pageWidth = static_cast<float>(root->overflowWidth());
+ 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);
diff --git a/WebCore/page/gtk/EventHandlerGtk.cpp b/WebCore/page/gtk/EventHandlerGtk.cpp
index d12cdcc..7051391 100644
--- a/WebCore/page/gtk/EventHandlerGtk.cpp
+++ b/WebCore/page/gtk/EventHandlerGtk.cpp
@@ -122,4 +122,13 @@ unsigned EventHandler::accessKeyModifiers()
return PlatformKeyboardEvent::AltKey;
}
+// GTK+ must scroll horizontally if the mouse pointer is on top of the
+// horizontal scrollbar while scrolling with the wheel; we need to
+// add the deltas and ticks here so that this behavior is consistent
+// for styled scrollbars.
+bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult& result) const
+{
+ return result.scrollbar() && result.scrollbar()->orientation() == HorizontalScrollbar;
+}
+
}
diff --git a/WebCore/page/haiku/DragControllerHaiku.cpp b/WebCore/page/haiku/DragControllerHaiku.cpp
index 0b95558..ef08ac2 100644
--- a/WebCore/page/haiku/DragControllerHaiku.cpp
+++ b/WebCore/page/haiku/DragControllerHaiku.cpp
@@ -32,10 +32,9 @@
#include <InterfaceDefs.h>
-namespace WebCore
-{
+namespace WebCore {
-// FIXME: These values are straight out of DragControllerMac, so probably have
+// FIXME: These values are straight out of DragControllerMac, so probably have
// little correlation with Haiku standards...
const int DragController::LinkDragBorderInset = 2;
const int DragController::MaxOriginalImageArea = 1500 * 1500;
diff --git a/WebCore/page/haiku/EventHandlerHaiku.cpp b/WebCore/page/haiku/EventHandlerHaiku.cpp
index 64b8519..203344e 100644
--- a/WebCore/page/haiku/EventHandlerHaiku.cpp
+++ b/WebCore/page/haiku/EventHandlerHaiku.cpp
@@ -36,14 +36,13 @@
#include "HitTestResult.h"
#include "KeyboardEvent.h"
#include "MouseEventWithHitTestResults.h"
+#include "NotImplemented.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformScrollBar.h"
#include "PlatformWheelEvent.h"
#include "RenderWidget.h"
-#include "NotImplemented.h"
-
#include <interface/View.h>
@@ -117,13 +116,15 @@ bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& eve
bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* widget)
{
- notImplemented();
- return false;
+ if (!widget->isFrameView())
+ return false;
+
+ return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(event);
}
PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
- return new ClipboardHaiku(ClipboardWritable, true);
+ return ClipboardHaiku::create(ClipboardWritable, true);
}
bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
diff --git a/WebCore/page/mac/DragControllerMac.mm b/WebCore/page/mac/DragControllerMac.mm
index c476df7..8a04809 100644
--- a/WebCore/page/mac/DragControllerMac.mm
+++ b/WebCore/page/mac/DragControllerMac.mm
@@ -26,6 +26,7 @@
#import "config.h"
#import "DragController.h"
+#if ENABLE(DRAG_SUPPORT)
#import "DragData.h"
#import "Frame.h"
#import "FrameView.h"
@@ -75,4 +76,6 @@ void DragController::cleanupAfterSystemDrag()
dragEnded();
}
-}
+} // namespace WebCore
+
+#endif // ENABLE(DRAG_SUPPORT)
diff --git a/WebCore/page/mac/EventHandlerMac.mm b/WebCore/page/mac/EventHandlerMac.mm
index 54bdff9..7da1d36 100644
--- a/WebCore/page/mac/EventHandlerMac.mm
+++ b/WebCore/page/mac/EventHandlerMac.mm
@@ -60,7 +60,9 @@ static inline IMP method_setImplementation(Method m, IMP i)
namespace WebCore {
+#if ENABLE(DRAG_SUPPORT)
const double EventHandler::TextDragDelay = 0.15;
+#endif
static RetainPtr<NSEvent>& currentNSEventSlot()
{
@@ -110,7 +112,7 @@ bool EventHandler::wheelEvent(NSEvent *event)
m_useLatchedWheelEventNode = wkIsLatchingWheelEvent(event);
- PlatformWheelEvent wheelEvent(event, page->chrome()->platformWindow());
+ PlatformWheelEvent wheelEvent(event, page->chrome()->platformPageClient());
handleWheelEvent(wheelEvent);
return wheelEvent.isAccepted();
@@ -372,6 +374,7 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const
return m_activationEventNumber == event.eventNumber();
}
+#if ENABLE(DRAG_SUPPORT)
bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&)
{
NSView *view = mouseDownViewIfStillGood();
@@ -399,6 +402,7 @@ PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
[pasteboard declareTypes:[NSArray array] owner:nil];
return ClipboardMac::create(true, pasteboard, ClipboardWritable, m_frame);
}
+#endif // ENABLE(DRAG_SUPPORT)
bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
{
@@ -430,8 +434,10 @@ bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& eve
// layout tests.
if (!m_mouseDownWasInSubframe)
return false;
+#if ENABLE(DRAG_SUPPORT)
if (subframe->page()->dragController()->didInitiateDrag())
return false;
+#endif
case NSMouseMoved:
// Since we're passing in currentNSEvent() here, we can call
// handleMouseMoveEvent() directly, since the save/restore of
@@ -706,24 +712,28 @@ PlatformMouseEvent EventHandler::currentPlatformMouseEvent() const
{
NSView *windowView = nil;
if (Page* page = m_frame->page())
- windowView = page->chrome()->platformWindow();
+ windowView = page->chrome()->platformPageClient();
return PlatformMouseEvent(currentNSEvent(), windowView);
}
+#if ENABLE(CONTEXT_MENUS)
bool EventHandler::sendContextMenuEvent(NSEvent *event)
{
Page* page = m_frame->page();
if (!page)
return false;
- return sendContextMenuEvent(PlatformMouseEvent(event, page->chrome()->platformWindow()));
+ return sendContextMenuEvent(PlatformMouseEvent(event, page->chrome()->platformPageClient()));
}
+#endif // ENABLE(CONTEXT_MENUS)
+#if ENABLE(DRAG_SUPPORT)
bool EventHandler::eventMayStartDrag(NSEvent *event)
{
Page* page = m_frame->page();
if (!page)
return false;
- return eventMayStartDrag(PlatformMouseEvent(event, page->chrome()->platformWindow()));
+ return eventMayStartDrag(PlatformMouseEvent(event, page->chrome()->platformPageClient()));
}
+#endif // ENABLE(DRAG_SUPPORT)
}
diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm
index c656624..d9faa8b 100644
--- a/WebCore/page/mac/FrameMac.mm
+++ b/WebCore/page/mac/FrameMac.mm
@@ -28,7 +28,6 @@
#import "config.h"
#import "Frame.h"
-#import "Base64.h"
#import "BlockExceptions.h"
#import "ColorMac.h"
#import "Cursor.h"
@@ -53,7 +52,6 @@
#import "RenderTableCell.h"
#import "Scrollbar.h"
#import "SimpleFontData.h"
-#import "UserStyleSheetLoader.h"
#import "WebCoreViewFactory.h"
#import "visible_units.h"
@@ -533,35 +531,4 @@ DragImageRef Frame::dragImageForSelection()
return selectionImage();
}
-void Frame::setUserStyleSheetLocation(const KURL& url)
-{
- delete m_userStyleSheetLoader;
- m_userStyleSheetLoader = 0;
-
- // Data URLs with base64-encoded UTF-8 style sheets are common. We can process them
- // synchronously and avoid using a loader.
- if (url.protocolIs("data") && url.string().startsWith("data:text/css;charset=utf-8;base64,")) {
- const unsigned prefixLength = 35;
- Vector<char> encodedData(url.string().length() - prefixLength);
- for (unsigned i = prefixLength; i < url.string().length(); ++i)
- encodedData[i - prefixLength] = static_cast<char>(url.string()[i]);
-
- Vector<char> styleSheetAsUTF8;
- if (base64Decode(encodedData, styleSheetAsUTF8)) {
- m_doc->setUserStyleSheet(String::fromUTF8(styleSheetAsUTF8.data()));
- return;
- }
- }
-
- if (m_doc->docLoader())
- m_userStyleSheetLoader = new UserStyleSheetLoader(m_doc, url.string());
-}
-
-void Frame::setUserStyleSheet(const String& styleSheet)
-{
- delete m_userStyleSheetLoader;
- m_userStyleSheetLoader = 0;
- m_doc->setUserStyleSheet(styleSheet);
-}
-
} // namespace WebCore
diff --git a/WebCore/page/mac/WebCoreViewFactory.h b/WebCore/page/mac/WebCoreViewFactory.h
index d4dc821..249d696 100644
--- a/WebCore/page/mac/WebCoreViewFactory.h
+++ b/WebCore/page/mac/WebCoreViewFactory.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003, 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2009 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,6 +39,7 @@
- (NSString *)fileButtonNoFileSelectedLabel;
- (NSString *)copyImageUnknownFileLabel;
+#if ENABLE(CONTEXT_MENUS)
// Context menu item titles
- (NSString *)contextMenuItemTagOpenLinkInNewWindow;
- (NSString *)contextMenuItemTagDownloadLinkToDisk;
@@ -97,6 +98,7 @@
- (NSString *)contextMenuItemTagCapitalize;
- (NSString *)contextMenuItemTagChangeBack:(NSString *)replacedString;
- (NSString *)contextMenuItemTagInspectElement;
+#endif // ENABLE(CONTEXT_MENUS)
- (NSString *)searchMenuNoRecentSearchesText;
- (NSString *)searchMenuRecentSearchesText;
@@ -129,6 +131,7 @@
- (NSString *)AXHeadingText;
- (NSString *)AXDefinitionListTermText;
- (NSString *)AXDefinitionListDefinitionText;
+- (NSString *)AXARIAContentGroupText:(NSString *)ariaType;
- (NSString *)AXButtonActionVerb;
- (NSString *)AXRadioButtonActionVerb;
@@ -143,6 +146,10 @@
- (NSString *)mediaElementLoadingStateText;
- (NSString *)mediaElementLiveBroadcastStateText;
+- (NSString*)localizedMediaControlElementString:(NSString*)name;
+- (NSString*)localizedMediaControlElementHelpText:(NSString*)name;
+- (NSString*)localizedMediaTimeDescription:(float)time;
+
@end
diff --git a/WebCore/page/qt/FrameQt.cpp b/WebCore/page/qt/FrameQt.cpp
index 388bf66..493e60d 100644
--- a/WebCore/page/qt/FrameQt.cpp
+++ b/WebCore/page/qt/FrameQt.cpp
@@ -24,8 +24,6 @@
#include "config.h"
#include "Frame.h"
-#include "UserStyleSheetLoader.h"
-
namespace WebCore {
DragImageRef Frame::dragImageForSelection()
@@ -33,21 +31,5 @@ DragImageRef Frame::dragImageForSelection()
return 0;
}
-void Frame::setUserStyleSheetLocation(const KURL& url)
-{
- delete m_userStyleSheetLoader;
- m_userStyleSheetLoader = 0;
- if (m_doc && m_doc->docLoader())
- m_userStyleSheetLoader = new UserStyleSheetLoader(m_doc, url.string());
-}
-
-void Frame::setUserStyleSheet(const String& styleSheet)
-{
- delete m_userStyleSheetLoader;
- m_userStyleSheetLoader = 0;
- if (m_doc)
- m_doc->setUserStyleSheet(styleSheet);
-}
-
}
// vim: ts=4 sw=4 et
diff --git a/WebCore/page/win/FrameWin.cpp b/WebCore/page/win/FrameWin.cpp
index 1e480fb..b15d195 100644
--- a/WebCore/page/win/FrameWin.cpp
+++ b/WebCore/page/win/FrameWin.cpp
@@ -61,7 +61,7 @@ void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float head
float ratio = static_cast<float>(printRect.height()) / static_cast<float>(printRect.width());
- float pageWidth = static_cast<float>(root->overflowWidth());
+ 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);
diff --git a/WebCore/page/wince/FrameWince.cpp b/WebCore/page/wince/FrameWince.cpp
index 480a103..5ecb579 100644
--- a/WebCore/page/wince/FrameWince.cpp
+++ b/WebCore/page/wince/FrameWince.cpp
@@ -50,7 +50,6 @@
#include "runtime_root.h"
#include "Settings.h"
#include "TextResourceDecoder.h"
-#include "UserStyleSheetLoader.h"
#include <windows.h>
@@ -166,20 +165,4 @@ DragImageRef Frame::dragImageForSelection()
return 0;
}
-void Frame::setUserStyleSheetLocation(const KURL& url)
-{
- delete m_userStyleSheetLoader;
- m_userStyleSheetLoader = 0;
- if (m_doc && m_doc->docLoader())
- m_userStyleSheetLoader = new UserStyleSheetLoader(m_doc, url.string());
-}
-
-void Frame::setUserStyleSheet(const String& styleSheet)
-{
- delete m_userStyleSheetLoader;
- m_userStyleSheetLoader = 0;
- if (m_doc)
- m_doc->setUserStyleSheet(styleSheet);
-}
-
} // namespace WebCore
diff --git a/WebCore/page/wx/EventHandlerWx.cpp b/WebCore/page/wx/EventHandlerWx.cpp
index 65a743c..f4f6914 100644
--- a/WebCore/page/wx/EventHandlerWx.cpp
+++ b/WebCore/page/wx/EventHandlerWx.cpp
@@ -32,6 +32,7 @@
#include "FrameView.h"
#include "KeyboardEvent.h"
#include "MouseEventWithHitTestResults.h"
+#include "NotImplemented.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
#include "RenderWidget.h"
@@ -43,17 +44,20 @@ const double EventHandler::TextDragDelay = 0.0;
bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
{
- return passSubframeEventToSubframe(mev, subframe);
+ subframe->eventHandler()->handleMousePressEvent(mev.event());
+ return true;
}
bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, WebCore::HitTestResult* hittest)
{
- return passSubframeEventToSubframe(mev, subframe);
+ subframe->eventHandler()->handleMouseMoveEvent(mev.event(), hittest);
+ return true;
}
bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
{
- return passSubframeEventToSubframe(mev, subframe);
+ subframe->eventHandler()->handleMouseReleaseEvent(mev.event());
+ return true;
}
bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
@@ -70,6 +74,32 @@ bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
return passMouseDownEventToWidget(renderWidget->widget());
}
+bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* widget)
+{
+ if (!widget || !widget->isFrameView())
+ return false;
+
+ return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(event);
+}
+
+bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
+{
+ notImplemented();
+ return false;
+}
+
+bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult*)
+{
+ notImplemented();
+ return false;
+}
+
+bool EventHandler::passMouseDownEventToWidget(Widget*)
+{
+ notImplemented();
+ return false;
+}
+
void EventHandler::focusDocumentView()
{
if (Page* page = m_frame->page())
diff --git a/WebCore/page/wx/FrameWx.cpp b/WebCore/page/wx/FrameWx.cpp
new file mode 100644
index 0000000..b220694
--- /dev/null
+++ b/WebCore/page/wx/FrameWx.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 Kevin Ollivier <kevino@theolliviers.com>. 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 "Frame.h"
+#include "NotImplemented.h"
+
+namespace WebCore {
+
+DragImageRef Frame::dragImageForSelection()
+{
+ notImplemented();
+ return 0;
+}
+
+}