summaryrefslogtreecommitdiffstats
path: root/WebCore/page
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/page')
-rw-r--r--WebCore/page/Chrome.cpp26
-rw-r--r--WebCore/page/Chrome.h13
-rw-r--r--WebCore/page/ChromeClient.h27
-rw-r--r--WebCore/page/Console.cpp2
-rw-r--r--WebCore/page/Console.idl3
-rw-r--r--WebCore/page/DOMSelection.cpp30
-rw-r--r--WebCore/page/DOMSelection.h1
-rw-r--r--WebCore/page/DOMWindow.cpp135
-rw-r--r--WebCore/page/DOMWindow.h10
-rw-r--r--WebCore/page/DOMWindow.idl46
-rw-r--r--WebCore/page/DragController.cpp49
-rw-r--r--WebCore/page/DragController.h2
-rw-r--r--WebCore/page/EventHandler.cpp274
-rw-r--r--WebCore/page/EventHandler.h16
-rw-r--r--WebCore/page/EventSource.cpp7
-rw-r--r--WebCore/page/EventSource.idl8
-rw-r--r--WebCore/page/FocusController.cpp197
-rw-r--r--WebCore/page/FocusController.h9
-rw-r--r--WebCore/page/FocusDirection.h9
-rw-r--r--WebCore/page/Frame.cpp170
-rw-r--r--WebCore/page/Frame.h47
-rw-r--r--WebCore/page/FrameTree.cpp1
-rw-r--r--WebCore/page/FrameView.cpp135
-rw-r--r--WebCore/page/FrameView.h12
-rw-r--r--WebCore/page/Geolocation.cpp118
-rw-r--r--WebCore/page/Geolocation.h43
-rw-r--r--WebCore/page/Geolocation.idl4
-rw-r--r--WebCore/page/GeolocationPositionCache.cpp13
-rw-r--r--WebCore/page/Geoposition.idl2
-rw-r--r--WebCore/page/History.idl4
-rw-r--r--WebCore/page/Location.cpp4
-rw-r--r--WebCore/page/OriginAccessEntry.cpp1
-rw-r--r--WebCore/page/OriginAccessEntry.h17
-rw-r--r--WebCore/page/Page.cpp56
-rw-r--r--WebCore/page/Page.h25
-rw-r--r--WebCore/page/PageGroup.cpp18
-rw-r--r--WebCore/page/PageGroup.h7
-rw-r--r--WebCore/page/PositionCallback.h1
-rw-r--r--WebCore/page/PositionError.idl2
-rw-r--r--WebCore/page/PositionErrorCallback.h1
-rw-r--r--WebCore/page/PrintContext.cpp62
-rw-r--r--WebCore/page/PrintContext.h9
-rw-r--r--WebCore/page/SecurityOrigin.cpp226
-rw-r--r--WebCore/page/SecurityOrigin.h24
-rw-r--r--WebCore/page/Settings.cpp63
-rw-r--r--WebCore/page/Settings.h50
-rw-r--r--WebCore/page/SpatialNavigation.cpp530
-rw-r--r--WebCore/page/SpatialNavigation.h129
-rw-r--r--WebCore/page/UserContentURLPattern.cpp43
-rw-r--r--WebCore/page/UserContentURLPattern.h4
-rw-r--r--WebCore/page/XSSAuditor.cpp71
-rw-r--r--WebCore/page/XSSAuditor.h28
-rw-r--r--WebCore/page/ZoomMode.h32
-rw-r--r--WebCore/page/animation/AnimationBase.cpp60
-rw-r--r--WebCore/page/animation/AnimationBase.h5
-rw-r--r--WebCore/page/animation/AnimationController.cpp3
-rw-r--r--WebCore/page/animation/CompositeAnimation.cpp2
-rw-r--r--WebCore/page/animation/KeyframeAnimation.cpp21
-rw-r--r--WebCore/page/brew/EventHandlerBrew.cpp127
-rw-r--r--WebCore/page/chromium/ChromeClientChromium.h5
-rw-r--r--WebCore/page/chromium/DragControllerChromium.cpp5
-rw-r--r--WebCore/page/efl/DragControllerEfl.cpp69
-rw-r--r--WebCore/page/efl/EventHandlerEfl.cpp138
-rw-r--r--WebCore/page/efl/FrameEfl.cpp (renamed from WebCore/page/win/PageWin.cpp)18
-rw-r--r--WebCore/page/haiku/EventHandlerHaiku.cpp34
-rw-r--r--WebCore/page/mac/FrameMac.mm8
-rw-r--r--WebCore/page/mac/WebCoreViewFactory.h3
-rw-r--r--WebCore/page/qt/EventHandlerQt.cpp6
68 files changed, 2783 insertions, 537 deletions
diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp
index cb7f6bf..b3df888 100644
--- a/WebCore/page/Chrome.cpp
+++ b/WebCore/page/Chrome.cpp
@@ -67,9 +67,19 @@ Chrome::~Chrome()
m_client->chromeDestroyed();
}
-void Chrome::repaint(const IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly)
+void Chrome::invalidateWindow(const IntRect& updateRect, bool immediate)
{
- m_client->repaint(windowRect, contentChanged, immediate, repaintContentOnly);
+ m_client->invalidateWindow(updateRect, immediate);
+}
+
+void Chrome::invalidateContentsAndWindow(const IntRect& updateRect, bool immediate)
+{
+ m_client->invalidateContentsAndWindow(updateRect, immediate);
+}
+
+void Chrome::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
+{
+ m_client->invalidateContentsForSlowScroll(updateRect, immediate);
}
void Chrome::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
@@ -334,7 +344,7 @@ void Chrome::mouseDidMoveOverElement(const HitTestResult& result, unsigned modif
if (result.innerNode()) {
Document* document = result.innerNode()->document();
if (document && document->isDNSPrefetchEnabled())
- prefetchDNS(result.absoluteLinkURL().host());
+ ResourceHandle::prepareForURL(result.absoluteLinkURL());
}
m_client->mouseDidMoveOverElement(result, modifierFlags);
@@ -417,9 +427,15 @@ void Chrome::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geo
m_client->requestGeolocationPermissionForFrame(frame, geolocation);
}
+<<<<<<< HEAD
void Chrome::cancelGeolocationPermissionRequestForFrame(Frame* frame)
{
m_client->cancelGeolocationPermissionRequestForFrame(frame);
+=======
+void Chrome::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocation* geolocation)
+{
+ m_client->cancelGeolocationPermissionRequestForFrame(frame, geolocation);
+>>>>>>> webkit.org at r58033
}
void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
@@ -427,9 +443,9 @@ void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
m_client->runOpenPanel(frame, fileChooser);
}
-void Chrome::iconForFiles(const Vector<String>& filenames, PassRefPtr<FileChooser> fileChooser)
+void Chrome::chooseIconForFiles(const Vector<String>& filenames, FileChooser* fileChooser)
{
- m_client->iconForFiles(filenames, fileChooser);
+ m_client->chooseIconForFiles(filenames, fileChooser);
}
bool Chrome::setCursor(PlatformCursorHandle cursor)
diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h
index 9227f87..ec58de2 100644
--- a/WebCore/page/Chrome.h
+++ b/WebCore/page/Chrome.h
@@ -60,8 +60,11 @@ namespace WebCore {
ChromeClient* client() { return m_client; }
// HostWindow methods.
- virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false);
- virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
+
+ virtual void invalidateWindow(const IntRect&, bool);
+ virtual void invalidateContentsAndWindow(const IntRect&, bool);
+ virtual void invalidateContentsForSlowScroll(const IntRect&, bool);
+ virtual void scroll(const IntSize&, const IntRect&, const IntRect&);
virtual IntPoint screenToWindow(const IntPoint&) const;
virtual IntRect windowToScreen(const IntRect&) const;
virtual PlatformPageClient platformPageClient() const;
@@ -133,10 +136,14 @@ namespace WebCore {
void print(Frame*);
void requestGeolocationPermissionForFrame(Frame*, Geolocation*);
+<<<<<<< HEAD
void cancelGeolocationPermissionRequestForFrame(Frame*);
+=======
+ void cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*);
+>>>>>>> webkit.org at r58033
void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
- void iconForFiles(const Vector<String>&, PassRefPtr<FileChooser>);
+ void chooseIconForFiles(const Vector<String>&, FileChooser*);
bool setCursor(PlatformCursorHandle);
diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h
index 1b8b734..e0b70e0 100644
--- a/WebCore/page/ChromeClient.h
+++ b/WebCore/page/ChromeClient.h
@@ -56,6 +56,7 @@ namespace WebCore {
class Widget;
struct FrameLoadRequest;
+ struct ViewportArguments;
struct WindowFeatures;
#if USE(ACCELERATED_COMPOSITING)
@@ -133,8 +134,10 @@ namespace WebCore {
virtual IntRect windowResizerRect() const = 0;
// Methods used by HostWindow.
- virtual void repaint(const IntRect&, bool contentChanged, bool immediate = false, bool repaintContentOnly = false) = 0;
- virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) = 0;
+ virtual void invalidateWindow(const IntRect&, bool) = 0;
+ virtual void invalidateContentsAndWindow(const IntRect&, bool) = 0;
+ virtual void invalidateContentsForSlowScroll(const IntRect&, bool) = 0;
+ virtual void scroll(const IntSize&, const IntRect&, const IntRect&) = 0;
virtual IntPoint screenToWindow(const IntPoint&) const = 0;
virtual IntRect windowToScreen(const IntRect&) const = 0;
virtual PlatformPageClient platformPageClient() const = 0;
@@ -147,6 +150,8 @@ namespace WebCore {
virtual void setToolTip(const String&, TextDirection) = 0;
+ virtual void didReceiveViewportArguments(Frame*, const ViewportArguments&) const { }
+
virtual void print(Frame*) = 0;
#if ENABLE(DATABASE)
@@ -187,12 +192,15 @@ namespace WebCore {
// This can be either a synchronous or asynchronous call. The ChromeClient can display UI asking the user for permission
// to use Geolocation.
virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*) = 0;
+<<<<<<< HEAD
virtual void cancelGeolocationPermissionRequestForFrame(Frame*) = 0;
+=======
+ virtual void cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*) = 0;
+>>>>>>> webkit.org at r58033
virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0;
// Asynchronous request to load an icon for specified filenames.
- // This is called only if Icon::createIconForFiles() returns 0.
- virtual void iconForFiles(const Vector<String>&, PassRefPtr<FileChooser>) = 0;
+ virtual void chooseIconForFiles(const Vector<String>&, FileChooser*) = 0;
virtual bool setCursor(PlatformCursorHandle) = 0;
@@ -214,6 +222,9 @@ namespace WebCore {
// Sets a flag to specify that the view needs to be updated, so we need
// to do an eager layout before the drawing.
virtual void scheduleCompositingLayerSync() = 0;
+ // Returns whether or not the client can render the composited layer,
+ // regardless of the settings.
+ virtual bool allowsAcceleratedCompositing() const { return true; }
#endif
virtual bool supportsFullscreenForNode(const Node*) { return false; }
@@ -233,6 +244,14 @@ namespace WebCore {
virtual void needTouchEvents(bool) = 0;
#endif
+#if ENABLE(WIDGETS_10_SUPPORT)
+ virtual bool isWindowed() { return false; }
+ virtual bool isFloating() { return false; }
+ virtual bool isFullscreen() { return false; }
+ virtual bool isMaximized() { return false; }
+ virtual bool isMinimized() { return false; }
+#endif
+
protected:
virtual ~ChromeClient() { }
};
diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp
index 99b3106..d5ff7bc 100644
--- a/WebCore/page/Console.cpp
+++ b/WebCore/page/Console.cpp
@@ -29,7 +29,6 @@
#include "config.h"
#include "Console.h"
-#include "CString.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "ConsoleMessage.h"
@@ -45,6 +44,7 @@
#include "ScriptProfile.h"
#include "ScriptProfiler.h"
#include <stdio.h>
+#include <wtf/text/CString.h>
#include <wtf/UnusedParam.h>
namespace WebCore {
diff --git a/WebCore/page/Console.idl b/WebCore/page/Console.idl
index c08fcc0..b3c0c24 100644
--- a/WebCore/page/Console.idl
+++ b/WebCore/page/Console.idl
@@ -30,8 +30,7 @@ module window {
interface [OmitConstructor] Console {
- // Not enabled in V8 because it requires request-reply style.
-#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER && !(defined(V8_BINDING) && V8_BINDING)
+#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER
readonly attribute [CustomGetter] Array profiles;
#endif
diff --git a/WebCore/page/DOMSelection.cpp b/WebCore/page/DOMSelection.cpp
index 0d21c56..a583176 100644
--- a/WebCore/page/DOMSelection.cpp
+++ b/WebCore/page/DOMSelection.cpp
@@ -207,6 +207,10 @@ void DOMSelection::collapse(Node* node, int offset, ExceptionCode& ec)
ec = INDEX_SIZE_ERR;
return;
}
+
+ if (!isValidForPosition(node))
+ return;
+
m_frame->selection()->moveTo(VisiblePosition(node, offset, DOWNSTREAM));
}
@@ -244,6 +248,10 @@ void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extent
ec = INDEX_SIZE_ERR;
return;
}
+
+ if (!isValidForPosition(baseNode) || !isValidForPosition(extentNode))
+ return;
+
VisiblePosition visibleBase = VisiblePosition(baseNode, baseOffset, DOWNSTREAM);
VisiblePosition visibleExtent = VisiblePosition(extentNode, extentOffset, DOWNSTREAM);
@@ -258,6 +266,10 @@ void DOMSelection::setPosition(Node* node, int offset, ExceptionCode& ec)
ec = INDEX_SIZE_ERR;
return;
}
+
+ if (!isValidForPosition(node))
+ return;
+
m_frame->selection()->moveTo(VisiblePosition(node, offset, DOWNSTREAM));
}
@@ -320,14 +332,16 @@ void DOMSelection::extend(Node* node, int offset, ExceptionCode& ec)
ec = TYPE_MISMATCH_ERR;
return;
}
+
if (offset < 0 || offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node->childNodeCount())) {
ec = INDEX_SIZE_ERR;
return;
}
- SelectionController* selection = m_frame->selection();
- selection->expandUsingGranularity(CharacterGranularity);
- selection->setExtent(VisiblePosition(node, offset, DOWNSTREAM));
+ if (!isValidForPosition(node))
+ return;
+
+ m_frame->selection()->setExtent(VisiblePosition(node, offset, DOWNSTREAM));
}
PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionCode& ec)
@@ -429,7 +443,7 @@ bool DOMSelection::containsNode(const Node* n, bool allowPartial) const
SelectionController* selection = m_frame->selection();
- if (!n || selection->isNone())
+ if (!n || m_frame->document() != n->document() || selection->isNone())
return false;
Node* parentNode = n->parentNode();
@@ -472,4 +486,12 @@ String DOMSelection::toString()
return plainText(m_frame->selection()->selection().toNormalizedRange().get());
}
+bool DOMSelection::isValidForPosition(Node* node) const
+{
+ ASSERT(m_frame);
+ if (!node)
+ return true;
+ return node->document() == m_frame->document();
+}
+
} // namespace WebCore
diff --git a/WebCore/page/DOMSelection.h b/WebCore/page/DOMSelection.h
index e0fe1e3..0287e44 100644
--- a/WebCore/page/DOMSelection.h
+++ b/WebCore/page/DOMSelection.h
@@ -96,6 +96,7 @@ namespace WebCore {
// Convenience method for accessors, does not NULL check m_frame.
const VisibleSelection& visibleSelection() const;
+ bool isValidForPosition(Node*) const;
Frame* m_frame;
};
diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp
index 6af22c3..c74cfaf 100644
--- a/WebCore/page/DOMWindow.cpp
+++ b/WebCore/page/DOMWindow.cpp
@@ -26,15 +26,16 @@
#include "config.h"
#include "DOMWindow.h"
+#include "Base64.h"
#include "BarInfo.h"
#include "BeforeUnloadEvent.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSRuleList.h"
#include "CSSStyleSelector.h"
-#include "CString.h"
#include "Chrome.h"
#include "Console.h"
#include "Database.h"
+#include "DatabaseCallback.h"
#include "DOMApplicationCache.h"
#include "DOMSelection.h"
#include "DOMTimer.h"
@@ -52,6 +53,8 @@
#include "FrameView.h"
#include "HTMLFrameOwnerElement.h"
#include "History.h"
+#include "IndexedDatabase.h"
+#include "IndexedDatabaseRequest.h"
#include "InspectorController.h"
#include "InspectorTimelineAgent.h"
#include "Location.h"
@@ -73,6 +76,7 @@
#include "SuddenTermination.h"
#include "WebKitPoint.h"
#include <algorithm>
+#include <wtf/text/CString.h>
#include <wtf/MathExtras.h>
using std::min;
@@ -466,6 +470,12 @@ void DOMWindow::clear()
m_notifications->disconnectFrame();
m_notifications = 0;
#endif
+
+#if ENABLE(INDEXED_DATABASE)
+ if (m_indexedDatabaseRequest)
+ m_indexedDatabaseRequest->disconnectFrame();
+ m_indexedDatabaseRequest = 0;
+#endif
}
#if ENABLE(ORIENTATION_EVENTS)
@@ -573,9 +583,6 @@ Storage* DOMWindow::sessionStorage() const
Document* document = this->document();
if (!document)
return 0;
-
- if (!document->securityOrigin()->canAccessStorage())
- return 0;
Page* page = document->page();
if (!page)
@@ -590,7 +597,7 @@ Storage* DOMWindow::sessionStorage() const
return m_sessionStorage.get();
}
-Storage* DOMWindow::localStorage() const
+Storage* DOMWindow::localStorage(ExceptionCode& ec) const
{
if (m_localStorage)
return m_localStorage.get();
@@ -599,8 +606,10 @@ Storage* DOMWindow::localStorage() const
if (!document)
return 0;
- if (!document->securityOrigin()->canAccessStorage())
+ if (!document->securityOrigin()->canAccessLocalStorage()) {
+ ec = SECURITY_ERR;
return 0;
+ }
Page* page = document->page();
if (!page)
@@ -644,7 +653,23 @@ NotificationCenter* DOMWindow::webkitNotifications() const
#if ENABLE(INDEXED_DATABASE)
IndexedDatabaseRequest* DOMWindow::indexedDB() const
{
- return 0;
+ if (m_indexedDatabaseRequest)
+ return m_indexedDatabaseRequest.get();
+
+ Document* document = this->document();
+ if (!document)
+ return 0;
+
+ // FIXME: See if access is allowed.
+
+ Page* page = document->page();
+ if (!page)
+ return 0;
+
+ // FIXME: See if indexedDatabase access is allowed.
+
+ m_indexedDatabaseRequest = IndexedDatabaseRequest::create(page->group().indexedDatabase(), m_frame);
+ return m_indexedDatabaseRequest.get();
}
#endif
@@ -826,6 +851,57 @@ String DOMWindow::prompt(const String& message, const String& defaultValue)
return String();
}
+static bool isSafeToConvertCharList(const String& string)
+{
+ for (unsigned i = 0; i < string.length(); i++) {
+ if (string[i] > 0xFF)
+ return false;
+ }
+
+ return true;
+}
+
+String DOMWindow::btoa(const String& stringToEncode, ExceptionCode& ec)
+{
+ if (stringToEncode.isNull())
+ return String();
+
+ if (!isSafeToConvertCharList(stringToEncode)) {
+ ec = INVALID_CHARACTER_ERR;
+ return String();
+ }
+
+ Vector<char> in;
+ in.append(stringToEncode.characters(), stringToEncode.length());
+ Vector<char> out;
+
+ base64Encode(in, out);
+
+ return String(out.data(), out.size());
+}
+
+String DOMWindow::atob(const String& encodedString, ExceptionCode& ec)
+{
+ if (encodedString.isNull())
+ return String();
+
+ if (!isSafeToConvertCharList(encodedString)) {
+ ec = INVALID_CHARACTER_ERR;
+ return String();
+ }
+
+ Vector<char> in;
+ in.append(encodedString.characters(), encodedString.length());
+ Vector<char> out;
+
+ if (!base64Decode(in, out)) {
+ ec = INVALID_CHARACTER_ERR;
+ return String();
+ }
+
+ return String(out.data(), out.size());
+}
+
bool DOMWindow::find(const String& string, bool caseSensitive, bool backwards, bool wrap, bool /*wholeWord*/, bool /*searchInFrames*/, bool /*showDialog*/) const
{
if (!m_frame)
@@ -1067,24 +1143,20 @@ PassRefPtr<Media> DOMWindow::media() const
return m_media.get();
}
-PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* elt, const String&) const
+PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* elt, const String& pseudoElt) const
{
if (!elt)
return 0;
- // FIXME: This needs take pseudo elements into account.
- return computedStyle(elt);
+ return computedStyle(elt, false, pseudoElt);
}
-PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* elt, const String& pseudoElt, bool authorOnly) const
+PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* elt, const String&, bool authorOnly) const
{
if (!m_frame)
return 0;
Document* doc = m_frame->document();
-
- if (!pseudoElt.isEmpty())
- return doc->styleSelector()->pseudoStyleRulesForElement(elt, pseudoElt, authorOnly);
return doc->styleSelector()->styleRulesForElement(elt, authorOnly);
}
@@ -1125,20 +1197,16 @@ double DOMWindow::devicePixelRatio() const
}
#if ENABLE(DATABASE)
-PassRefPtr<Database> DOMWindow::openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, ExceptionCode& ec)
+PassRefPtr<Database> DOMWindow::openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode& ec)
{
- if (!m_frame)
- return 0;
+ RefPtr<Database> database = 0;
+ if (m_frame && Database::isAvailable() && m_frame->document()->securityOrigin()->canAccessDatabase())
+ database = Database::openDatabase(m_frame->document(), name, version, displayName, estimatedSize, creationCallback, ec);
- Document* document = m_frame->document();
- if (!document->securityOrigin()->canAccessDatabase())
- return 0;
+ if (!database && !ec)
+ ec = SECURITY_ERR;
- Settings* settings = m_frame->settings();
- if (!settings || !settings->databasesEnabled())
- return 0;
-
- return Database::openDatabase(document, name, version, displayName, estimatedSize, ec);
+ return database;
}
#endif
@@ -1359,20 +1427,21 @@ bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget
event->setEventPhase(Event::AT_TARGET);
#if ENABLE(INSPECTOR)
- InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent();
- bool timelineAgentIsActive = timelineAgent && hasEventListeners(event->type());
- if (timelineAgentIsActive)
- timelineAgent->willDispatchEvent(*event);
+ Page* inspectedPage = InspectorTimelineAgent::instanceCount() && frame() ? frame()->page() : 0;
+ if (inspectedPage) {
+ if (InspectorTimelineAgent* timelineAgent = hasEventListeners(event->type()) ? inspectedPage->inspectorTimelineAgent() : 0)
+ timelineAgent->willDispatchEvent(*event);
+ else
+ inspectedPage = 0;
+ }
#endif
bool result = fireEventListeners(event.get());
#if ENABLE(INSPECTOR)
- if (timelineAgentIsActive) {
- timelineAgent = inspectorTimelineAgent();
- if (timelineAgent)
+ if (inspectedPage)
+ if (InspectorTimelineAgent* timelineAgent = inspectedPage->inspectorTimelineAgent())
timelineAgent->didDispatchEvent();
- }
#endif
return result;
diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h
index 4452dbb..c3a781c 100644
--- a/WebCore/page/DOMWindow.h
+++ b/WebCore/page/DOMWindow.h
@@ -45,6 +45,7 @@ namespace WebCore {
class Console;
class DOMSelection;
class Database;
+ class DatabaseCallback;
class Document;
class Element;
class Event;
@@ -139,6 +140,8 @@ namespace WebCore {
void alert(const String& message);
bool confirm(const String& message);
String prompt(const String& message, const String& defaultValue);
+ String btoa(const String& stringToEncode, ExceptionCode&);
+ String atob(const String& encodedString, ExceptionCode&);
bool find(const String&, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const;
@@ -198,13 +201,13 @@ namespace WebCore {
#if ENABLE(DATABASE)
// HTML 5 client-side database
- PassRefPtr<Database> openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, ExceptionCode&);
+ PassRefPtr<Database> openDatabase(const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback, ExceptionCode&);
#endif
#if ENABLE(DOM_STORAGE)
// HTML 5 key/value storage
Storage* sessionStorage() const;
- Storage* localStorage() const;
+ Storage* localStorage(ExceptionCode&) const;
#endif
Console* console() const;
@@ -398,6 +401,9 @@ namespace WebCore {
#if ENABLE(NOTIFICATIONS)
mutable RefPtr<NotificationCenter> m_notifications;
#endif
+#if ENABLE(INDEXED_DATABASE)
+ mutable RefPtr<IndexedDatabaseRequest> m_indexedDatabaseRequest;
+#endif
EventTargetData m_eventTargetData;
};
diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl
index a4b72d2..018b4de 100644
--- a/WebCore/page/DOMWindow.idl
+++ b/WebCore/page/DOMWindow.idl
@@ -160,12 +160,13 @@ module window {
readonly attribute [EnabledAtRuntime] DOMApplicationCache applicationCache;
#endif
#if defined(ENABLE_DATABASE) && ENABLE_DATABASE
- [EnabledAtRuntime] Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize)
+ [EnabledAtRuntime, Custom] Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in DatabaseCallback creationCallback)
raises(DOMException);
#endif
#if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE
readonly attribute [EnabledAtRuntime] Storage sessionStorage;
- readonly attribute [EnabledAtRuntime] Storage localStorage;
+ readonly attribute [EnabledAtRuntime] Storage localStorage
+ getter raises(DOMException);
#endif
#if defined(ENABLE_NOTIFICATIONS) && ENABLE_NOTIFICATIONS
readonly attribute [EnabledAtRuntime] NotificationCenter webkitNotifications;
@@ -204,9 +205,9 @@ module window {
void clearInterval(in long handle);
// Base64
- [Custom] DOMString atob(in DOMString string)
+ DOMString atob(in [ConvertNullToNullString] DOMString string)
raises(DOMException);
- [Custom] DOMString btoa(in DOMString string)
+ DOMString btoa(in [ConvertNullToNullString] DOMString string)
raises(DOMException);
// Events
@@ -293,12 +294,10 @@ module window {
#if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS
attribute EventListener onorientationchange;
#endif
- #if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
- attribute [DontEnum] EventListener ontouchstart;
- attribute [DontEnum] EventListener ontouchmove;
- attribute [DontEnum] EventListener ontouchend;
- attribute [DontEnum] EventListener ontouchcancel;
- #endif
+ attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchstart;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchmove;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchend;
+ attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchcancel;
// EventTarget interface
[Custom] void addEventListener(in DOMString type,
@@ -421,6 +420,9 @@ module window {
attribute HTMLParagraphElementConstructor HTMLParagraphElement;
attribute HTMLParamElementConstructor HTMLParamElement;
attribute HTMLPreElementConstructor HTMLPreElement;
+#if defined(ENABLE_PROGRESS_TAG) && ENABLE_PROGRESS_TAG
+ attribute HTMLProgressElementConstructor HTMLProgressElement;
+#endif
attribute HTMLQuoteElementConstructor HTMLQuoteElement;
attribute HTMLScriptElementConstructor HTMLScriptElement;
attribute HTMLSelectElementConstructor HTMLSelectElement;
@@ -443,17 +445,17 @@ module window {
attribute CanvasRenderingContext2DConstructor CanvasRenderingContext2D;
attribute ImageDataConstructor ImageData;
- attribute [Conditional=3D_CANVAS] WebGLRenderingContextConstructor WebGLRenderingContext;
+ attribute [Conditional=3D_CANVAS,EnabledAtRuntime] WebGLRenderingContextConstructor WebGLRenderingContext;
attribute TextMetricsConstructor TextMetrics;
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] WebGLArrayBufferConstructor WebGLArrayBuffer; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] WebGLByteArrayConstructor WebGLByteArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] WebGLUnsignedByteArrayConstructor WebGLUnsignedByteArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] WebGLShortArrayConstructor WebGLShortArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] WebGLUnsignedShortArrayConstructor WebGLUnsignedShortArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] WebGLIntArrayConstructor WebGLIntArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] WebGLUnsignedIntArrayConstructor WebGLUnsignedIntArray; // Usable with new operator
- attribute [JSCCustomGetter,Conditional=3D_CANVAS] WebGLFloatArrayConstructor WebGLFloatArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLArrayBufferConstructor WebGLArrayBuffer; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLByteArrayConstructor WebGLByteArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLUnsignedByteArrayConstructor WebGLUnsignedByteArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLShortArrayConstructor WebGLShortArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLUnsignedShortArrayConstructor WebGLUnsignedShortArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLIntArrayConstructor WebGLIntArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLUnsignedIntArrayConstructor WebGLUnsignedIntArray; // Usable with new operator
+ attribute [JSCCustomGetter,Conditional=3D_CANVAS,EnabledAtRuntime] WebGLFloatArrayConstructor WebGLFloatArray; // Usable with new operator
attribute EventConstructor Event;
attribute BeforeLoadEventConstructor BeforeLoadEvent;
@@ -709,9 +711,9 @@ module window {
#endif
#endif
-#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
- attribute TouchEventConstructor TouchEvent;
-#endif
+ attribute [Conditional=TOUCH_EVENTS] TouchEventConstructor TouchEvent;
+
+ attribute DOMFormDataConstructor FormData;
#endif // defined(LANGUAGE_JAVASCRIPT)
diff --git a/WebCore/page/DragController.cpp b/WebCore/page/DragController.cpp
index 18e3195..f238b27 100644
--- a/WebCore/page/DragController.cpp
+++ b/WebCore/page/DragController.cpp
@@ -53,6 +53,7 @@
#include "MoveSelectionCommand.h"
#include "Node.h"
#include "Page.h"
+#include "PlatformKeyboardEvent.h"
#include "RenderFileUploadControl.h"
#include "RenderImage.h"
#include "RenderView.h"
@@ -70,10 +71,12 @@ namespace WebCore {
static PlatformMouseEvent createMouseEvent(DragData* dragData)
{
- // FIXME: We should fake modifier keys here.
+ bool shiftKey, ctrlKey, altKey, metaKey;
+ shiftKey = ctrlKey = altKey = metaKey = false;
+ PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
return PlatformMouseEvent(dragData->clientPosition(), dragData->globalPosition(),
- LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime());
-
+ LeftButton, MouseEventMoved, 0, shiftKey, ctrlKey, altKey,
+ metaKey, currentTime());
}
DragController::DragController(Page* page, DragClient* client)
@@ -429,10 +432,11 @@ bool DragController::concludeEditDrag(DragData* dragData)
m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData);
if (dragIsMove(innerFrame->selection())) {
- bool smartMove = innerFrame->selectionGranularity() == WordGranularity
- && innerFrame->editor()->smartInsertDeleteEnabled()
- && dragData->canSmartReplace();
- applyCommand(MoveSelectionCommand::create(fragment, dragCaret.base(), smartMove));
+ // NSTextView behavior is to always smart delete on moving a selection,
+ // but only to smart insert if the selection granularity is word granularity.
+ bool smartDelete = innerFrame->editor()->smartInsertDeleteEnabled();
+ bool smartInsert = smartDelete && innerFrame->selectionGranularity() == WordGranularity && dragData->canSmartReplace();
+ applyCommand(MoveSelectionCommand::create(fragment, dragCaret.base(), smartInsert, smartDelete));
} else {
if (setSelectionToDragCaret(innerFrame, dragCaret, range, point))
applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse, fragment, true, dragData->canSmartReplace(), chosePlainText));
@@ -482,6 +486,25 @@ bool DragController::canProcessDrag(DragData* dragData)
return true;
}
+static DragOperation defaultOperationForDrag(DragOperation srcOpMask)
+{
+ // This is designed to match IE's operation fallback for the case where
+ // the page calls preventDefault() in a drag event but doesn't set dropEffect.
+ if (srcOpMask == DragOperationEvery)
+ return DragOperationCopy;
+ if (srcOpMask == DragOperationNone)
+ return DragOperationNone;
+ if (srcOpMask & DragOperationMove || srcOpMask & DragOperationGeneric)
+ return DragOperationMove;
+ if (srcOpMask & DragOperationCopy)
+ return DragOperationCopy;
+ if (srcOpMask & DragOperationLink)
+ return DragOperationLink;
+
+ // FIXME: Does IE really return "generic" even if no operations were allowed by the source?
+ return DragOperationGeneric;
+}
+
bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
{
ASSERT(dragData);
@@ -503,7 +526,9 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
}
operation = clipboard->destinationOperation();
- if (!(srcOpMask & operation)) {
+ if (clipboard->dropEffectIsUninitialized())
+ operation = defaultOperationForDrag(srcOpMask);
+ else if (!(srcOpMask & operation)) {
// The element picked an operation which is not supported by the source
operation = DragOperationNone;
}
@@ -512,7 +537,7 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
return true;
}
-bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPoint& framePos)
+bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPoint& framePos, Node* node)
{
ASSERT(frame);
ASSERT(frame->settings());
@@ -523,6 +548,8 @@ bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPo
HitTestResult mouseDownTarget = HitTestResult(framePos);
mouseDownTarget = frame->eventHandler()->hitTestResultAtPoint(framePos, true);
+ if (node)
+ mouseDownTarget.setInnerNonSharedNode(node);
if (mouseDownTarget.image()
&& !mouseDownTarget.absoluteImageURL().isEmpty()
@@ -532,7 +559,8 @@ bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPo
if (!mouseDownTarget.absoluteLinkURL().isEmpty()
&& m_dragSourceAction & DragSourceActionLink
- && mouseDownTarget.isLiveLink())
+ && mouseDownTarget.isLiveLink()
+ && mouseDownTarget.URLElement()->renderer() && mouseDownTarget.URLElement()->renderer()->style()->userDrag() != DRAG_NONE)
return true;
if (mouseDownTarget.isSelected()
@@ -540,7 +568,6 @@ bool DragController::mayStartDragAtEventLocation(const Frame* frame, const IntPo
return true;
return false;
-
}
static CachedImage* getCachedImage(Element* element)
diff --git a/WebCore/page/DragController.h b/WebCore/page/DragController.h
index 3d59ebf..3b2b083 100644
--- a/WebCore/page/DragController.h
+++ b/WebCore/page/DragController.h
@@ -77,7 +77,7 @@ namespace WebCore {
DragDestinationAction dragDestinationAction() const { return m_dragDestinationAction; }
DragSourceAction delegateDragSourceAction(const IntPoint& pagePoint);
- bool mayStartDragAtEventLocation(const Frame*, const IntPoint& framePos);
+ bool mayStartDragAtEventLocation(const Frame*, const IntPoint& framePos, Node*);
void dragEnded();
void placeDragCaret(const IntPoint&);
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index a950407..df8759a 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
*
* Redistribution and use in source and binary forms, with or without
@@ -57,7 +57,11 @@
#include "Page.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformWheelEvent.h"
+<<<<<<< HEAD
#include "PluginView.h"
+=======
+#include "PluginDocument.h"
+>>>>>>> webkit.org at r58033
#include "RenderFrameSet.h"
#include "RenderTextControlSingleLine.h"
#include "RenderView.h"
@@ -66,7 +70,10 @@
#include "SelectionController.h"
#include "Settings.h"
#include "TextEvent.h"
+#include "UserGestureIndicator.h"
+#include "WheelEvent.h"
#include "htmlediting.h" // for comparePositions()
+#include <wtf/CurrentTime.h>
#include <wtf/StdLibExtras.h>
#if ENABLE(SVG)
@@ -110,25 +117,33 @@ using namespace SVGNames;
// When the autoscroll or the panScroll is triggered when do the scroll every 0.05s to make it smooth
const double autoscrollInterval = 0.05;
+const double fakeMouseMoveInterval = 0.1;
+
static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
-static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node, Node** stopNode)
+static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, ScrollDirection positiveDirection, ScrollDirection negativeDirection, Node* node, Node** stopNode)
{
if (!delta)
- return;
-
+ return false;
+
+ if (!node->renderer())
+ return false;
+
// Find the nearest enclosing box.
RenderBox* enclosingBox = node->renderer()->enclosingBox();
- if (e.granularity() == ScrollByPageWheelEvent) {
- if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1, stopNode))
- e.accept();
- return;
- }
+ float absDelta = delta > 0 ? delta : -delta;
+
+ if (granularity == WheelEvent::Page)
+ return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, absDelta, stopNode);
+
+ if (granularity == WheelEvent::Line)
+ return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByLine, absDelta, stopNode);
- float pixelsToScroll = delta > 0 ? delta : -delta;
- if (enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll, stopNode))
- e.accept();
+ if (granularity == WheelEvent::Pixel)
+ return enclosingBox->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, absDelta, stopNode);
+
+ return false;
}
#if !PLATFORM(MAC) || ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
@@ -166,6 +181,7 @@ EventHandler::EventHandler(Frame* frame)
, m_autoscrollInProgress(false)
, m_mouseDownMayStartAutoscroll(false)
, m_mouseDownWasInSubframe(false)
+ , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFired)
#if ENABLE(SVG)
, m_svgPan(false)
#endif
@@ -185,6 +201,7 @@ EventHandler::EventHandler(Frame* frame)
EventHandler::~EventHandler()
{
+ ASSERT(!m_fakeMouseMoveEventTimer.isActive());
}
#if ENABLE(DRAG_SUPPORT)
@@ -198,6 +215,7 @@ EventHandler::EventHandlerDragState& EventHandler::dragState()
void EventHandler::clear()
{
m_hoverTimer.stop();
+ m_fakeMouseMoveEventTimer.stop();
m_resizeLayer = 0;
m_nodeUnderMouse = 0;
m_lastNodeUnderMouse = 0;
@@ -233,20 +251,21 @@ void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestRe
if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) {
VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
+ TextGranularity granularity = CharacterGranularity;
if (pos.isNotNull()) {
newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(WordGranularity);
}
if (newSelection.isRange()) {
- m_frame->setSelectionGranularity(WordGranularity);
+ granularity = WordGranularity;
m_beganSelectingText = true;
if (result.event().clickCount() == 2 && m_frame->editor()->isSelectTrailingWhitespaceEnabled())
newSelection.appendTrailingWhitespace();
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection, granularity);
}
}
@@ -264,13 +283,14 @@ void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit
if (pos.isNotNull() && pos.deepEquivalent().node()->isDescendantOf(URLElement))
newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
+ TextGranularity granularity = CharacterGranularity;
if (newSelection.isRange()) {
- m_frame->setSelectionGranularity(WordGranularity);
+ granularity = WordGranularity;
m_beganSelectingText = true;
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection, granularity);
}
}
@@ -307,13 +327,15 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR
newSelection = VisibleSelection(pos);
newSelection.expandUsingGranularity(ParagraphGranularity);
}
+
+ TextGranularity granularity = CharacterGranularity;
if (newSelection.isRange()) {
- m_frame->setSelectionGranularity(ParagraphGranularity);
+ granularity = ParagraphGranularity;
m_beganSelectingText = true;
}
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection, granularity);
return true;
}
@@ -343,8 +365,10 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
Position pos = visiblePos.deepEquivalent();
VisibleSelection newSelection = m_frame->selection()->selection();
+ TextGranularity granularity = CharacterGranularity;
+
if (extendSelection && newSelection.isCaretOrRange()) {
- m_frame->selection()->setLastChangeWasHorizontalExtension(false);
+ m_frame->selection()->setIsDirectional(false);
// See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
// was created right-to-left
@@ -355,16 +379,17 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
else
newSelection = VisibleSelection(start, pos);
- if (m_frame->selectionGranularity() != CharacterGranularity)
+ if (m_frame->selectionGranularity() != CharacterGranularity) {
+ granularity = m_frame->selectionGranularity();
newSelection.expandUsingGranularity(m_frame->selectionGranularity());
+ }
+
m_beganSelectingText = true;
- } else {
+ } else
newSelection = VisibleSelection(visiblePos);
- m_frame->setSelectionGranularity(CharacterGranularity);
- }
if (m_frame->shouldChangeSelection(newSelection))
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setSelection(newSelection, granularity);
return true;
}
@@ -376,6 +401,8 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
dragState().m_dragSrc = 0;
#endif
+ cancelFakeMouseMoveEvent();
+
if (ScrollView* scrollView = m_frame->view()) {
if (scrollView->isPointInScrollbarCorner(event.event().pos()))
return false;
@@ -576,8 +603,8 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint&
newSelection.expandUsingGranularity(m_frame->selectionGranularity());
if (m_frame->shouldChangeSelection(newSelection)) {
- m_frame->selection()->setLastChangeWasHorizontalExtension(false);
- m_frame->selection()->setSelection(newSelection);
+ m_frame->selection()->setIsDirectional(false);
+ m_frame->selection()->setSelection(newSelection, m_frame->selectionGranularity());
}
}
#endif // ENABLE(DRAG_SUPPORT)
@@ -1005,8 +1032,8 @@ Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scr
if (style && style->cursors()) {
const CursorList* cursors = style->cursors();
for (unsigned i = 0; i < cursors->size(); ++i) {
- CachedImage* cimage = (*cursors)[i].cursorImage.get();
- IntPoint hotSpot = (*cursors)[i].hotSpot;
+ const CachedImage* cimage = (*cursors)[i].image();
+ IntPoint hotSpot = (*cursors)[i].hotSpot();
if (!cimage)
continue;
// Limit the size of cursors so that they cannot be used to cover UI elements in chrome.
@@ -1151,6 +1178,9 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame->view());
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
+
+ cancelFakeMouseMoveEvent();
m_mousePressed = true;
m_capturesDragging = true;
m_currentMousePosition = mouseEvent.pos();
@@ -1185,7 +1215,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
if (Page* page = m_frame->page()) {
InspectorController* inspector = page->inspectorController();
if (inspector && inspector->enabled() && inspector->searchingForNodeInPage()) {
- inspector->handleMousePressOnNode(m_mousePressNode.get());
+ inspector->handleMousePress();
invalidateClick();
return true;
}
@@ -1279,6 +1309,8 @@ bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEv
{
RefPtr<FrameView> protector(m_frame->view());
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
+
// We get this instead of a second mouse-up
m_mousePressed = false;
m_currentMousePosition = mouseEvent.pos();
@@ -1342,6 +1374,8 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
if (m_hoverTimer.isActive())
m_hoverTimer.stop();
+ cancelFakeMouseMoveEvent();
+
#if ENABLE(SVG)
if (m_svgPan) {
static_cast<SVGDocument*>(m_frame->document())->updatePan(m_currentMousePosition);
@@ -1404,8 +1438,18 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, Hi
scrollbar->mouseMoved(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
if (Page* page = m_frame->page()) {
if ((!m_resizeLayer || !m_resizeLayer->inResizeMode()) && !page->mainFrame()->eventHandler()->panScrollInProgress()) {
- if (FrameView* view = m_frame->view())
- view->setCursor(selectCursor(mev, scrollbar));
+ // Plugins set cursor on their own. The only case WebKit intervenes is resetting cursor to arrow on mouse enter,
+ // in case the particular plugin doesn't manipulate cursor at all. Thus, even a CSS cursor set on body has no
+ // effect on plugins (which matches Firefox).
+ bool overPluginElement = false;
+ if (mev.targetNode() && mev.targetNode()->isHTMLElement()) {
+ HTMLElement* el = static_cast<HTMLElement*>(mev.targetNode());
+ overPluginElement = el->hasTagName(appletTag) || el->hasTagName(objectTag) || el->hasTagName(embedTag);
+ }
+ if (!overPluginElement) {
+ if (FrameView* view = m_frame->view())
+ view->setCursor(selectCursor(mev, scrollbar));
+ }
}
}
}
@@ -1433,6 +1477,8 @@ void EventHandler::invalidateClick()
bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
{
RefPtr<FrameView> protector(m_frame->view());
+
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
#if ENABLE(PAN_SCROLLING)
if (mouseEvent.button() == MiddleButton)
@@ -1863,21 +1909,6 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
node->dispatchWheelEvent(e);
if (e.isAccepted())
return true;
-
- // If we don't have a renderer, send the wheel event to the first node we find with a renderer.
- // This is needed for <option> and <optgroup> elements so that <select>s get a wheel scroll.
- while (node && !node->renderer())
- node = node->parent();
-
- if (node && node->renderer()) {
- // Just break up into two scrolls if we need to. Diagonal movement on
- // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
- Node* stopNode = m_previousWheelScrolledNode.get();
- scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node, &stopNode);
- scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node, &stopNode);
- if (!m_useLatchedWheelEventNode)
- m_previousWheelScrolledNode = stopNode;
- }
}
if (e.isAccepted())
@@ -1890,6 +1921,25 @@ bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
view->wheelEvent(e);
return e.isAccepted();
}
+
+void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEvent)
+{
+ if (!startNode || !wheelEvent)
+ return;
+
+ Node* stopNode = m_previousWheelScrolledNode.get();
+
+ // Break up into two scrolls if we need to. Diagonal movement on
+ // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
+ if (scrollNode(wheelEvent->rawDeltaX(), wheelEvent->granularity(), ScrollLeft, ScrollRight, startNode, &stopNode))
+ wheelEvent->setDefaultHandled();
+
+ if (scrollNode(wheelEvent->rawDeltaY(), wheelEvent->granularity(), ScrollUp, ScrollDown, startNode, &stopNode))
+ wheelEvent->setDefaultHandled();
+
+ if (!m_useLatchedWheelEventNode)
+ m_previousWheelScrolledNode = stopNode;
+}
#if ENABLE(CONTEXT_MENUS)
bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
@@ -1930,6 +1980,43 @@ void EventHandler::scheduleHoverStateUpdate()
m_hoverTimer.startOneShot(0);
}
+void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
+{
+ FrameView* view = m_frame->view();
+ if (!view)
+ return;
+
+ if (m_mousePressed || !quad.containsPoint(view->windowToContents(m_currentMousePosition)))
+ return;
+
+ if (!m_fakeMouseMoveEventTimer.isActive())
+ m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveInterval);
+}
+
+void EventHandler::cancelFakeMouseMoveEvent()
+{
+ m_fakeMouseMoveEventTimer.stop();
+}
+
+void EventHandler::fakeMouseMoveEventTimerFired(Timer<EventHandler>* timer)
+{
+ ASSERT_UNUSED(timer, timer == &m_fakeMouseMoveEventTimer);
+ ASSERT(!m_mousePressed);
+
+ FrameView* view = m_frame->view();
+ if (!view)
+ return;
+
+ bool shiftKey;
+ bool ctrlKey;
+ bool altKey;
+ bool metaKey;
+ PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
+ IntPoint globalPoint = view->contentsToScreen(IntRect(view->windowToContents(m_currentMousePosition), IntSize())).location();
+ PlatformMouseEvent fakeMouseMoveEvent(m_currentMousePosition, globalPoint, NoButton, MouseEventMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime());
+ mouseMoved(fakeMouseMoveEvent);
+}
+
// Whether or not a mouse down can begin the creation of a selection. Fires the selectStart event.
bool EventHandler::canMouseDownStartSelect(Node* node)
{
@@ -1996,6 +2083,7 @@ static Node* eventTargetNodeForDocument(Document* doc)
if (!doc)
return 0;
Node* node = doc->focusedNode();
+<<<<<<< HEAD
#if defined(ANDROID_PLUGINS)
if (!node && doc->frame() && doc->frame()->view())
@@ -2003,6 +2091,12 @@ static Node* eventTargetNodeForDocument(Document* doc)
->cursorNodeIsPlugin();
#endif
+=======
+ if (!node && doc->isPluginDocument()) {
+ PluginDocument* pluginDocument = static_cast<PluginDocument*>(doc);
+ node = pluginDocument->pluginNode();
+ }
+>>>>>>> webkit.org at r58033
if (!node && doc->isHTMLDocument())
node = doc->body();
if (!node)
@@ -2055,6 +2149,8 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
if (!node)
return false;
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
+
if (FrameView* view = m_frame->view())
view->resetDeferredRepaintDelay();
@@ -2171,10 +2267,15 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
return;
if (event->keyIdentifier() == "U+0009")
defaultTabEventHandler(event);
+ else {
+ FocusDirection direction = focusDirectionForKey(event->keyIdentifier());
+ if (direction != FocusDirectionNone)
+ defaultArrowEventHandler(direction, event);
+ }
- // provides KB navigation and selection for enhanced accessibility users
- if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
- handleKeyboardSelectionMovement(event);
+ // provides KB navigation and selection for enhanced accessibility users
+ if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
+ handleKeyboardSelectionMovement(event);
}
if (event->type() == eventNames().keypressEvent) {
m_frame->editor()->handleKeyboardEvent(event);
@@ -2185,6 +2286,27 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
}
}
+FocusDirection EventHandler::focusDirectionForKey(const AtomicString& keyIdentifier) const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, Down, ("Down"));
+ DEFINE_STATIC_LOCAL(AtomicString, Up, ("Up"));
+ DEFINE_STATIC_LOCAL(AtomicString, Left, ("Left"));
+ DEFINE_STATIC_LOCAL(AtomicString, Right, ("Right"));
+
+ FocusDirection retVal = FocusDirectionNone;
+
+ if (keyIdentifier == Down)
+ retVal = FocusDirectionDown;
+ else if (keyIdentifier == Up)
+ retVal = FocusDirectionUp;
+ else if (keyIdentifier == Left)
+ retVal = FocusDirectionLeft;
+ else if (keyIdentifier == Right)
+ retVal = FocusDirectionRight;
+
+ return retVal;
+}
+
#if ENABLE(DRAG_SUPPORT)
bool EventHandler::dragHysteresisExceeded(const FloatPoint& floatDragViewportLocation) const
{
@@ -2222,7 +2344,7 @@ bool EventHandler::shouldDragAutoNode(Node* node, const IntPoint& point) const
if (!node || !m_frame->view())
return false;
Page* page = m_frame->page();
- return page && page->dragController()->mayStartDragAtEventLocation(m_frame, point);
+ return page && page->dragController()->mayStartDragAtEventLocation(m_frame, point, node);
}
void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
@@ -2332,7 +2454,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
// FIXME: This doesn't work correctly with transforms.
FloatPoint absPos = renderer->localToAbsolute();
IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
- dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint() + delta);
+ dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), toPoint(delta));
} else {
// The renderer has disappeared, this can happen if the onStartDrag handler has hidden
// the element in some way. In this case we just kill the drag.
@@ -2412,8 +2534,7 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
return event->defaultHandled();
}
-
-#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(HAIKU)
+#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(HAIKU) && !PLATFORM(EFL)
bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent*) const
{
return false;
@@ -2479,6 +2600,27 @@ void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
#endif
+void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, KeyboardEvent* event)
+{
+ if (event->ctrlKey() || event->metaKey() || event->altGraphKey() || event->shiftKey())
+ return;
+
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
+ if (!page->settings() || !page->settings()->isSpatialNavigationEnabled())
+ return;
+
+ // Arrows and other possible directional navigation keys can be used in design
+ // mode editing.
+ if (m_frame->document()->inDesignMode())
+ return;
+
+ if (page->focusController()->advanceFocus(focusDirection, event))
+ event->setDefaultHandled();
+}
+
void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
{
// We should only advance focus on tabs if no special modifier keys are held down.
@@ -2576,6 +2718,11 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
const Vector<PlatformTouchPoint>& points = event.touchPoints();
AtomicString* eventName = 0;
+<<<<<<< HEAD
+=======
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
+
+>>>>>>> webkit.org at r58033
for (unsigned i = 0; i < points.size(); ++i) {
const PlatformTouchPoint& point = points[i];
IntPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos());
@@ -2602,13 +2749,18 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
// Increment the platform touch id by 1 to avoid storing a key of 0 in the hashmap.
unsigned touchPointTargetKey = point.id() + 1;
+<<<<<<< HEAD
RefPtr<EventTarget> touchTarget;
+=======
+ EventTarget* touchTarget = 0;
+>>>>>>> webkit.org at r58033
if (point.state() == PlatformTouchPoint::TouchPressed) {
m_originatingTouchPointTargets.set(touchPointTargetKey, target);
touchTarget = target;
} else if (point.state() == PlatformTouchPoint::TouchReleased || point.state() == PlatformTouchPoint::TouchCancelled) {
// The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel
// we also remove it from the map.
+<<<<<<< HEAD
touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey);
} else
touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey);
@@ -2617,6 +2769,16 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
continue;
RefPtr<Touch> touch = Touch::create(doc->frame(), touchTarget.get(), point.id(),
+=======
+ touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey).get();
+ } else
+ touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey).get();
+
+ if (!touchTarget)
+ continue;
+
+ RefPtr<Touch> touch = Touch::create(doc->frame(), touchTarget, point.id(),
+>>>>>>> webkit.org at r58033
point.screenPos().x(), point.screenPos().y(),
adjustedPageX, adjustedPageY);
@@ -2625,6 +2787,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
touches->append(touch);
// Now build up the correct list for changedTouches.
+<<<<<<< HEAD
// Note that any touches that are in the TouchStationary state (e.g. if
// the user had several points touched but did not move them all) should
// only be present in the touches list. They may also be added to the
@@ -2632,6 +2795,8 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
// list so we do not handle them explicitly here.
// See https://bugs.webkit.org/show_bug.cgi?id=37609 for further discussion
// about the TouchStationary state.
+=======
+>>>>>>> webkit.org at r58033
if (point.state() == PlatformTouchPoint::TouchReleased)
releasedTouches->append(touch);
else if (point.state() == PlatformTouchPoint::TouchCancelled)
@@ -2694,6 +2859,7 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
RefPtr<TouchList> targetTouches = assembleTargetTouches(changedTouch, touches.get());
+<<<<<<< HEAD
#if PLATFORM(ANDROID)
if (event.type() == TouchLongPress) {
eventName = &eventNames().touchlongpressEvent;
@@ -2717,6 +2883,8 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
defaultPrevented |= doubleTapEv->defaultPrevented();
} else {
#endif
+=======
+>>>>>>> webkit.org at r58033
eventName = &eventNames().touchstartEvent;
RefPtr<TouchEvent> startEv =
TouchEvent::create(touches.get(), targetTouches.get(), pressedTouches.get(),
diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h
index a268adb..282100d 100644
--- a/WebCore/page/EventHandler.h
+++ b/WebCore/page/EventHandler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +27,7 @@
#define EventHandler_h
#include "DragActions.h"
+#include "FocusDirection.h"
#include "PlatformMouseEvent.h"
#include "ScrollTypes.h"
#include "Timer.h"
@@ -49,6 +50,7 @@ class Cursor;
class Event;
class EventTarget;
class FloatPoint;
+class FloatQuad;
class Frame;
class HitTestRequest;
class HitTestResult;
@@ -67,6 +69,7 @@ class String;
class SVGElementInstance;
class TextEvent;
class TouchEvent;
+class WheelEvent;
class Widget;
#if ENABLE(DRAG_SUPPORT)
@@ -100,6 +103,8 @@ public:
RenderObject* autoscrollRenderer() const;
void updateAutoscrollRenderer();
+ void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
+
HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars);
bool mousePressed() const { return m_mousePressed; }
@@ -146,6 +151,7 @@ public:
bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0);
bool handleMouseReleaseEvent(const PlatformMouseEvent&);
bool handleWheelEvent(PlatformWheelEvent&);
+ void defaultWheelEventHandler(Node*, WheelEvent*);
#if ENABLE(CONTEXT_MENUS)
bool sendContextMenuEvent(const PlatformMouseEvent&);
@@ -263,6 +269,9 @@ private:
void setAutoscrollRenderer(RenderObject*);
void autoscrollTimerFired(Timer<EventHandler>*);
+ void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
+ void cancelFakeMouseMoveEvent();
+
void invalidateClick();
Node* nodeUnderMouse() const;
@@ -306,6 +315,7 @@ private:
void defaultSpaceEventHandler(KeyboardEvent*);
void defaultTabEventHandler(KeyboardEvent*);
+ void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
#if ENABLE(DRAG_SUPPORT)
void allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const;
@@ -328,6 +338,8 @@ private:
void setFrameWasScrolledByUser();
+ FocusDirection focusDirectionForKey(const AtomicString&) const;
+
bool capturesDragging() const { return m_capturesDragging; }
#if PLATFORM(MAC) && defined(__OBJC__) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE)
@@ -367,6 +379,8 @@ private:
bool m_mouseDownMayStartAutoscroll;
bool m_mouseDownWasInSubframe;
+ Timer<EventHandler> m_fakeMouseMoveEventTimer;
+
#if ENABLE(SVG)
bool m_svgPan;
RefPtr<SVGElementInstance> m_instanceUnderMouse;
diff --git a/WebCore/page/EventSource.cpp b/WebCore/page/EventSource.cpp
index 0c79998..9ccccd7 100644
--- a/WebCore/page/EventSource.cpp
+++ b/WebCore/page/EventSource.cpp
@@ -250,8 +250,10 @@ void EventSource::parseEventStream()
void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int lineLength)
{
if (!lineLength) {
- if (!m_data.isEmpty())
+ if (!m_data.isEmpty()) {
+ m_data.removeLast();
dispatchEvent(createMessageEvent());
+ }
if (!m_eventName.isEmpty())
m_eventName = "";
} else if (fieldLength) {
@@ -269,10 +271,9 @@ void EventSource::parseEventStreamLine(unsigned int bufPos, int fieldLength, int
int valueLength = lineLength - step;
if (field == "data") {
- if (m_data.size() > 0)
- m_data.append('\n');
if (valueLength)
m_data.append(&m_receiveBuf[bufPos], valueLength);
+ m_data.append('\n');
} else if (field == "event")
m_eventName = valueLength ? String(&m_receiveBuf[bufPos], valueLength) : "";
else if (field == "id")
diff --git a/WebCore/page/EventSource.idl b/WebCore/page/EventSource.idl
index ec42556..57bd807 100644
--- a/WebCore/page/EventSource.idl
+++ b/WebCore/page/EventSource.idl
@@ -53,12 +53,12 @@ module window {
void close();
// EventTarget interface
- [Custom] void addEventListener(in DOMString type,
- in EventListener listener,
- in boolean useCapture);
- [Custom] void removeEventListener(in DOMString type,
+ [JSCCustom] void addEventListener(in DOMString type,
in EventListener listener,
in boolean useCapture);
+ [JSCCustom] void removeEventListener(in DOMString type,
+ in EventListener listener,
+ in boolean useCapture);
boolean dispatchEvent(in Event evt)
raises(EventException);
diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp
index bdd3151..e07e2ea 100644
--- a/WebCore/page/FocusController.cpp
+++ b/WebCore/page/FocusController.cpp
@@ -49,18 +49,26 @@
#include "RenderWidget.h"
#include "SelectionController.h"
#include "Settings.h"
+#include "SpatialNavigation.h"
#include "Widget.h"
-#include <wtf/Platform.h>
namespace WebCore {
using namespace HTMLNames;
+using namespace std;
static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool focused)
{
// If we have a focused node we should dispatch blur on it before we blur the window.
// If we have a focused node we should dispatch focus on it after we focus the window.
// https://bugs.webkit.org/show_bug.cgi?id=27105
+
+ // Do not fire events while modal dialogs are up. See https://bugs.webkit.org/show_bug.cgi?id=33962
+ if (Page* page = document->page()) {
+ if (page->defersLoading())
+ return;
+ }
+
if (!focused && document->focusedNode())
document->focusedNode()->dispatchBlurEvent();
document->dispatchWindowEvent(Event::create(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false));
@@ -153,6 +161,24 @@ bool FocusController::setInitialFocus(FocusDirection direction, KeyboardEvent* e
bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* event, bool initialFocus)
{
+ switch (direction) {
+ case FocusDirectionForward:
+ case FocusDirectionBackward:
+ return advanceFocusInDocumentOrder(direction, event, initialFocus);
+ case FocusDirectionLeft:
+ case FocusDirectionRight:
+ case FocusDirectionUp:
+ case FocusDirectionDown:
+ return advanceFocusDirectionally(direction, event);
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return false;
+}
+
+bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, KeyboardEvent* event, bool initialFocus)
+{
Frame* frame = focusedOrMainFrame();
ASSERT(frame);
Document* document = frame->document();
@@ -257,6 +283,175 @@ bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* even
return true;
}
+bool FocusController::advanceFocusDirectionally(FocusDirection direction, KeyboardEvent* event)
+{
+ Frame* frame = focusedOrMainFrame();
+ ASSERT(frame);
+ Document* focusedDocument = frame->document();
+ if (!focusedDocument)
+ return false;
+
+ Node* focusedNode = focusedDocument->focusedNode();
+ if (!focusedNode) {
+ // Just move to the first focusable node.
+ FocusDirection tabDirection = (direction == FocusDirectionUp || direction == FocusDirectionLeft) ?
+ FocusDirectionForward : FocusDirectionBackward;
+ // 'initialFocus' is set to true so the chrome is not focused.
+ return advanceFocusInDocumentOrder(tabDirection, event, true);
+ }
+
+ // Move up in the chain of nested frames.
+ frame = frame->tree()->top();
+
+ FocusCandidate focusCandidate;
+ findFocusableNodeInDirection(frame->document(), focusedNode, direction, event, focusCandidate);
+
+ Node* node = focusCandidate.node;
+ if (!node || !node->isElementNode()) {
+ // FIXME: May need a way to focus a document here.
+ Frame* frame = focusedOrMainFrame();
+ scrollInDirection(frame, direction);
+ return false;
+ }
+
+ // In order to avoid crazy jump between links that are either far away from each other,
+ // or just not currently visible, lets do a scroll in the given direction and bail out
+ // if |node| element is not in the viewport.
+ if (hasOffscreenRect(node)) {
+ Frame* frame = node->document()->view()->frame();
+ scrollInDirection(frame, direction);
+ return true;
+ }
+
+ Document* newDocument = node->document();
+
+ if (newDocument != focusedDocument) {
+ // Focus is going away from the originally focused document, so clear the focused node.
+ focusedDocument->setFocusedNode(0);
+ }
+
+ if (newDocument)
+ setFocusedFrame(newDocument->frame());
+
+ Element* element = static_cast<Element*>(node);
+ ASSERT(element);
+
+ scrollIntoView(element);
+ element->focus(false);
+ return true;
+}
+
+// FIXME: Make this method more modular, and simpler to understand and maintain.
+static void updateFocusCandidateIfCloser(Node* focusedNode, const FocusCandidate& candidate, FocusCandidate& closest)
+{
+ bool sameDocument = candidate.document() == closest.document();
+ if (sameDocument) {
+ if (closest.alignment > candidate.alignment
+ || (closest.parentAlignment && candidate.alignment > closest.parentAlignment))
+ return;
+ } else if (closest.alignment > candidate.alignment
+ && (closest.parentAlignment && candidate.alignment > closest.parentAlignment))
+ return;
+
+ if (candidate.alignment != None
+ || (closest.parentAlignment >= candidate.alignment
+ && closest.document() == candidate.document())) {
+
+ // If we are now in an higher precedent case, lets reset the current closest's
+ // distance so we force it to be bigger than any result we will get from
+ // spatialDistance().
+ if (closest.alignment < candidate.alignment
+ && closest.parentAlignment < candidate.alignment)
+ closest.distance = maxDistance();
+ }
+
+ // Bail out if candidate's distance is larger than that of the closest candidate.
+ if (candidate.distance >= closest.distance)
+ return;
+
+ if (closest.isNull()) {
+ closest = candidate;
+ return;
+ }
+
+ // If the focused node and the candadate are in the same document and current
+ // closest candidate is not in an {i}frame that is preferable to get focused ...
+ if (focusedNode->document() == candidate.document()
+ && candidate.distance < closest.parentDistance)
+ closest = candidate;
+ else if (focusedNode->document() != candidate.document()) {
+ // If the focusedNode is in an inner document and candidate is in a
+ // different document, we only consider to change focus if there is not
+ // another already good focusable candidate in the same document as focusedNode.
+ if (!((isInRootDocument(candidate.node) && !isInRootDocument(focusedNode))
+ && focusedNode->document() == closest.document()))
+ closest = candidate;
+ }
+}
+
+void FocusController::findFocusableNodeInDirection(Document* document, Node* focusedNode,
+ FocusDirection direction, KeyboardEvent* event,
+ FocusCandidate& closestFocusCandidate,
+ const FocusCandidate& candidateParent)
+{
+ ASSERT(document);
+ ASSERT(candidateParent.isNull() || static_cast<HTMLFrameOwnerElement*>(candidateParent.node));
+
+ // Walk all the child nodes and update closestFocusCandidate if we find a nearer node.
+ for (Node* candidate = document->firstChild(); candidate; candidate = candidate->traverseNextNode()) {
+ // Inner documents case.
+
+ if (candidate->isFrameOwnerElement())
+ deepFindFocusableNodeInDirection(focusedNode, candidate, direction, event, closestFocusCandidate);
+ else if (candidate != focusedNode && candidate->isKeyboardFocusable(event)) {
+ FocusCandidate currentFocusCandidate(candidate);
+
+ // Get distance and alignment from current candidate.
+ distanceDataForNode(direction, focusedNode, currentFocusCandidate);
+
+ // Bail out if distance is maximum.
+ if (currentFocusCandidate.distance == maxDistance())
+ continue;
+
+ // If candidateParent is not null, it means that we are in a recursive call
+ // from deepFineFocusableNodeInDirection (i.e. processing an element in an iframe),
+ // and holds the distance and alignment data of the iframe element itself.
+ if (!candidateParent.isNull()) {
+ currentFocusCandidate.parentAlignment = candidateParent.alignment;
+ currentFocusCandidate.parentDistance = candidateParent.distance;
+ }
+
+ updateFocusCandidateIfCloser(focusedNode, currentFocusCandidate, closestFocusCandidate);
+ }
+ }
+}
+
+void FocusController::deepFindFocusableNodeInDirection(Node* focusedNode, Node* candidate,
+ FocusDirection direction, KeyboardEvent* event,
+ FocusCandidate& closestFocusCandidate)
+{
+ HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(candidate);
+ if (!owner->contentFrame())
+ return;
+
+ Document* innerDocument = owner->contentFrame()->document();
+ if (!innerDocument)
+ return;
+
+ if (innerDocument == focusedNode->document())
+ findFocusableNodeInDirection(innerDocument, focusedNode, direction, event, closestFocusCandidate);
+ else {
+ // Check if the current {i}frame element itself is a good candidate
+ // to move focus to. If it is, then we traverse its inner nodes.
+ FocusCandidate candidateParent = FocusCandidate(candidate);
+ distanceDataForNode(direction, focusedNode, candidateParent);
+
+ // FIXME: Consider alignment?
+ if (candidateParent.distance < closestFocusCandidate.distance)
+ findFocusableNodeInDirection(innerDocument, focusedNode, direction, event, closestFocusCandidate, candidateParent);
+ }
+}
+
static bool relinquishesEditingFocus(Node *node)
{
ASSERT(node);
diff --git a/WebCore/page/FocusController.h b/WebCore/page/FocusController.h
index 32d4060..dfa3780 100644
--- a/WebCore/page/FocusController.h
+++ b/WebCore/page/FocusController.h
@@ -27,12 +27,14 @@
#define FocusController_h
#include "FocusDirection.h"
+#include "SpatialNavigation.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
namespace WebCore {
+class Document;
class Frame;
class KeyboardEvent;
class Node;
@@ -58,6 +60,13 @@ public:
bool isFocused() const { return m_isFocused; }
private:
+ bool advanceFocusDirectionally(FocusDirection, KeyboardEvent*);
+ bool advanceFocusInDocumentOrder(FocusDirection, KeyboardEvent*, bool initialFocus);
+
+ void findFocusableNodeInDirection(Document*, Node*, FocusDirection, KeyboardEvent*, FocusCandidate& closestFocusCandidate,
+ const FocusCandidate& parentCandidate = FocusCandidate());
+ void deepFindFocusableNodeInDirection(Node*, Node*, FocusDirection, KeyboardEvent*, FocusCandidate&);
+
Page* m_page;
RefPtr<Frame> m_focusedFrame;
bool m_isActive;
diff --git a/WebCore/page/FocusDirection.h b/WebCore/page/FocusDirection.h
index 261c745..8a6d51f 100644
--- a/WebCore/page/FocusDirection.h
+++ b/WebCore/page/FocusDirection.h
@@ -28,8 +28,13 @@
namespace WebCore {
enum FocusDirection {
- FocusDirectionForward = 0,
- FocusDirectionBackward
+ FocusDirectionNone = 0,
+ FocusDirectionForward,
+ FocusDirectionBackward,
+ FocusDirectionUp,
+ FocusDirectionDown,
+ FocusDirectionLeft,
+ FocusDirectionRight
};
}
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index 87c9733..a8d58fd 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -49,6 +49,7 @@
#include "FrameLoaderClient.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+#include "GraphicsLayer.h"
#include "HTMLDocument.h"
#include "HTMLFormControlElement.h"
#include "HTMLFormElement.h"
@@ -84,8 +85,8 @@
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/StdLibExtras.h>
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
-#import <Carbon/Carbon.h>
+#if USE(ACCELERATED_COMPOSITING)
+#include "RenderLayerCompositor.h"
#endif
#if USE(JSC)
@@ -112,6 +113,10 @@
#include "MathMLNames.h"
#endif
+#if ENABLE(TILED_BACKING_STORE)
+#include "TiledBackingStore.h"
+#endif
+
using namespace std;
namespace WebCore {
@@ -136,7 +141,6 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
, m_redirectScheduler(this)
, m_ownerElement(ownerElement)
, m_script(this)
- , m_selectionGranularity(CharacterGranularity)
, m_selectionController(this)
, m_editor(this)
, m_eventHandler(this)
@@ -175,9 +179,13 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient*
XMLNSNames::init();
XMLNames::init();
- if (!ownerElement)
+ if (!ownerElement) {
page->setMainFrame(this);
- else {
+#if ENABLE(TILED_BACKING_STORE)
+ // Top level frame only for now.
+ setTiledBackingStoreEnabled(page->settings()->tiledBackingStoreEnabled());
+#endif
+ } else {
page->incrementFrameCount();
// Make sure we will not end up with two frames referencing the same owner element.
ASSERT((!(ownerElement->m_contentFrame)) || (ownerElement->m_contentFrame->ownerElement() != ownerElement));
@@ -265,6 +273,11 @@ void Frame::setView(PassRefPtr<FrameView> view)
// Since this part may be getting reused as a result of being
// pulled from the back/forward cache, reset this flag.
loader()->resetMultipleFormSubmissionProtection();
+
+#if ENABLE(TILED_BACKING_STORE)
+ if (m_view && tiledBackingStore())
+ m_view->setPaintsEntireContents(true);
+#endif
}
ScriptController* Frame::script()
@@ -285,8 +298,7 @@ void Frame::setDocument(PassRefPtr<Document> newDoc)
}
m_doc = newDoc;
- if (m_doc && selection()->isFocusedAndActive())
- setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
+ selection()->updateSecureKeyboardEntryIfActive();
if (m_doc && !m_doc->attached())
m_doc->attach();
@@ -366,12 +378,7 @@ Editor* Frame::editor() const
TextGranularity Frame::selectionGranularity() const
{
- return m_selectionGranularity;
-}
-
-void Frame::setSelectionGranularity(TextGranularity granularity)
-{
- m_selectionGranularity = granularity;
+ return m_selectionController.granularity();
}
SelectionController* Frame::dragCaretController() const
@@ -657,6 +664,11 @@ void Frame::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& cl
ASSERT(dragCaretController->selection().isCaret());
if (dragCaretController->selection().start().node()->document()->frame() == this)
dragCaretController->paintCaret(p, tx, ty, clipRect);
+#else
+ UNUSED_PARAM(p);
+ UNUSED_PARAM(tx);
+ UNUSED_PARAM(ty);
+ UNUSED_PARAM(clipRect);
#endif
}
@@ -665,28 +677,24 @@ float Frame::zoomFactor() const
return m_zoomFactor;
}
-bool Frame::isZoomFactorTextOnly() const
+ZoomMode Frame::zoomMode() const
{
- return m_page->settings()->zoomsTextOnly();
+ return m_page->settings()->zoomMode();
}
bool Frame::shouldApplyTextZoom() const
{
- if (m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
- return false;
- return true;
+ return m_zoomFactor != 1.0f && zoomMode() == ZoomTextOnly;
}
bool Frame::shouldApplyPageZoom() const
{
- if (m_zoomFactor == 1.0f || isZoomFactorTextOnly())
- return false;
- return true;
+ return m_zoomFactor != 1.0f && zoomMode() == ZoomPage;
}
-void Frame::setZoomFactor(float percent, bool isTextOnly)
+void Frame::setZoomFactor(float percent, ZoomMode mode)
{
- if (m_zoomFactor == percent && isZoomFactorTextOnly() == isTextOnly)
+ if (m_zoomFactor == percent && zoomMode() == mode)
return;
#if ENABLE(SVG)
@@ -700,7 +708,7 @@ void Frame::setZoomFactor(float percent, bool isTextOnly)
}
#endif
- if (!isTextOnly) {
+ if (mode == ZoomPage) {
// Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
IntPoint scrollPosition = view()->scrollPosition();
float percentDifference = (percent / m_zoomFactor);
@@ -708,12 +716,12 @@ void Frame::setZoomFactor(float percent, bool isTextOnly)
}
m_zoomFactor = percent;
- m_page->settings()->setZoomsTextOnly(isTextOnly);
+ m_page->settings()->setZoomMode(mode);
m_doc->recalcStyle(Node::Force);
for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
- child->setZoomFactor(m_zoomFactor, isTextOnly);
+ child->setZoomFactor(m_zoomFactor, mode);
if (m_doc->renderer() && m_doc->renderer()->needsLayout() && view()->didFirstLayout())
view()->layout();
@@ -722,7 +730,8 @@ void Frame::setZoomFactor(float percent, bool isTextOnly)
void Frame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
{
m_doc->setPrinting(printing);
- view()->setMediaType(printing ? "print" : "screen");
+ view()->adjustMediaTypeForPrinting(printing);
+
m_doc->updateStyleSelector();
view()->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth, adjustViewSize);
@@ -850,43 +859,6 @@ bool Frame::isContentEditable() const
return m_doc->inDesignMode();
}
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
-const short enableRomanKeyboardsOnly = -23;
-#endif
-void Frame::setUseSecureKeyboardEntry(bool enable)
-{
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
- if (enable == IsSecureEventInputEnabled())
- return;
- if (enable) {
- EnableSecureEventInput();
-#ifdef BUILDING_ON_TIGER
- KeyScript(enableRomanKeyboardsOnly);
-#else
- // WebKit substitutes nil for input context when in password field, which corresponds to null TSMDocument. So, there is
- // no need to call TSMGetActiveDocument(), which may return an incorrect result when selection hasn't been yet updated
- // after focusing a node.
- CFArrayRef inputSources = TISCreateASCIICapableInputSourceList();
- TSMSetDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag, sizeof(CFArrayRef), &inputSources);
- CFRelease(inputSources);
-#endif
- } else {
- DisableSecureEventInput();
-#ifdef BUILDING_ON_TIGER
- KeyScript(smKeyEnableKybds);
-#else
- TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag);
-#endif
- }
-#endif
-}
-
-void Frame::updateSecureKeyboardEntryIfActive()
-{
- if (selection()->isFocusedAndActive())
- setUseSecureKeyboardEntry(m_doc->useSecureKeyboardEntryWhenActive());
-}
-
CSSMutableStyleDeclaration *Frame::typingStyle() const
{
return m_typingStyle.get();
@@ -1423,7 +1395,7 @@ bool Frame::findString(const String& target, bool forward, bool caseFlag, bool w
// If we started in the selection and the found range exactly matches the existing selection, find again.
// Build a selection with the found range to remove collapsed whitespace.
// Compare ranges instead of selection objects to ignore the way that the current selection was made.
- if (startInSelection && *VisibleSelection(resultRange.get()).toNormalizedRange() == *selection.toNormalizedRange()) {
+ if (startInSelection && areRangesEqual(VisibleSelection(resultRange.get()).toNormalizedRange().get(), selection.toNormalizedRange().get())) {
searchRange = rangeOfContents(document());
if (forward)
setStart(searchRange.get(), selection.visibleEnd());
@@ -1818,7 +1790,8 @@ Document* Frame::documentAtPoint(const IntPoint& point)
void Frame::createView(const IntSize& viewportSize,
const Color& backgroundColor, bool transparent,
const IntSize& fixedLayoutSize, bool useFixedLayout,
- ScrollbarMode horizontalScrollbarMode, ScrollbarMode verticalScrollbarMode)
+ ScrollbarMode horizontalScrollbarMode, bool horizontalLock,
+ ScrollbarMode verticalScrollbarMode, bool verticalLock)
{
ASSERT(this);
ASSERT(m_page);
@@ -1838,7 +1811,7 @@ void Frame::createView(const IntSize& viewportSize,
} else
frameView = FrameView::create(this);
- frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode);
+ frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode, horizontalLock, verticalLock);
setView(frameView);
@@ -1855,4 +1828,67 @@ void Frame::createView(const IntSize& viewportSize,
view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
}
+#if ENABLE(TILED_BACKING_STORE)
+void Frame::setTiledBackingStoreEnabled(bool enabled)
+{
+ if (!enabled) {
+ m_tiledBackingStore.clear();
+ return;
+ }
+ if (m_tiledBackingStore)
+ return;
+ m_tiledBackingStore.set(new TiledBackingStore(this));
+ if (m_view)
+ m_view->setPaintsEntireContents(true);
+}
+
+void Frame::tiledBackingStorePaintBegin()
+{
+ if (!m_view)
+ return;
+ m_view->layoutIfNeededRecursive();
+ m_view->flushDeferredRepaints();
+}
+
+void Frame::tiledBackingStorePaint(GraphicsContext* context, const IntRect& rect)
+{
+ if (!m_view)
+ return;
+ m_view->paintContents(context, rect);
+}
+
+void Frame::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea)
+{
+ if (!m_page || !m_view)
+ return;
+ unsigned size = paintedArea.size();
+ // Request repaint from the system
+ for (int n = 0; n < size; ++n)
+ m_page->chrome()->invalidateContentsAndWindow(m_view->contentsToWindow(paintedArea[n]), false);
+}
+
+IntRect Frame::tiledBackingStoreContentsRect()
+{
+ if (!m_view)
+ return IntRect();
+ return IntRect(IntPoint(), m_view->contentsSize());
+}
+#endif
+
+String Frame::layerTreeAsText() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (!contentRenderer())
+ return String();
+
+ GraphicsLayer* rootLayer = contentRenderer()->compositor()->rootPlatformLayer();
+ if (!rootLayer)
+ return String();
+
+ return rootLayer->layerTreeAsText();
+#else
+ return String();
+#endif
+}
+
} // namespace WebCore
diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h
index 26d1efa..4a7cdaf 100644
--- a/WebCore/page/Frame.h
+++ b/WebCore/page/Frame.h
@@ -38,11 +38,16 @@
#include "ScrollBehavior.h"
#include "SelectionController.h"
#include "UserScriptTypes.h"
+#include "ZoomMode.h"
#if PLATFORM(WIN)
#include "FrameWin.h"
#endif
+#if ENABLE(TILED_BACKING_STORE)
+#include "TiledBackingStoreClient.h"
+#endif
+
#if PLATFORM(MAC)
#ifndef __OBJC__
class NSArray;
@@ -62,8 +67,14 @@ namespace WebCore {
class CSSMutableStyleDeclaration;
class HTMLTableCellElement;
class RegularExpression;
+ class RenderPart;
+ class TiledBackingStore;
- class Frame : public RefCounted<Frame> {
+ class Frame : public RefCounted<Frame>
+#if ENABLE(TILED_BACKING_STORE)
+ , public TiledBackingStoreClient
+#endif
+ {
public:
static PassRefPtr<Frame> create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
{
@@ -108,9 +119,12 @@ namespace WebCore {
void setExcludeFromTextSearch(bool);
void createView(const IntSize&, const Color&, bool, const IntSize &, bool,
- ScrollbarMode = ScrollbarAuto, ScrollbarMode = ScrollbarAuto);
+ ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
+ ScrollbarMode = ScrollbarAuto, bool verticalLock = false);
void injectUserScripts(UserScriptInjectionTime);
+
+ String layerTreeAsText() const;
private:
void injectUserScriptsForWorld(DOMWrapperWorld*, const UserScriptVector&, UserScriptInjectionTime);
@@ -163,15 +177,20 @@ namespace WebCore {
return document() ? document()->displayStringModifiedByEncoding(str) : str;
}
+#if ENABLE(TILED_BACKING_STORE)
+ TiledBackingStore* tiledBackingStore() const { return m_tiledBackingStore.get(); }
+ void setTiledBackingStoreEnabled(bool);
+#endif
+
private:
void lifeSupportTimerFired(Timer<Frame>*);
// === to be moved into FrameView
public:
- void setZoomFactor(float scale, bool isTextOnly);
+ void setZoomFactor(float scale, ZoomMode);
float zoomFactor() const;
- bool isZoomFactorTextOnly() const;
+ ZoomMode zoomMode() const;
bool shouldApplyTextZoom() const;
bool shouldApplyPageZoom() const;
float pageZoomFactor() const { return shouldApplyPageZoom() ? zoomFactor() : 1.0f; }
@@ -232,7 +251,6 @@ namespace WebCore {
public:
TextGranularity selectionGranularity() const;
- void setSelectionGranularity(TextGranularity);
bool shouldChangeSelection(const VisibleSelection&) const;
bool shouldDeleteSelection(const VisibleSelection&) const;
@@ -243,8 +261,6 @@ namespace WebCore {
bool isContentEditable() const; // if true, everything in frame is editable
- void updateSecureKeyboardEntryIfActive();
-
CSSMutableStyleDeclaration* typingStyle() const;
void setTypingStyle(CSSMutableStyleDeclaration*);
void clearTypingStyle();
@@ -258,8 +274,6 @@ namespace WebCore {
void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, bool revealExtent = false);
void setSelectionFromNone();
- void setUseSecureKeyboardEntry(bool);
-
SelectionController* dragCaretController() const;
String searchForLabelsAboveCell(RegularExpression*, HTMLTableCellElement*, size_t* resultDistanceFromStartOfCell);
@@ -268,6 +282,15 @@ namespace WebCore {
VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
Document* documentAtPoint(const IntPoint& windowPoint);
+
+ private:
+#if ENABLE(TILED_BACKING_STORE)
+ // TiledBackingStoreClient interface
+ virtual void tiledBackingStorePaintBegin();
+ virtual void tiledBackingStorePaint(GraphicsContext*, const IntRect&);
+ virtual void tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea);
+ virtual IntRect tiledBackingStoreContentsRect();
+#endif
#if PLATFORM(MAC)
@@ -325,8 +348,6 @@ namespace WebCore {
float m_zoomFactor;
- TextGranularity m_selectionGranularity;
-
mutable SelectionController m_selectionController;
mutable VisibleSelection m_mark;
mutable Editor m_editor;
@@ -346,6 +367,10 @@ namespace WebCore {
bool m_needsReapplyStyles;
bool m_isDisconnected;
bool m_excludeFromTextSearch;
+
+#if ENABLE(TILED_BACKING_STORE)
+ OwnPtr<TiledBackingStore> m_tiledBackingStore;
+#endif
};
} // namespace WebCore
diff --git a/WebCore/page/FrameTree.cpp b/WebCore/page/FrameTree.cpp
index 41caa9c..d6170e1 100644
--- a/WebCore/page/FrameTree.cpp
+++ b/WebCore/page/FrameTree.cpp
@@ -25,7 +25,6 @@
#include "Page.h"
#include "PageGroup.h"
#include <stdarg.h>
-#include <wtf/Platform.h>
#include <wtf/StringExtras.h>
#include <wtf/Vector.h>
diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp
index 356ada2..f784c1b 100644
--- a/WebCore/page/FrameView.cpp
+++ b/WebCore/page/FrameView.cpp
@@ -75,10 +75,16 @@
#include "SVGViewSpec.h"
#endif
+<<<<<<< HEAD
#if PLATFORM(ANDROID)
#include "WebCoreFrameBridge.h"
#endif
+=======
+#if ENABLE(TILED_BACKING_STORE)
+#include "TiledBackingStore.h"
+#endif
+>>>>>>> webkit.org at r58033
namespace WebCore {
@@ -117,6 +123,7 @@ FrameView::FrameView(Frame* frame)
: m_frame(frame)
, m_canHaveScrollbars(true)
, m_slowRepaintObjectCount(0)
+ , m_fixedObjectCount(0)
, m_layoutTimer(this, &FrameView::layoutTimerFired)
, m_layoutRoot(0)
, m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
@@ -301,7 +308,7 @@ void FrameView::invalidateRect(const IntRect& rect)
{
if (!parent()) {
if (hostWindow())
- hostWindow()->repaint(rect, true);
+ hostWindow()->invalidateContentsAndWindow(rect, false /*immediate*/);
return;
}
@@ -330,6 +337,23 @@ void FrameView::setMarginHeight(int h)
m_margins.setHeight(h);
}
+bool FrameView::avoidScrollbarCreation()
+{
+ ASSERT(m_frame);
+
+ // with frame flattening no subframe can have scrollbars
+ // but we also cannot turn scrollbars of as we determine
+ // our flattening policy using that.
+
+ if (!m_frame->ownerElement())
+ return false;
+
+ if (!m_frame->settings() || m_frame->settings()->frameFlatteningEnabled())
+ return true;
+
+ return false;
+}
+
void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
{
m_canHaveScrollbars = canHaveScrollbars;
@@ -385,7 +409,7 @@ void FrameView::setContentsSize(const IntSize& size)
return;
page->chrome()->contentsSizeChanged(frame(), size); //notify only
-
+
m_deferSetNeedsLayouts--;
if (!m_deferSetNeedsLayouts)
@@ -398,6 +422,7 @@ void FrameView::adjustViewSize()
RenderView* root = m_frame->contentRenderer();
if (!root)
return;
+
setContentsSize(IntSize(root->rightLayoutOverflow(), root->bottomLayoutOverflow()));
}
@@ -628,7 +653,7 @@ void FrameView::layout(bool allowSubtree)
RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
Node* body = document->body();
if (body && body->renderer()) {
- if (body->hasTagName(framesetTag) && !m_frame->settings()->frameSetFlatteningEnabled()) {
+ if (body->hasTagName(framesetTag) && !m_frame->settings()->frameFlatteningEnabled()) {
body->renderer()->setChildNeedsLayout(true);
vMode = ScrollbarAlwaysOff;
hMode = ScrollbarAlwaysOff;
@@ -665,8 +690,9 @@ void FrameView::layout(bool allowSubtree)
ScrollbarMode currentVMode = verticalScrollbarMode();
if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
- setScrollbarsSuppressed(true);
if (m_firstLayout) {
+ setScrollbarsSuppressed(true);
+
m_firstLayout = false;
m_firstLayoutCallbackPending = true;
m_lastLayoutSize = IntSize(width(), height());
@@ -678,9 +704,11 @@ void FrameView::layout(bool allowSubtree)
// Set the initial hMode to AlwaysOff if we're auto.
if (hMode == ScrollbarAuto)
setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
- }
- setScrollbarModes(hMode, vMode);
- setScrollbarsSuppressed(false, true);
+
+ setScrollbarModes(hMode, vMode);
+ setScrollbarsSuppressed(false, true);
+ } else
+ setScrollbarModes(hMode, vMode);
}
IntSize oldSize = m_size;
@@ -728,10 +756,12 @@ void FrameView::layout(bool allowSubtree)
// Now update the positions of all layers.
beginDeferredRepaints();
+ IntPoint cachedOffset;
layer->updateLayerPositions((m_doFullRepaint ? RenderLayer::DoFullRepaint : 0)
| RenderLayer::CheckForRepaint
| RenderLayer::IsCompositingUpdateRoot
- | RenderLayer::UpdateCompositingLayers);
+ | RenderLayer::UpdateCompositingLayers,
+ subtree ? 0 : &cachedOffset);
endDeferredRepaints();
#if USE(ACCELERATED_COMPOSITING)
@@ -815,14 +845,27 @@ String FrameView::mediaType() const
return m_mediaType;
}
+void FrameView::adjustMediaTypeForPrinting(bool printing)
+{
+ if (printing) {
+ if (m_mediaTypeWhenNotPrinting.isNull())
+ m_mediaTypeWhenNotPrinting = mediaType();
+ setMediaType("print");
+ } else {
+ if (!m_mediaTypeWhenNotPrinting.isNull())
+ setMediaType(m_mediaTypeWhenNotPrinting);
+ m_mediaTypeWhenNotPrinting = String();
+ }
+}
+
bool FrameView::useSlowRepaints() const
{
- return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || m_isOverlapped || !m_contentIsOpaque;
+ return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || m_isOverlapped || !m_contentIsOpaque;
}
bool FrameView::useSlowRepaintsIfNotOverlapped() const
{
- return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque;
+ return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || (platformWidget() && m_fixedObjectCount > 0) || !m_contentIsOpaque;
}
void FrameView::setUseSlowRepaints()
@@ -846,6 +889,17 @@ void FrameView::removeSlowRepaintObject()
setCanBlitOnScroll(!useSlowRepaints());
}
+void FrameView::addFixedObject()
+{
+ ++m_fixedObjectCount;
+}
+
+void FrameView::removeFixedObject()
+{
+ ASSERT(m_fixedObjectCount > 0);
+ --m_fixedObjectCount;
+}
+
void FrameView::setIsOverlapped(bool isOverlapped)
{
if (isOverlapped == m_isOverlapped)
@@ -982,10 +1036,10 @@ void FrameView::scrollPositionChanged()
// For fixed position elements, update widget positions and compositing layers after scrolling,
// but only if we're not inside of layout.
- // FIXME: we could skip this if we knew the page had no fixed position elements.
- if (!m_nestedLayoutCount) {
+ if (!m_nestedLayoutCount && hasFixedObjects()) {
if (RenderView* root = m_frame->contentRenderer()) {
root->updateWidgetPositions();
+ root->layer()->updateRepaintRectsAfterScroll();
#if USE(ACCELERATED_COMPOSITING)
if (root->usesCompositing())
root->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
@@ -1040,6 +1094,12 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate)
if (!immediate && isOffscreen() && !shouldUpdateWhileOffscreen())
return;
+#if ENABLE(TILED_BACKING_STORE)
+ if (frame()->tiledBackingStore()) {
+ frame()->tiledBackingStore()->invalidate(r);
+ return;
+ }
+#endif
ScrollView::repaintContentRectangle(r, immediate);
}
@@ -1111,8 +1171,15 @@ void FrameView::doDeferredRepaints()
return;
}
unsigned size = m_repaintRects.size();
- for (unsigned i = 0; i < size; i++)
+ for (unsigned i = 0; i < size; i++) {
+#if ENABLE(TILED_BACKING_STORE)
+ if (frame()->tiledBackingStore()) {
+ frame()->tiledBackingStore()->invalidate(m_repaintRects[i]);
+ continue;
+ }
+#endif
ScrollView::repaintContentRectangle(m_repaintRects[i], false);
+ }
m_repaintRects.clear();
m_repaintCount = 0;
@@ -1182,6 +1249,7 @@ void FrameView::scheduleRelayout()
if (!m_frame->document()->shouldScheduleLayout())
return;
+<<<<<<< HEAD
#if defined(FLATTEN_IFRAME) || defined(FLATTEN_FRAMESET)
// This is the Android frame flattening code. The common code below is not
// used as frameSetFlatteningEnabled() is false on Android.
@@ -1190,9 +1258,14 @@ void FrameView::scheduleRelayout()
#endif
// When frameset flattening is enabled, the contents of the frame affects layout of the parent frames.
+=======
+ // When frame flattening is enabled, the contents of the frame affects layout of the parent frames.
+>>>>>>> webkit.org at r58033
// Also invalidate parent frame starting from the owner element of this frame.
- if (m_frame->settings()->frameSetFlatteningEnabled() && m_frame->ownerRenderer())
- m_frame->ownerRenderer()->setNeedsLayout(true, true);
+ if (m_frame->settings()->frameFlatteningEnabled() && m_frame->ownerRenderer()) {
+ if (m_frame->ownerElement()->hasTagName(iframeTag) || m_frame->ownerElement()->hasTagName(frameTag))
+ m_frame->ownerRenderer()->setNeedsLayout(true, true);
+ }
int delay = m_frame->document()->minimumLayoutDelay();
if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
@@ -1403,20 +1476,30 @@ bool FrameView::updateWidgets()
if (m_nestedLayoutCount > 1 || !m_widgetUpdateSet || m_widgetUpdateSet->isEmpty())
return true;
- Vector<RenderEmbeddedObject*> objectVector;
- copyToVector(*m_widgetUpdateSet, objectVector);
- size_t size = objectVector.size();
+ size_t size = m_widgetUpdateSet->size();
+
+ Vector<RenderEmbeddedObject*> objects;
+ objects.reserveCapacity(size);
+
+ RenderEmbeddedObjectSet::const_iterator end = m_widgetUpdateSet->end();
+ for (RenderEmbeddedObjectSet::const_iterator it = m_widgetUpdateSet->begin(); it != end; ++it) {
+ objects.uncheckedAppend(*it);
+ (*it)->ref();
+ }
+
for (size_t i = 0; i < size; ++i) {
- RenderEmbeddedObject* object = objectVector[i];
+ RenderEmbeddedObject* object = objects[i];
+
+ // The object may have been destroyed, but our manual ref() keeps the object from being deleted.
object->updateWidget(false);
-
- // updateWidget() can destroy the RenderPartObject, so we need to make sure it's
- // alive by checking if it's still in m_widgetUpdateSet.
- if (m_widgetUpdateSet->contains(object)) {
- object->updateWidgetPosition();
- m_widgetUpdateSet->remove(object);
- }
+ object->updateWidgetPosition();
+
+ m_widgetUpdateSet->remove(object);
}
+
+ RenderArena* arena = m_frame->document()->renderArena();
+ for (size_t i = 0; i < size; ++i)
+ objects[i]->deref(arena);
return m_widgetUpdateSet->isEmpty();
}
diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h
index 1d5a312..cbd0cb9 100644
--- a/WebCore/page/FrameView.h
+++ b/WebCore/page/FrameView.h
@@ -77,6 +77,8 @@ public:
virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
+ virtual bool avoidScrollbarCreation();
+
virtual void setContentsSize(const IntSize&);
void layout(bool allowSubtree = true);
@@ -141,6 +143,7 @@ public:
String mediaType() const;
void setMediaType(const String&);
+ void adjustMediaTypeForPrinting(bool printing);
void setUseSlowRepaints();
void setIsOverlapped(bool);
@@ -149,6 +152,9 @@ public:
void addSlowRepaintObject();
void removeSlowRepaintObject();
+ void addFixedObject();
+ void removeFixedObject();
+
void beginDeferredRepaints();
void endDeferredRepaints();
void checkStopDelayingDeferredRepaints();
@@ -215,6 +221,8 @@ private:
bool useSlowRepaints() const;
bool useSlowRepaintsIfNotOverlapped() const;
+ bool hasFixedObjects() const { return m_fixedObjectCount > 0; }
+
void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow);
@@ -272,6 +280,7 @@ private:
bool m_isOverlapped;
bool m_contentIsOpaque;
unsigned m_slowRepaintObjectCount;
+ unsigned m_fixedObjectCount;
int m_borderX, m_borderY;
@@ -293,7 +302,8 @@ private:
float m_lastZoomFactor;
String m_mediaType;
-
+ String m_mediaTypeWhenNotPrinting;
+
unsigned m_enqueueEvents;
Vector<ScheduledEvent*> m_scheduledEvents;
diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp
index a885062..55fdef5 100644
--- a/WebCore/page/Geolocation.cpp
+++ b/WebCore/page/Geolocation.cpp
@@ -28,7 +28,10 @@
#include "config.h"
#include "Geolocation.h"
+#if ENABLE(GEOLOCATION)
+
#include "Chrome.h"
+<<<<<<< HEAD
// ANDROID
#include "DOMWindow.h"
// END ANDROID
@@ -41,6 +44,10 @@
#if PLATFORM(ANDROID)
#include "PlatformBridge.h"
#endif
+=======
+#include "Frame.h"
+#include "Page.h"
+>>>>>>> webkit.org at r58033
#include <wtf/CurrentTime.h>
#if ENABLE(CLIENT_BASED_GEOLOCATION)
@@ -217,7 +224,10 @@ Geolocation::Geolocation(Frame* frame)
, m_service(GeolocationService::create(this))
#endif
, m_allowGeolocation(Unknown)
+<<<<<<< HEAD
, m_shouldClearCache(false)
+=======
+>>>>>>> webkit.org at r58033
, m_positionCache(new GeolocationPositionCache)
{
if (!m_frame)
@@ -241,6 +251,8 @@ Geolocation::~Geolocation()
void Geolocation::disconnectFrame()
{
+ if (m_frame && m_frame->page() && m_allowGeolocation == InProgress)
+ m_frame->page()->chrome()->cancelGeolocationPermissionRequestForFrame(m_frame, this);
stopUpdating();
if (m_frame) {
if (m_frame->document())
@@ -253,6 +265,8 @@ void Geolocation::disconnectFrame()
Geoposition* Geolocation::lastPosition()
{
+ ASSERT(isAllowed());
+
#if ENABLE(CLIENT_BASED_GEOLOCATION)
if (!m_frame)
return 0;
@@ -323,6 +337,7 @@ void Geolocation::fatalErrorOccurred(Geolocation::GeoNotifier* notifier)
}
void Geolocation::requestUsesCachedPosition(GeoNotifier* notifier)
+<<<<<<< HEAD
{
// This is called asynchronously, so the permissions could have been denied
// since we last checked in startRequest.
@@ -372,14 +387,57 @@ void Geolocation::makeCachedPositionCallbacks()
}
void Geolocation::requestTimedOut(GeoNotifier* notifier)
+=======
+>>>>>>> webkit.org at r58033
{
- // If this is a one-shot request, stop it.
- m_oneShots.remove(notifier);
+ // This is called asynchronously, so the permissions could have been denied
+ // since we last checked in startRequest.
+ if (isDenied()) {
+ notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage));
+ return;
+ }
+
+ m_requestsAwaitingCachedPosition.add(notifier);
+
+ // If permissions are allowed, make the callback
+ if (isAllowed()) {
+ makeCachedPositionCallbacks();
+ return;
+ }
+
+ // Request permissions, which may be synchronous or asynchronous.
+ requestPermission();
+}
+
+void Geolocation::makeCachedPositionCallbacks()
+{
+ // All modifications to m_requestsAwaitingCachedPosition are done
+ // asynchronously, so we don't need to worry about it being modified from
+ // the callbacks.
+ GeoNotifierSet::const_iterator end = m_requestsAwaitingCachedPosition.end();
+ for (GeoNotifierSet::const_iterator iter = m_requestsAwaitingCachedPosition.begin(); iter != end; ++iter) {
+ GeoNotifier* notifier = iter->get();
+ notifier->runSuccessCallback(m_positionCache->cachedPosition());
+
+ // If this is a one-shot request, stop it. Otherwise, if the watch still
+ // exists, start the service to get updates.
+ if (m_oneShots.contains(notifier))
+ m_oneShots.remove(notifier);
+ else if (m_watchers.contains(notifier)) {
+ if (notifier->hasZeroTimeout() || startUpdating(notifier))
+ notifier->startTimerIfNeeded();
+ else
+ notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, failedToStartServiceErrorMessage));
+ }
+ }
+
+ m_requestsAwaitingCachedPosition.clear();
if (!hasListeners())
stopUpdating();
}
+<<<<<<< HEAD
bool Geolocation::haveSuitableCachedPosition(PositionOptions* options)
{
if (!m_positionCache->cachedPosition())
@@ -393,27 +451,35 @@ bool Geolocation::haveSuitableCachedPosition(PositionOptions* options)
}
void Geolocation::clearWatch(int watchId)
+=======
+void Geolocation::requestTimedOut(GeoNotifier* notifier)
+>>>>>>> webkit.org at r58033
{
- m_watchers.remove(watchId);
-
+ // If this is a one-shot request, stop it.
+ m_oneShots.remove(notifier);
+
if (!hasListeners())
stopUpdating();
}
-void Geolocation::suspend()
+bool Geolocation::haveSuitableCachedPosition(PositionOptions* options)
{
-#if !ENABLE(CLIENT_BASED_GEOLOCATION)
- if (hasListeners())
- m_service->suspend();
-#endif
+ if (!m_positionCache->cachedPosition())
+ return false;
+ if (!options->hasMaximumAge())
+ return true;
+ if (!options->maximumAge())
+ return false;
+ DOMTimeStamp currentTimeMillis = currentTime() * 1000.0;
+ return m_positionCache->cachedPosition()->timestamp() > currentTimeMillis - options->maximumAge();
}
-void Geolocation::resume()
+void Geolocation::clearWatch(int watchId)
{
-#if !ENABLE(CLIENT_BASED_GEOLOCATION)
- if (hasListeners())
- m_service->resume();
-#endif
+ m_watchers.remove(watchId);
+
+ if (!hasListeners())
+ stopUpdating();
}
void Geolocation::setIsAllowed(bool allowed)
@@ -557,7 +623,7 @@ void Geolocation::requestPermission()
void Geolocation::positionChanged(PassRefPtr<Geoposition> newPosition)
{
- m_currentPosition = newPosition;
+ m_positionCache->setCachedPosition(newPosition.get());
m_positionCache->setCachedPosition(m_currentPosition.get());
@@ -578,7 +644,7 @@ void Geolocation::positionChanged(PassRefPtr<Geoposition> newPosition)
void Geolocation::makeSuccessCallbacks()
{
- ASSERT(m_currentPosition);
+ ASSERT(lastPosition());
ASSERT(isAllowed());
Vector<RefPtr<GeoNotifier> > oneShotsCopy;
@@ -592,8 +658,8 @@ void Geolocation::makeSuccessCallbacks()
// further callbacks to these notifiers.
m_oneShots.clear();
- sendPosition(oneShotsCopy, m_currentPosition.get());
- sendPosition(watchersCopy, m_currentPosition.get());
+ sendPosition(oneShotsCopy, lastPosition());
+ sendPosition(watchersCopy, lastPosition());
if (!hasListeners())
stopUpdating();
@@ -709,3 +775,19 @@ void Geolocation::handleEvent(ScriptExecutionContext*, Event* event)
// END ANDROID
} // namespace WebCore
+
+#else
+
+namespace WebCore {
+
+void Geolocation::disconnectFrame() {}
+
+Geolocation::Geolocation(Frame*) {}
+
+Geolocation::~Geolocation() {}
+
+void Geolocation::setIsAllowed(bool) {}
+
+}
+
+#endif // ENABLE(GEOLOCATION)
diff --git a/WebCore/page/Geolocation.h b/WebCore/page/Geolocation.h
index 358e4a3..30db435 100644
--- a/WebCore/page/Geolocation.h
+++ b/WebCore/page/Geolocation.h
@@ -27,9 +27,12 @@
#ifndef Geolocation_h
#define Geolocation_h
+<<<<<<< HEAD
// ANDROID
#include "EventListener.h"
// END ANDROID
+=======
+>>>>>>> webkit.org at r58033
#include "GeolocationPositionCache.h"
#include "GeolocationService.h"
#include "Geoposition.h"
@@ -38,14 +41,6 @@
#include "PositionErrorCallback.h"
#include "PositionOptions.h"
#include "Timer.h"
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/Platform.h>
-#include <wtf/RefCounted.h>
-#include <wtf/RefPtr.h>
-#include <wtf/Vector.h>
namespace WebCore {
@@ -56,35 +51,30 @@ class GeolocationPosition;
class GeolocationError;
#endif
+<<<<<<< HEAD
// ANDROID
class Geolocation : public EventListener
// END ANDROID
#if !ENABLE(CLIENT_BASED_GEOLOCATION)
+=======
+class Geolocation : public RefCounted<Geolocation>
+#if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
+>>>>>>> webkit.org at r58033
, public GeolocationServiceClient
#endif
{
public:
static PassRefPtr<Geolocation> create(Frame* frame) { return adoptRef(new Geolocation(frame)); }
- virtual ~Geolocation();
+ ~Geolocation();
void disconnectFrame();
- Geoposition* lastPosition();
-
void getCurrentPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
int watchPosition(PassRefPtr<PositionCallback>, PassRefPtr<PositionErrorCallback>, PassRefPtr<PositionOptions>);
void clearWatch(int watchId);
- void suspend();
- void resume();
-
void setIsAllowed(bool);
- bool isAllowed() const { return m_allowGeolocation == Yes; }
- bool isDenied() const { return m_allowGeolocation == No; }
-
- void setShouldClearCache(bool shouldClearCache) { m_shouldClearCache = shouldClearCache; }
- bool shouldClearCache() const { return m_shouldClearCache; }
Frame* frame() const { return m_frame; }
#if ENABLE(CLIENT_BASED_GEOLOCATION)
@@ -95,6 +85,11 @@ public:
#endif
private:
+ Geoposition* lastPosition();
+
+ bool isAllowed() const { return m_allowGeolocation == Yes; }
+ bool isDenied() const { return m_allowGeolocation == No; }
+
Geolocation(Frame*);
class GeoNotifier : public RefCounted<GeoNotifier> {
@@ -155,7 +150,7 @@ private:
bool startUpdating(GeoNotifier*);
void stopUpdating();
-#if !ENABLE(CLIENT_BASED_GEOLOCATION)
+#if !ENABLE(CLIENT_BASED_GEOLOCATION) && ENABLE(GEOLOCATION)
// GeolocationServiceClient
virtual void geolocationServicePositionChanged(GeolocationService*);
virtual void geolocationServiceErrorOccurred(GeolocationService*);
@@ -186,7 +181,6 @@ private:
RefPtr<GeoNotifier> m_startRequestPermissionNotifier;
#endif
RefPtr<Geoposition> m_lastPosition;
- RefPtr<Geoposition> m_currentPosition;
enum {
Unknown,
@@ -194,9 +188,16 @@ private:
Yes,
No
} m_allowGeolocation;
+<<<<<<< HEAD
bool m_shouldClearCache;
OwnPtr<GeolocationPositionCache> m_positionCache;
+=======
+
+#if ENABLE(GEOLOCATION)
+ OwnPtr<GeolocationPositionCache> m_positionCache;
+#endif
+>>>>>>> webkit.org at r58033
GeoNotifierSet m_requestsAwaitingCachedPosition;
};
diff --git a/WebCore/page/Geolocation.idl b/WebCore/page/Geolocation.idl
index 76056a3..aa5b59f 100644
--- a/WebCore/page/Geolocation.idl
+++ b/WebCore/page/Geolocation.idl
@@ -25,9 +25,7 @@
module core {
- interface [OmitConstructor] Geolocation {
- readonly attribute Geoposition lastPosition;
-
+ interface [Conditional=GEOLOCATION, OmitConstructor] Geolocation {
[Custom] void getCurrentPosition(in PositionCallback successCallback, in PositionErrorCallback errorCallback, in PositionOptions options);
[Custom] long watchPosition(in PositionCallback successCallback, in PositionErrorCallback errorCallback, in PositionOptions options);
diff --git a/WebCore/page/GeolocationPositionCache.cpp b/WebCore/page/GeolocationPositionCache.cpp
index 5796191..76d2b0b 100644
--- a/WebCore/page/GeolocationPositionCache.cpp
+++ b/WebCore/page/GeolocationPositionCache.cpp
@@ -26,6 +26,11 @@
#include "config.h"
#include "GeolocationPositionCache.h"
+<<<<<<< HEAD
+=======
+#if ENABLE(GEOLOCATION)
+
+>>>>>>> webkit.org at r58033
#include "Geoposition.h"
#include "SQLValue.h"
#include "SQLiteDatabase.h"
@@ -33,7 +38,10 @@
#include "SQLiteStatement.h"
#include "SQLiteTransaction.h"
+<<<<<<< HEAD
+=======
+>>>>>>> webkit.org at r58033
namespace WebCore {
static const char* databaseName = "CachedGeoposition.db";
@@ -173,3 +181,8 @@ void GeolocationPositionCache::writeToDB(const Geoposition* position)
}
} // namespace WebCore
+<<<<<<< HEAD
+=======
+
+#endif // ENABLE(GEOLOCATION)
+>>>>>>> webkit.org at r58033
diff --git a/WebCore/page/Geoposition.idl b/WebCore/page/Geoposition.idl
index 6fa12ff..41a2262 100644
--- a/WebCore/page/Geoposition.idl
+++ b/WebCore/page/Geoposition.idl
@@ -25,7 +25,7 @@
module core {
- interface [OmitConstructor] Geoposition {
+ interface [Conditional=GEOLOCATION, OmitConstructor] Geoposition {
readonly attribute Coordinates coords;
readonly attribute DOMTimeStamp timestamp;
};
diff --git a/WebCore/page/History.idl b/WebCore/page/History.idl
index 3fc2771..d1be5ae 100644
--- a/WebCore/page/History.idl
+++ b/WebCore/page/History.idl
@@ -41,9 +41,9 @@ module window {
[DoNotCheckDomainSecurity] void forward();
[DoNotCheckDomainSecurity] void go(in long distance);
- [Custom] void pushState(in any data, in DOMString title, in optional DOMString url)
+ [Custom, EnabledAtRuntime] void pushState(in any data, in DOMString title, in optional DOMString url)
raises(DOMException);
- [Custom] void replaceState(in any data, in DOMString title, in optional DOMString url)
+ [Custom, EnabledAtRuntime] void replaceState(in any data, in DOMString title, in optional DOMString url)
raises(DOMException);
};
diff --git a/WebCore/page/Location.cpp b/WebCore/page/Location.cpp
index 5adc48d..5754357 100644
--- a/WebCore/page/Location.cpp
+++ b/WebCore/page/Location.cpp
@@ -82,7 +82,7 @@ String Location::host() const
// Note: this is the IE spec. The NS spec swaps the two, it says
// "The hostname property is the concatenation of the host and port properties, separated by a colon."
const KURL& url = this->url();
- return url.port() ? url.host() + ":" + String::number((static_cast<int>(url.port()))) : url.host();
+ return url.port() ? url.host() + ":" + String::number(url.port()) : url.host();
}
String Location::hostname() const
@@ -99,7 +99,7 @@ String Location::port() const
return String();
const KURL& url = this->url();
- return url.port() ? String::number(static_cast<int>(url.port())) : "";
+ return url.port() ? String::number(url.port()) : "";
}
String Location::pathname() const
diff --git a/WebCore/page/OriginAccessEntry.cpp b/WebCore/page/OriginAccessEntry.cpp
index 98c280c..7ff67cc 100644
--- a/WebCore/page/OriginAccessEntry.cpp
+++ b/WebCore/page/OriginAccessEntry.cpp
@@ -40,7 +40,6 @@ OriginAccessEntry::OriginAccessEntry(const String& protocol, const String& host,
, 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.
diff --git a/WebCore/page/OriginAccessEntry.h b/WebCore/page/OriginAccessEntry.h
index 767d75f..7c8d556 100644
--- a/WebCore/page/OriginAccessEntry.h
+++ b/WebCore/page/OriginAccessEntry.h
@@ -47,15 +47,28 @@ public:
// 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;
-
+
+ const String& protocol() const { return m_protocol; }
+ const String& host() const { return m_host; }
+ SubdomainSetting subdomainSettings() const { return m_subdomainSettings; }
+
private:
String m_protocol;
String m_host;
SubdomainSetting m_subdomainSettings;
bool m_hostIsIPAddress;
-
};
+inline bool operator==(const OriginAccessEntry& a, const OriginAccessEntry& b)
+{
+ return equalIgnoringCase(a.protocol(), b.protocol()) && equalIgnoringCase(a.host(), b.host()) && a.subdomainSettings() == b.subdomainSettings();
+}
+
+inline bool operator!=(const OriginAccessEntry& a, const OriginAccessEntry& b)
+{
+ return !(a == b);
+}
+
} // namespace WebCore
#endif // CrossOriginAccess_h
diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp
index d348d73..ee5c052 100644
--- a/WebCore/page/Page.cpp
+++ b/WebCore/page/Page.cpp
@@ -30,10 +30,10 @@
#include "ContextMenuController.h"
#include "DOMWindow.h"
#include "DragController.h"
-#include "ExceptionCode.h"
#include "EditorClient.h"
-#include "EventNames.h"
#include "Event.h"
+#include "EventNames.h"
+#include "ExceptionCode.h"
#include "FileSystem.h"
#include "FocusController.h"
#include "Frame.h"
@@ -52,12 +52,14 @@
#include "PageGroup.h"
#include "PluginData.h"
#include "PluginHalter.h"
+#include "PluginView.h"
#include "ProgressTracker.h"
-#include "RenderWidget.h"
#include "RenderTheme.h"
+#include "RenderWidget.h"
#include "ScriptController.h"
#include "SelectionController.h"
#include "Settings.h"
+#include "SharedBuffer.h"
#include "StringHash.h"
#include "TextResourceDecoder.h"
#include "Widget.h"
@@ -70,8 +72,8 @@
#include "StorageNamespace.h"
#endif
-#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
-#include "JavaScriptDebugServer.h"
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+#include "ScriptDebugServer.h"
#endif
#if ENABLE(WML)
@@ -151,9 +153,6 @@ 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)
@@ -192,8 +191,8 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
m_pluginHalter->setPluginAllowedRunTime(m_settings->pluginAllowedRunTime());
}
-#if ENABLE(JAVASCRIPT_DEBUGGER) && USE(JSC)
- JavaScriptDebugServer::shared().pageCreated(this);
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+ ScriptDebugServer::shared().pageCreated(this);
#endif
#ifndef NDEBUG
@@ -212,8 +211,6 @@ Page::~Page()
m_editorClient->pageDestroyed();
#if ENABLE(INSPECTOR)
- if (m_parentInspectorController)
- m_parentInspectorController->pageDestroyed();
m_inspectorController->inspectedPageDestroyed();
#endif
@@ -310,7 +307,7 @@ void Page::goToItem(HistoryItem* item, FrameLoadType type)
{
// Abort any current load unless we're navigating the current document to a new state object
HistoryItem* currentItem = m_mainFrame->loader()->history()->currentItem();
- if (!item->stateObject() || !currentItem || item->documentSequenceNumber() != currentItem->documentSequenceNumber()) {
+ if (!item->stateObject() || !currentItem || item->documentSequenceNumber() != currentItem->documentSequenceNumber() || item == currentItem) {
// Define what to do with any open database connections. By default we stop them and terminate the database thread.
DatabasePolicy databasePolicy = DatabasePolicyStop;
@@ -407,7 +404,7 @@ void Page::refreshPlugins(bool reload)
PluginData* Page::pluginData() const
{
- if (!settings()->arePluginsEnabled())
+ if (!mainFrame()->loader()->allowPlugins(NotAboutToInstantiatePlugin))
return 0;
if (!m_pluginData)
m_pluginData = PluginData::create(this);
@@ -725,7 +722,7 @@ void Page::setDebugger(JSC::Debugger* debugger)
StorageNamespace* Page::sessionStorage(bool optionalCreate)
{
if (!m_sessionStorage && optionalCreate)
- m_sessionStorage = StorageNamespace::sessionStorageNamespace(this);
+ m_sessionStorage = StorageNamespace::sessionStorageNamespace(this, m_settings->sessionStorageQuota());
return m_sessionStorage.get();
}
@@ -793,6 +790,35 @@ InspectorTimelineAgent* Page::inspectorTimelineAgent() const
}
#endif
+void Page::privateBrowsingStateChanged()
+{
+ bool privateBrowsingEnabled = m_settings->privateBrowsingEnabled();
+
+ // Collect the PluginViews in to a vector to ensure that action the plug-in takes
+ // from below privateBrowsingStateChanged does not affect their lifetime.
+
+ Vector<RefPtr<PluginView>, 32> pluginViews;
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
+ FrameView* view = frame->view();
+ if (!view)
+ return;
+
+ const HashSet<RefPtr<Widget> >* children = view->children();
+ ASSERT(children);
+
+ HashSet<RefPtr<Widget> >::const_iterator end = children->end();
+ for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != end; ++it) {
+ Widget* widget = (*it).get();
+ if (!widget->isPluginView())
+ continue;
+ pluginViews.append(static_cast<PluginView*>(widget));
+ }
+ }
+
+ for (size_t i = 0; i < pluginViews.size(); i++)
+ pluginViews[i]->privateBrowsingStateChanged(privateBrowsingEnabled);
+}
+
void Page::pluginAllowedRunTimeChanged()
{
if (m_pluginHalter)
diff --git a/WebCore/page/Page.h b/WebCore/page/Page.h
index 04a545c..94e6dd5 100644
--- a/WebCore/page/Page.h
+++ b/WebCore/page/Page.h
@@ -31,10 +31,6 @@
#include "SchedulePair.h"
#endif
-#if PLATFORM(WIN) || (PLATFORM(WX) && OS(WINDOWS)) || (PLATFORM(QT) && defined(Q_WS_WIN))
-typedef struct HINSTANCE__* HINSTANCE;
-#endif
-
namespace JSC {
class Debugger;
}
@@ -153,11 +149,6 @@ namespace WebCore {
#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; }
@@ -197,6 +188,8 @@ namespace WebCore {
void userStyleSheetLocationChanged();
const String& userStyleSheet() const;
+ void privateBrowsingStateChanged();
+
void didStartPlugin(HaltablePlugin*);
void didStopPlugin(HaltablePlugin*);
void pluginAllowedRunTimeChanged();
@@ -205,12 +198,6 @@ namespace WebCore {
void setDebugger(JSC::Debugger*);
JSC::Debugger* debugger() const { return m_debugger; }
-#if PLATFORM(WIN) || (PLATFORM(WX) && OS(WINDOWS)) || (PLATFORM(QT) && defined(Q_WS_WIN))
- // The global DLL or application instance used for all windows.
- static void setInstanceHandle(HINSTANCE instanceHandle) { s_instanceHandle = instanceHandle; }
- static HINSTANCE instanceHandle() { return s_instanceHandle; }
-#endif
-
static void removeAllVisitedLinks();
static void allVisitedStateChanged(PageGroup*);
@@ -294,10 +281,6 @@ namespace WebCore {
bool m_javaScriptURLsAreAllowed;
-#if ENABLE(INSPECTOR)
- InspectorController* m_parentInspectorController;
-#endif
-
String m_userStyleSheetPath;
mutable String m_userStyleSheet;
mutable bool m_didLoadUserStyleSheet;
@@ -320,10 +303,6 @@ namespace WebCore {
RefPtr<StorageNamespace> m_sessionStorage;
#endif
-#if PLATFORM(WIN) || (PLATFORM(WX) && defined(__WXMSW__)) || (PLATFORM(QT) && defined(Q_WS_WIN))
- static HINSTANCE s_instanceHandle;
-#endif
-
#if ENABLE(WML)
OwnPtr<WMLPageState> m_wmlPageState;
#endif
diff --git a/WebCore/page/PageGroup.cpp b/WebCore/page/PageGroup.cpp
index f376d52..f6c746d 100644
--- a/WebCore/page/PageGroup.cpp
+++ b/WebCore/page/PageGroup.cpp
@@ -30,12 +30,10 @@
#include "ChromeClient.h"
#include "Document.h"
#include "Frame.h"
+#include "IndexedDatabase.h"
#include "Page.h"
#include "Settings.h"
-
-#if ENABLE(DOM_STORAGE)
#include "StorageNamespace.h"
-#endif
#if PLATFORM(CHROMIUM)
#include "ChromiumBridge.h"
@@ -191,6 +189,9 @@ StorageNamespace* PageGroup::localStorage()
{
if (!m_localStorage) {
// Need a page in this page group to query the settings for the local storage database path.
+ // Having these parameters attached to the page settings is unfortunate since these settings are
+ // not per-page (and, in fact, we simply grab the settings from some page at random), but
+ // at this point we're stuck with it.
Page* page = *m_pages.begin();
const String& path = page->settings()->localStorageDatabasePath();
unsigned quota = page->settings()->localStorageQuota();
@@ -201,6 +202,17 @@ StorageNamespace* PageGroup::localStorage()
}
#endif
+#if ENABLE(INDEXED_DATABASE)
+IndexedDatabase* PageGroup::indexedDatabase()
+{
+ // Do not add page setting based access control here since this object is shared by all pages in
+ // the group and having per-page controls is misleading.
+ if (!m_indexedDatabase)
+ m_indexedDatabase = IndexedDatabase::create();
+ return m_indexedDatabase.get();
+}
+#endif
+
void PageGroup::addUserScriptToWorld(DOMWrapperWorld* world, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist,
PassOwnPtr<Vector<String> > blacklist, UserScriptInjectionTime injectionTime)
{
diff --git a/WebCore/page/PageGroup.h b/WebCore/page/PageGroup.h
index 446f0c7..c1d25fa 100644
--- a/WebCore/page/PageGroup.h
+++ b/WebCore/page/PageGroup.h
@@ -36,6 +36,7 @@
namespace WebCore {
class KURL;
+ class IndexedDatabase;
class Page;
class StorageNamespace;
@@ -69,6 +70,9 @@ namespace WebCore {
StorageNamespace* localStorage();
bool hasLocalStorage() { return m_localStorage; }
#endif
+#if ENABLE(DOM_STORAGE)
+ IndexedDatabase* indexedDatabase();
+#endif
void addUserScriptToWorld(DOMWrapperWorld*, const String& source, const KURL&,
PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist,
@@ -101,6 +105,9 @@ namespace WebCore {
#if ENABLE(DOM_STORAGE)
RefPtr<StorageNamespace> m_localStorage;
#endif
+#if ENABLE(INDEXED_DATABASE)
+ RefPtr<IndexedDatabase> m_indexedDatabase;
+#endif
OwnPtr<UserScriptMap> m_userScripts;
OwnPtr<UserStyleSheetMap> m_userStyleSheets;
diff --git a/WebCore/page/PositionCallback.h b/WebCore/page/PositionCallback.h
index 9f36d7a..5b7a202 100644
--- a/WebCore/page/PositionCallback.h
+++ b/WebCore/page/PositionCallback.h
@@ -26,7 +26,6 @@
#ifndef PositionCallback_h
#define PositionCallback_h
-#include <wtf/Platform.h>
#include <wtf/RefCounted.h>
namespace WebCore {
diff --git a/WebCore/page/PositionError.idl b/WebCore/page/PositionError.idl
index 1f28d95..5870e0d 100644
--- a/WebCore/page/PositionError.idl
+++ b/WebCore/page/PositionError.idl
@@ -25,7 +25,7 @@
module core {
- interface PositionError {
+ interface [Conditional=GEOLOCATION] PositionError {
readonly attribute unsigned short code;
readonly attribute DOMString message;
diff --git a/WebCore/page/PositionErrorCallback.h b/WebCore/page/PositionErrorCallback.h
index c23e883..e784297 100644
--- a/WebCore/page/PositionErrorCallback.h
+++ b/WebCore/page/PositionErrorCallback.h
@@ -26,7 +26,6 @@
#ifndef PositionErrorCallback_h
#define PositionErrorCallback_h
-#include <wtf/Platform.h>
#include <wtf/RefCounted.h>
namespace WebCore {
diff --git a/WebCore/page/PrintContext.cpp b/WebCore/page/PrintContext.cpp
index 31c8777..e0235de 100644
--- a/WebCore/page/PrintContext.cpp
+++ b/WebCore/page/PrintContext.cpp
@@ -32,11 +32,13 @@ namespace WebCore {
PrintContext::PrintContext(Frame* frame)
: m_frame(frame)
+ , m_isPrinting(false)
{
}
PrintContext::~PrintContext()
{
+ ASSERT(!m_isPrinting);
m_pageRects.clear();
}
@@ -58,18 +60,18 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig
if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
return;
- RenderView* root = toRenderView(m_frame->document()->renderer());
-
- if (!root) {
- LOG_ERROR("document to be printed has no renderer");
+ if (userScaleFactor <= 0) {
+ LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
return;
}
+ RenderView* root = toRenderView(m_frame->document()->renderer());
+
float ratio = printRect.height() / printRect.width();
float pageWidth = (float)root->rightLayoutOverflow();
float pageHeight = pageWidth * ratio;
- outPageHeight = pageHeight; // this is the height of the page adjusted by margins
+ outPageHeight = pageHeight; // this is the height of the page adjusted by margins
pageHeight -= headerHeight + footerHeight;
if (pageHeight <= 0) {
@@ -77,26 +79,25 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig
return;
}
- computePageRectsWithPageSize(FloatSize(pageWidth, pageHeight), userScaleFactor);
+ computePageRectsWithPageSizeInternal(FloatSize(pageWidth / userScaleFactor, pageHeight / userScaleFactor), false);
}
-void PrintContext::computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, float userScaleFactor)
+void PrintContext::computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalMultiPages)
{
- RenderView* root = toRenderView(m_frame->document()->renderer());
-
- if (!root) {
- LOG_ERROR("document to be printed has no renderer");
- return;
- }
+ m_pageRects.clear();
+ computePageRectsWithPageSizeInternal(pageSizeInPixels, allowHorizontalMultiPages);
+}
- if (userScaleFactor <= 0) {
- LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
+void PrintContext::computePageRectsWithPageSizeInternal(const FloatSize& pageSizeInPixels, bool allowHorizontalMultiPages)
+{
+ if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer())
return;
- }
+ RenderView* root = toRenderView(m_frame->document()->renderer());
- float currPageHeight = pageSizeInPixels.height() / userScaleFactor;
- float docHeight = root->layer()->height();
- float currPageWidth = pageSizeInPixels.width() / userScaleFactor;
+ const float pageWidth = pageSizeInPixels.width();
+ const float docWidth = root->layer()->width();
+ const float docHeight = root->layer()->height();
+ float currPageHeight = pageSizeInPixels.height();
// always return at least one page, since empty files should print a blank page
float printedPagesHeight = 0;
@@ -104,14 +105,20 @@ void PrintContext::computePageRectsWithPageSize(const FloatSize& pageSizeInPixel
float proposedBottom = std::min(docHeight, printedPagesHeight + pageSizeInPixels.height());
m_frame->view()->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
-
- m_pageRects.append(IntRect(0, (int)printedPagesHeight, (int)currPageWidth, (int)currPageHeight));
+ if (allowHorizontalMultiPages) {
+ for (float curWidth = 0; curWidth < docWidth; curWidth += pageWidth)
+ m_pageRects.append(IntRect(curWidth, (int)printedPagesHeight, (int)pageWidth, (int)currPageHeight));
+ } else
+ m_pageRects.append(IntRect(0, (int)printedPagesHeight, (int)pageWidth, (int)currPageHeight));
printedPagesHeight += currPageHeight;
} while (printedPagesHeight < docHeight);
}
void PrintContext::begin(float width)
{
+ ASSERT(!m_isPrinting);
+ m_isPrinting = true;
+
// By imaging to a width a little wider than the available pixels,
// thin pages will be scaled down a little, matching the way they
// print in IE and Camino. This lets them use fewer sheets than they
@@ -148,6 +155,8 @@ void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
void PrintContext::end()
{
+ ASSERT(m_isPrinting);
+ m_isPrinting = false;
m_frame->setPrinting(false, 0, 0, true);
}
@@ -175,17 +184,18 @@ int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSi
FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
PrintContext printContext(frame);
printContext.begin(pageRect.width());
- printContext.computePageRectsWithPageSize(pageSizeInPixels, 1);
+ printContext.computePageRectsWithPageSize(pageSizeInPixels, false);
int top = box->offsetTop();
int left = box->offsetLeft();
- for (int pageNumber = 0; pageNumber < printContext.pageCount(); pageNumber++) {
+ int pageNumber = 0;
+ for (; pageNumber < printContext.pageCount(); pageNumber++) {
const IntRect& page = printContext.pageRect(pageNumber);
if (page.x() <= left && left < page.right() && page.y() <= top && top < page.bottom())
- return pageNumber;
+ break;
}
printContext.end();
- return -1;
+ return (pageNumber < printContext.pageCount() ? pageNumber : -1);
}
int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels)
@@ -195,7 +205,7 @@ int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels)
FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
PrintContext printContext(frame);
printContext.begin(pageRect.width());
- printContext.computePageRectsWithPageSize(pageSizeInPixels, 1);
+ printContext.computePageRectsWithPageSize(pageSizeInPixels, false);
printContext.end();
return printContext.pageCount();
}
diff --git a/WebCore/page/PrintContext.h b/WebCore/page/PrintContext.h
index ec15b84..1891144 100644
--- a/WebCore/page/PrintContext.h
+++ b/WebCore/page/PrintContext.h
@@ -42,6 +42,7 @@ public:
const Vector<IntRect>& pageRects() const { return m_pageRects; }
void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight);
+ void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, bool allowHorizontalMultiPages);
// TODO: eliminate width param
void begin(float width);
@@ -56,10 +57,14 @@ public:
static int numberOfPages(Frame*, const FloatSize& pageSizeInPixels);
protected:
- void computePageRectsWithPageSize(const FloatSize& pageSizeInPixels, float userScaleFactor);
-
Frame* m_frame;
Vector<IntRect> m_pageRects;
+
+private:
+ void computePageRectsWithPageSizeInternal(const FloatSize& pageSizeInPixels, bool allowHorizontalMultiPages);
+
+ // Used to prevent misuses of begin() and end() (e.g., call end without begin).
+ bool m_isPrinting;
};
}
diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp
index fe6efbd..265c643 100644
--- a/WebCore/page/SecurityOrigin.cpp
+++ b/WebCore/page/SecurityOrigin.cpp
@@ -29,7 +29,6 @@
#include "config.h"
#include "SecurityOrigin.h"
-#include "CString.h"
#include "Document.h"
#include "KURL.h"
#include "OriginAccessEntry.h"
@@ -65,6 +64,19 @@ static URLSchemesMap& localSchemes()
return localSchemes;
}
+static URLSchemesMap& secureSchemes()
+{
+ DEFINE_STATIC_LOCAL(URLSchemesMap, secureSchemes, ());
+
+ if (secureSchemes.isEmpty()) {
+ secureSchemes.add("https");
+ secureSchemes.add("about");
+ secureSchemes.add("data");
+ }
+
+ return secureSchemes;
+}
+
static URLSchemesMap& schemesWithUniqueOrigins()
{
DEFINE_STATIC_LOCAL(URLSchemesMap, schemesWithUniqueOrigins, ());
@@ -85,6 +97,7 @@ SecurityOrigin::SecurityOrigin(const KURL& url, SandboxFlags sandboxFlags)
, m_isUnique(isSandboxed(SandboxOrigin) || shouldTreatURLSchemeAsNoAccess(m_protocol))
, m_universalAccess(false)
, m_domainWasSetInDOM(false)
+ , m_enforceFilePathSeparation(false)
{
// These protocols do not create security origins; the owner frame provides the origin
if (m_protocol == "about" || m_protocol == "javascript")
@@ -99,6 +112,8 @@ SecurityOrigin::SecurityOrigin(const KURL& url, SandboxFlags sandboxFlags)
// Directories should never be readable.
if (!url.hasPath() || url.path().endsWith("/"))
m_isUnique = true;
+ // Store the path in case we are doing per-file origin checking.
+ m_filePath = url.path();
}
if (isDefaultPortForProtocol(m_port, m_protocol))
@@ -109,12 +124,15 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other)
: m_sandboxFlags(other->m_sandboxFlags)
, m_protocol(other->m_protocol.threadsafeCopy())
, m_host(other->m_host.threadsafeCopy())
+ , m_encodedHost(other->m_encodedHost.threadsafeCopy())
, m_domain(other->m_domain.threadsafeCopy())
+ , m_filePath(other->m_filePath.threadsafeCopy())
, m_port(other->m_port)
, m_isUnique(other->m_isUnique)
, m_universalAccess(other->m_universalAccess)
, m_domainWasSetInDOM(other->m_domainWasSetInDOM)
, m_canLoadLocalResources(other->m_canLoadLocalResources)
+ , m_enforceFilePathSeparation(other->m_enforceFilePathSeparation)
{
}
@@ -172,7 +190,7 @@ bool SecurityOrigin::isDomainRelaxationForbiddenForURLScheme(const String& schem
}
bool SecurityOrigin::canAccess(const SecurityOrigin* other) const
-{
+{
if (m_universalAccess)
return true;
@@ -199,17 +217,31 @@ bool SecurityOrigin::canAccess(const SecurityOrigin* other) const
// Opera 9 allows access when only one page has set document.domain, but
// this is a security vulnerability.
+ bool canAccess = false;
if (m_protocol == other->m_protocol) {
if (!m_domainWasSetInDOM && !other->m_domainWasSetInDOM) {
if (m_host == other->m_host && m_port == other->m_port)
- return true;
+ canAccess = true;
} else if (m_domainWasSetInDOM && other->m_domainWasSetInDOM) {
if (m_domain == other->m_domain)
- return true;
+ canAccess = true;
}
}
-
- return false;
+
+ if (canAccess && isLocal())
+ canAccess = passesFileCheck(other);
+
+ return canAccess;
+}
+
+bool SecurityOrigin::passesFileCheck(const SecurityOrigin* other) const
+{
+ ASSERT(isLocal() && other->isLocal());
+
+ if (!m_enforceFilePathSeparation && !other->m_enforceFilePathSeparation)
+ return true;
+
+ return (m_filePath == other->m_filePath);
}
bool SecurityOrigin::canRequest(const KURL& url) const
@@ -229,12 +261,8 @@ bool SecurityOrigin::canRequest(const KURL& url) const
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;
- }
- }
+ if (isAccessWhiteListed(targetOrigin.get()))
+ return true;
return false;
}
@@ -256,15 +284,32 @@ bool SecurityOrigin::taintsCanvas(const KURL& url) const
return true;
}
+bool SecurityOrigin::isAccessWhiteListed(const SecurityOrigin* targetOrigin) const
+{
+ 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::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 we were provided a document, we first check if the access has been white listed.
+ // Then we let its local file police dictate the result.
+ // Otherwise we allow local loads only if the supplied referrer is also local.
+ if (document) {
+ SecurityOrigin* documentOrigin = document->securityOrigin();
+ RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url);
+ if (documentOrigin->isAccessWhiteListed(targetOrigin.get()))
+ return true;
+ return documentOrigin->canLoadLocalResources();
+ }
if (!referrer.isEmpty())
return shouldTreatURLAsLocal(referrer);
return false;
@@ -286,9 +331,10 @@ void SecurityOrigin::grantUniversalAccess()
m_universalAccess = true;
}
-void SecurityOrigin::makeUnique()
+void SecurityOrigin::enforceFilePathSeparation()
{
- m_isUnique = true;
+ ASSERT(isLocal());
+ m_enforceFilePathSeparation = true;
}
bool SecurityOrigin::isLocal() const
@@ -314,8 +360,11 @@ String SecurityOrigin::toString() const
if (isUnique())
return "null";
- if (m_protocol == "file")
- return String("file://");
+ if (m_protocol == "file") {
+ if (m_enforceFilePathSeparation)
+ return "null";
+ return "file://";
+ }
Vector<UChar> result;
result.reserveInitialCapacity(m_protocol.length() + m_host.length() + 10);
@@ -368,13 +417,92 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const St
// Split out the 3 sections of data
String protocol = databaseIdentifier.substring(0, separator1);
String host = databaseIdentifier.substring(separator1 + 1, separator2 - separator1 - 1);
+
+ host = decodeURLEscapeSequences(host);
return create(KURL(KURL(), protocol + "://" + host + ":" + String::number(port)));
}
+// The following lower-ASCII characters need escaping to be used in a filename
+// across all systems, including Windows:
+// - Unprintable ASCII (00-1F)
+// - Space (20)
+// - Double quote (22)
+// - Percent (25) (escaped because it is our escape character)
+// - Asterisk (2A)
+// - Slash (2F)
+// - Colon (3A)
+// - Less-than (3C)
+// - Greater-than (3E)
+// - Question Mark (3F)
+// - Backslash (5C)
+// - Pipe (7C)
+// - Delete (7F)
+
+static const bool needsEscaping[128] = {
+ /* 00-07 */ true, true, true, true, true, true, true, true,
+ /* 08-0F */ true, true, true, true, true, true, true, true,
+
+ /* 10-17 */ true, true, true, true, true, true, true, true,
+ /* 18-1F */ true, true, true, true, true, true, true, true,
+
+ /* 20-27 */ true, false, true, false, false, true, false, false,
+ /* 28-2F */ false, false, true, false, false, false, false, true,
+
+ /* 30-37 */ false, false, false, false, false, false, false, false,
+ /* 38-3F */ false, false, true, false, true, false, true, true,
+
+ /* 40-47 */ false, false, false, false, false, false, false, false,
+ /* 48-4F */ false, false, false, false, false, false, false, false,
+
+ /* 50-57 */ false, false, false, false, false, false, false, false,
+ /* 58-5F */ false, false, false, false, true, false, false, false,
+
+ /* 60-67 */ false, false, false, false, false, false, false, false,
+ /* 68-6F */ false, false, false, false, false, false, false, false,
+
+ /* 70-77 */ false, false, false, false, false, false, false, false,
+ /* 78-7F */ false, false, false, false, true, false, false, true,
+};
+
+static inline bool shouldEscapeUChar(UChar c)
+{
+ return c > 127 ? false : needsEscaping[c];
+}
+
+static const char hexDigits[17] = "0123456789ABCDEF";
+
+static String encodedHost(const String& host)
+{
+ unsigned length = host.length();
+ Vector<UChar, 512> buffer(length * 3 + 1);
+ UChar* p = buffer.data();
+
+ const UChar* str = host.characters();
+ const UChar* strEnd = str + length;
+
+ while (str < strEnd) {
+ UChar c = *str++;
+ if (shouldEscapeUChar(c)) {
+ *p++ = '%';
+ *p++ = hexDigits[(c >> 4) & 0xF];
+ *p++ = hexDigits[c & 0xF];
+ } else
+ *p++ = c;
+ }
+
+ ASSERT(p - buffer.data() <= static_cast<int>(buffer.size()));
+
+ return String(buffer.data(), p - buffer.data());
+}
+
String SecurityOrigin::databaseIdentifier() const
{
- DEFINE_STATIC_LOCAL(String, separatorString, (&SeparatorCharacter, 1));
- return m_protocol + separatorString + m_host + separatorString + String::number(m_port);
+ String separatorString(&SeparatorCharacter, 1);
+
+ if (m_encodedHost.isEmpty())
+ m_encodedHost = encodedHost(m_host);
+
+ return m_protocol + separatorString + m_encodedHost + separatorString + String::number(m_port);
}
bool SecurityOrigin::equal(const SecurityOrigin* other) const
@@ -405,6 +533,9 @@ bool SecurityOrigin::isSameSchemeHostPort(const SecurityOrigin* other) const
if (m_port != other->m_port)
return false;
+ if (isLocal() && !passesFileCheck(other))
+ return false;
+
return true;
}
@@ -477,6 +608,16 @@ bool SecurityOrigin::shouldTreatURLSchemeAsNoAccess(const String& scheme)
return schemesWithUniqueOrigins().contains(scheme);
}
+void SecurityOrigin::registerURLSchemeAsSecure(const String& scheme)
+{
+ secureSchemes().add(scheme);
+}
+
+bool SecurityOrigin::shouldTreatURLSchemeAsSecure(const String& scheme)
+{
+ return secureSchemes().contains(scheme);
+}
+
bool SecurityOrigin::shouldHideReferrer(const KURL& url, const String& referrer)
{
bool referrerIsSecureURL = protocolIs(referrer, "https");
@@ -508,7 +649,7 @@ bool SecurityOrigin::allowSubstituteDataAccessToLocal()
return localLoadPolicy != SecurityOrigin::AllowLocalLoadsForLocalOnly;
}
-void SecurityOrigin::whiteListAccessFromOrigin(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains)
+void SecurityOrigin::addOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains)
{
ASSERT(isMainThread());
ASSERT(!sourceOrigin.isEmpty());
@@ -516,15 +657,42 @@ void SecurityOrigin::whiteListAccessFromOrigin(const SecurityOrigin& sourceOrigi
return;
String sourceString = sourceOrigin.toString();
- OriginAccessWhiteList* list = originAccessMap().get(sourceString);
- if (!list) {
- list = new OriginAccessWhiteList;
- originAccessMap().set(sourceString, list);
- }
+ pair<OriginAccessMap::iterator, bool> result = originAccessMap().add(sourceString, 0);
+ if (result.second)
+ result.first->second = new OriginAccessWhiteList;
+
+ OriginAccessWhiteList* list = result.first->second;
list->append(OriginAccessEntry(destinationProtocol, destinationDomains, allowDestinationSubdomains ? OriginAccessEntry::AllowSubdomains : OriginAccessEntry::DisallowSubdomains));
}
-void SecurityOrigin::resetOriginAccessWhiteLists()
+void SecurityOrigin::removeOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains)
+{
+ ASSERT(isMainThread());
+ ASSERT(!sourceOrigin.isEmpty());
+ if (sourceOrigin.isEmpty())
+ return;
+
+ String sourceString = sourceOrigin.toString();
+ OriginAccessMap& map = originAccessMap();
+ OriginAccessMap::iterator it = map.find(sourceString);
+ if (it == map.end())
+ return;
+
+ OriginAccessWhiteList* list = it->second;
+ size_t index = list->find(OriginAccessEntry(destinationProtocol, destinationDomains, allowDestinationSubdomains ? OriginAccessEntry::AllowSubdomains : OriginAccessEntry::DisallowSubdomains));
+ if (index == notFound)
+ return;
+
+ list->remove(index);
+
+ if (!list->isEmpty())
+ return;
+
+ map.remove(it);
+ delete list;
+}
+
+void SecurityOrigin::resetOriginAccessWhitelists()
{
ASSERT(isMainThread());
OriginAccessMap& map = originAccessMap();
diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h
index c96bb83..d732664 100644
--- a/WebCore/page/SecurityOrigin.h
+++ b/WebCore/page/SecurityOrigin.h
@@ -117,7 +117,7 @@ public:
bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
bool canAccessDatabase() const { return !isUnique(); }
- bool canAccessStorage() const { return !isUnique(); }
+ bool canAccessLocalStorage() const { return !isUnique(); }
bool canAccessCookies() const { return !isUnique(); }
bool isSecureTransitionTo(const KURL&) const;
@@ -138,8 +138,8 @@ public:
// addition, the SandboxOrigin flag is inherited by iframes.
bool isUnique() const { return m_isUnique; }
- // Marks an origin as being unique.
- void makeUnique();
+ // Marks a file:// origin as being in a domain defined by its path.
+ void enforceFilePathSeparation();
// Convert this SecurityOrigin into a string. The string
// representation of a SecurityOrigin is similar to a URL, except it
@@ -174,6 +174,12 @@ public:
static bool shouldTreatURLAsLocal(const String&);
static bool shouldTreatURLSchemeAsLocal(const String&);
+ // Secure schemes do not trigger mixed content warnings. For example,
+ // https and data are secure schemes because they cannot be corrupted by
+ // active network attackers.
+ static void registerURLSchemeAsSecure(const String&);
+ static bool shouldTreatURLSchemeAsSecure(const String&);
+
static bool shouldHideReferrer(const KURL&, const String& referrer);
enum LocalLoadPolicy {
@@ -188,22 +194,30 @@ public:
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 void addOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains);
+ static void removeOriginAccessWhitelistEntry(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains);
+ static void resetOriginAccessWhitelists();
private:
SecurityOrigin(const KURL&, SandboxFlags);
explicit SecurityOrigin(const SecurityOrigin*);
+ bool passesFileCheck(const SecurityOrigin* other) const;
+
+ bool isAccessWhiteListed(const SecurityOrigin* targetOrigin) const;
+
SandboxFlags m_sandboxFlags;
String m_protocol;
String m_host;
+ mutable String m_encodedHost;
String m_domain;
+ String m_filePath;
unsigned short m_port;
bool m_isUnique;
bool m_universalAccess;
bool m_domainWasSetInDOM;
bool m_canLoadLocalResources;
+ bool m_enforceFilePathSeparation;
};
} // namespace WebCore
diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp
index c59bdd0..e1b848a 100644
--- a/WebCore/page/Settings.cpp
+++ b/WebCore/page/Settings.cpp
@@ -27,12 +27,14 @@
#include "Settings.h"
#include "BackForwardList.h"
+#include "Database.h"
#include "Frame.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "HistoryItem.h"
#include "Page.h"
#include "PageCache.h"
+#include "StorageMap.h"
#include <limits>
using namespace std;
@@ -74,15 +76,20 @@ Settings::Settings(Page* page)
, m_blockNetworkImage(false)
#endif
, m_maximumDecodedImageSize(numeric_limits<size_t>::max())
+#if ENABLE(DOM_STORAGE)
, m_localStorageQuota(5 * 1024 * 1024) // Suggested by the HTML5 spec.
+ , m_sessionStorageQuota(StorageMap::noQuota)
+#endif
, m_pluginAllowedRunTime(numeric_limits<unsigned>::max())
+ , m_zoomMode(ZoomPage)
+ , m_isSpatialNavigationEnabled(false)
, m_isJavaEnabled(false)
, m_loadsImagesAutomatically(false)
, m_privateBrowsingEnabled(false)
, m_caretBrowsingEnabled(false)
, m_areImagesEnabled(true)
+ , m_isMediaEnabled(true)
, m_arePluginsEnabled(false)
- , m_databasesEnabled(false)
, m_localStorageEnabled(false)
, m_isJavaScriptEnabled(false)
, m_isWebSecurityEnabled(true)
@@ -108,13 +115,12 @@ Settings::Settings(Page* page)
, m_authorAndUserStylesEnabled(true)
, m_needsSiteSpecificQuirks(false)
, m_fontRenderingMode(0)
- , m_frameSetFlatteningEnabled(false)
+ , m_frameFlatteningEnabled(false)
, m_webArchiveDebugModeEnabled(false)
, m_localFileContentSniffingEnabled(false)
, m_inApplicationChromeMode(false)
, m_offlineWebApplicationCacheEnabled(false)
, m_shouldPaintCustomScrollbars(false)
- , m_zoomsTextOnly(false)
, m_enforceCSSMIMETypeInStrictMode(true)
, m_usesEncodingDetector(false)
, m_allowScriptsToCloseWindows(false)
@@ -135,11 +141,14 @@ Settings::Settings(Page* page)
, m_showRepaintCounter(false)
, m_experimentalNotificationsEnabled(false)
, m_webGLEnabled(false)
- , m_geolocationEnabled(true)
, m_loadDeferringEnabled(true)
+<<<<<<< HEAD
#ifdef ANDROID_PLUGINS
, m_pluginsOnDemand(false)
#endif
+=======
+ , m_tiledBackingStoreEnabled(false)
+>>>>>>> webkit.org at r58033
{
// A Frame may not have been created yet, so we initialize the AtomicString
// hash before trying to use it.
@@ -271,6 +280,11 @@ void Settings::setAllowFileAccessFromFileURLs(bool allowFileAccessFromFileURLs)
m_allowFileAccessFromFileURLs = allowFileAccessFromFileURLs;
}
+void Settings::setSpatialNavigationEnabled(bool isSpatialNavigationEnabled)
+{
+ m_isSpatialNavigationEnabled = isSpatialNavigationEnabled;
+}
+
void Settings::setJavaEnabled(bool isJavaEnabled)
{
m_isJavaEnabled = isJavaEnabled;
@@ -281,14 +295,14 @@ void Settings::setImagesEnabled(bool areImagesEnabled)
m_areImagesEnabled = areImagesEnabled;
}
-void Settings::setPluginsEnabled(bool arePluginsEnabled)
+void Settings::setMediaEnabled(bool isMediaEnabled)
{
- m_arePluginsEnabled = arePluginsEnabled;
+ m_isMediaEnabled = isMediaEnabled;
}
-void Settings::setDatabasesEnabled(bool databasesEnabled)
+void Settings::setPluginsEnabled(bool arePluginsEnabled)
{
- m_databasesEnabled = databasesEnabled;
+ m_arePluginsEnabled = arePluginsEnabled;
}
void Settings::setLocalStorageEnabled(bool localStorageEnabled)
@@ -296,14 +310,25 @@ void Settings::setLocalStorageEnabled(bool localStorageEnabled)
m_localStorageEnabled = localStorageEnabled;
}
+#if ENABLE(DOM_STORAGE)
void Settings::setLocalStorageQuota(unsigned localStorageQuota)
{
m_localStorageQuota = localStorageQuota;
}
+void Settings::setSessionStorageQuota(unsigned sessionStorageQuota)
+{
+ m_sessionStorageQuota = sessionStorageQuota;
+}
+#endif
+
void Settings::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
{
+ if (m_privateBrowsingEnabled == privateBrowsingEnabled)
+ return;
+
m_privateBrowsingEnabled = privateBrowsingEnabled;
+ m_page->privateBrowsingStateChanged();
}
void Settings::setJavaScriptCanOpenWindowsAutomatically(bool javaScriptCanOpenWindowsAutomatically)
@@ -631,9 +656,9 @@ void Settings::setNeedsSiteSpecificQuirks(bool needsQuirks)
m_needsSiteSpecificQuirks = needsQuirks;
}
-void Settings::setFrameSetFlatteningEnabled(bool frameSetFlatteningEnabled)
+void Settings::setFrameFlatteningEnabled(bool frameFlatteningEnabled)
{
- m_frameSetFlatteningEnabled = frameSetFlatteningEnabled;
+ m_frameFlatteningEnabled = frameFlatteningEnabled;
}
void Settings::setWebArchiveDebugModeEnabled(bool enabled)
@@ -666,12 +691,12 @@ void Settings::setShouldPaintCustomScrollbars(bool shouldPaintCustomScrollbars)
m_shouldPaintCustomScrollbars = shouldPaintCustomScrollbars;
}
-void Settings::setZoomsTextOnly(bool zoomsTextOnly)
+void Settings::setZoomMode(ZoomMode mode)
{
- if (zoomsTextOnly == m_zoomsTextOnly)
+ if (mode == m_zoomMode)
return;
- m_zoomsTextOnly = zoomsTextOnly;
+ m_zoomMode = mode;
setNeedsReapplyStylesInAllFrames(m_page);
}
@@ -762,14 +787,18 @@ void Settings::setWebGLEnabled(bool enabled)
m_webGLEnabled = enabled;
}
-void Settings::setGeolocationEnabled(bool enabled)
+void Settings::setLoadDeferringEnabled(bool enabled)
{
- m_geolocationEnabled = enabled;
+ m_loadDeferringEnabled = enabled;
}
-void Settings::setLoadDeferringEnabled(bool enabled)
+void Settings::setTiledBackingStoreEnabled(bool enabled)
{
- m_loadDeferringEnabled = enabled;
+ m_tiledBackingStoreEnabled = enabled;
+#if ENABLE(TILED_BACKING_STORE)
+ if (m_page->mainFrame())
+ m_page->mainFrame()->setTiledBackingStoreEnabled(enabled);
+#endif
}
} // namespace WebCore
diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h
index 44b4642..6893eae 100644
--- a/WebCore/page/Settings.h
+++ b/WebCore/page/Settings.h
@@ -30,6 +30,7 @@
#include "AtomicString.h"
#include "FontRenderingMode.h"
#include "KURL.h"
+#include "ZoomMode.h"
namespace WebCore {
@@ -127,6 +128,9 @@ namespace WebCore {
bool blockNetworkImage() const { return m_blockNetworkImage; }
#endif
void setJavaScriptEnabled(bool);
+ // Instead of calling isJavaScriptEnabled directly, please consider calling
+ // ScriptController::canExecuteScripts, which takes things like the
+ // HTML sandbox attribute into account.
bool isJavaScriptEnabled() const { return m_isJavaScriptEnabled; }
void setWebSecurityEnabled(bool);
@@ -141,15 +145,22 @@ namespace WebCore {
void setJavaScriptCanOpenWindowsAutomatically(bool);
bool javaScriptCanOpenWindowsAutomatically() const { return m_javaScriptCanOpenWindowsAutomatically; }
+ void setSpatialNavigationEnabled(bool);
+ bool isSpatialNavigationEnabled() const { return m_isSpatialNavigationEnabled; }
+
void setJavaEnabled(bool);
bool isJavaEnabled() const { return m_isJavaEnabled; }
void setImagesEnabled(bool);
bool areImagesEnabled() const { return m_areImagesEnabled; }
+ void setMediaEnabled(bool);
+ bool isMediaEnabled() const { return m_isMediaEnabled; }
+
void setPluginsEnabled(bool);
bool arePluginsEnabled() const { return m_arePluginsEnabled; }
+<<<<<<< HEAD
#ifdef ANDROID_PLUGINS
void setPluginsOnDemand(bool onDemand) { m_pluginsOnDemand = onDemand; }
bool arePluginsOnDemand() const { return m_pluginsOnDemand; }
@@ -158,12 +169,22 @@ namespace WebCore {
void setDatabasesEnabled(bool);
bool databasesEnabled() const { return m_databasesEnabled; }
+=======
+>>>>>>> webkit.org at r58033
void setLocalStorageEnabled(bool);
bool localStorageEnabled() const { return m_localStorageEnabled; }
+#if ENABLE(DOM_STORAGE)
void setLocalStorageQuota(unsigned);
unsigned localStorageQuota() const { return m_localStorageQuota; }
+ // Allow clients concerned with memory consumption to set a quota on session storage
+ // since the memory used won't be released until the Page is destroyed.
+ // Default is noQuota.
+ void setSessionStorageQuota(unsigned);
+ unsigned sessionStorageQuota() const { return m_sessionStorageQuota; }
+#endif
+
void setPrivateBrowsingEnabled(bool);
bool privateBrowsingEnabled() const { return m_privateBrowsingEnabled; }
@@ -232,8 +253,8 @@ namespace WebCore {
void setDeveloperExtrasEnabled(bool);
bool developerExtrasEnabled() const { return m_developerExtrasEnabled; }
- void setFrameSetFlatteningEnabled(bool);
- bool frameSetFlatteningEnabled() const { return m_frameSetFlatteningEnabled; }
+ void setFrameFlatteningEnabled(bool);
+ bool frameFlatteningEnabled() const { return m_frameFlatteningEnabled; }
#ifdef ANDROID_META_SUPPORT
void resetMetadataSettings();
@@ -300,8 +321,8 @@ namespace WebCore {
void setShouldPaintCustomScrollbars(bool);
bool shouldPaintCustomScrollbars() const { return m_shouldPaintCustomScrollbars; }
- void setZoomsTextOnly(bool);
- bool zoomsTextOnly() const { return m_zoomsTextOnly; }
+ void setZoomMode(ZoomMode);
+ ZoomMode zoomMode() const { return m_zoomMode; }
void setEnforceCSSMIMETypeInStrictMode(bool);
bool enforceCSSMIMETypeInStrictMode() { return m_enforceCSSMIMETypeInStrictMode; }
@@ -350,11 +371,11 @@ namespace WebCore {
void setWebGLEnabled(bool);
bool webGLEnabled() const { return m_webGLEnabled; }
- void setGeolocationEnabled(bool);
- bool geolocationEnabled() const { return m_geolocationEnabled; }
-
void setLoadDeferringEnabled(bool);
bool loadDeferringEnabled() const { return m_loadDeferringEnabled; }
+
+ void setTiledBackingStoreEnabled(bool);
+ bool tiledBackingStoreEnabled() const { return m_tiledBackingStoreEnabled; }
private:
Page* m_page;
@@ -413,15 +434,20 @@ namespace WebCore {
bool m_blockNetworkImage : 1;
#endif
size_t m_maximumDecodedImageSize;
+#if ENABLE(DOM_STORAGE)
unsigned m_localStorageQuota;
+ unsigned m_sessionStorageQuota;
+#endif
unsigned m_pluginAllowedRunTime;
+ ZoomMode m_zoomMode;
+ bool m_isSpatialNavigationEnabled : 1;
bool m_isJavaEnabled : 1;
bool m_loadsImagesAutomatically : 1;
bool m_privateBrowsingEnabled : 1;
bool m_caretBrowsingEnabled : 1;
bool m_areImagesEnabled : 1;
+ bool m_isMediaEnabled : 1;
bool m_arePluginsEnabled : 1;
- bool m_databasesEnabled : 1;
bool m_localStorageEnabled : 1;
bool m_isJavaScriptEnabled : 1;
bool m_isWebSecurityEnabled : 1;
@@ -447,13 +473,12 @@ namespace WebCore {
bool m_authorAndUserStylesEnabled : 1;
bool m_needsSiteSpecificQuirks : 1;
unsigned m_fontRenderingMode : 1;
- bool m_frameSetFlatteningEnabled : 1;
+ bool m_frameFlatteningEnabled : 1;
bool m_webArchiveDebugModeEnabled : 1;
bool m_localFileContentSniffingEnabled : 1;
bool m_inApplicationChromeMode : 1;
bool m_offlineWebApplicationCacheEnabled : 1;
bool m_shouldPaintCustomScrollbars : 1;
- bool m_zoomsTextOnly : 1;
bool m_enforceCSSMIMETypeInStrictMode : 1;
bool m_usesEncodingDetector : 1;
bool m_allowScriptsToCloseWindows : 1;
@@ -465,11 +490,14 @@ namespace WebCore {
bool m_showRepaintCounter : 1;
bool m_experimentalNotificationsEnabled : 1;
bool m_webGLEnabled : 1;
- bool m_geolocationEnabled : 1;
bool m_loadDeferringEnabled : 1;
+<<<<<<< HEAD
#ifdef ANDROID_PLUGINS
bool m_pluginsOnDemand : 1;
#endif
+=======
+ bool m_tiledBackingStoreEnabled : 1;
+>>>>>>> webkit.org at r58033
#if USE(SAFARI_THEME)
static bool gShouldPaintNativeControls;
diff --git a/WebCore/page/SpatialNavigation.cpp b/WebCore/page/SpatialNavigation.cpp
new file mode 100644
index 0000000..890eacd
--- /dev/null
+++ b/WebCore/page/SpatialNavigation.cpp
@@ -0,0 +1,530 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SpatialNavigation.h"
+
+#include "Frame.h"
+#include "FrameTree.h"
+#include "FrameView.h"
+#include "HTMLFrameOwnerElement.h"
+#include "IntRect.h"
+#include "Node.h"
+#include "Page.h"
+
+namespace WebCore {
+
+static long long spatialDistance(FocusDirection, const IntRect&, const IntRect&);
+static IntRect renderRectRelativeToRootDocument(RenderObject*);
+static RectsAlignment alignmentForRects(FocusDirection, const IntRect&, const IntRect&);
+static bool areRectsFullyAligned(FocusDirection, const IntRect&, const IntRect&);
+static bool areRectsPartiallyAligned(FocusDirection, const IntRect&, const IntRect&);
+static bool isRectInDirection(FocusDirection, const IntRect&, const IntRect&);
+static void deflateIfOverlapped(IntRect&, IntRect&);
+static bool checkNegativeCoordsForNode(Node*, const IntRect&);
+
+void distanceDataForNode(FocusDirection direction, Node* start, FocusCandidate& candidate)
+{
+ RenderObject* startRender = start->renderer();
+ if (!startRender) {
+ candidate.distance = maxDistance();
+ return;
+ }
+
+ RenderObject* destRender = candidate.node->renderer();
+ if (!destRender) {
+ candidate.distance = maxDistance();
+ return;
+ }
+
+ IntRect curRect = renderRectRelativeToRootDocument(startRender);
+ IntRect targetRect = renderRectRelativeToRootDocument(destRender);
+
+ // The bounding rectangle of two consecutive nodes can overlap. In such cases,
+ // deflate both.
+ deflateIfOverlapped(curRect, targetRect);
+
+ // If empty rects or negative width or height, bail out.
+ if (curRect.isEmpty() || targetRect.isEmpty()
+ || targetRect.width() <= 0 || targetRect.height() <= 0) {
+ candidate.distance = maxDistance();
+ return;
+ }
+
+ // Negative coordinates can be used if node is scrolled up offscreen.
+ if (!checkNegativeCoordsForNode(start, curRect)) {
+ candidate.distance = maxDistance();
+ return;
+ }
+
+ if (!checkNegativeCoordsForNode(candidate.node, targetRect)) {
+ candidate.distance = maxDistance();
+ return;
+ }
+
+ if (!isRectInDirection(direction, curRect, targetRect)) {
+ candidate.distance = maxDistance();
+ return;
+ }
+
+ // The distance between two nodes is not to be considered alone when evaluating/looking
+ // for the best focus candidate node. Alignment of rects can be also a good point to be
+ // considered in order to make the algorithm to behavior in a more intuitive way.
+ candidate.alignment = alignmentForRects(direction, curRect, targetRect);
+ candidate.distance = spatialDistance(direction, curRect, targetRect);
+}
+
+// FIXME: This function does not behave correctly with transformed frames.
+static IntRect renderRectRelativeToRootDocument(RenderObject* render)
+{
+ ASSERT(render);
+
+ IntRect rect(render->absoluteClippedOverflowRect());
+
+ if (rect.isEmpty()) {
+ Element* e = static_cast<Element*>(render->node());
+ rect = e->getRect();
+ }
+
+ // In cases when the |render|'s associated node is in a scrollable inner
+ // document, we only consider its scrollOffset if it is not offscreen.
+ Node* node = render->node();
+ Document* mainDocument = node->document()->page()->mainFrame()->document();
+ bool considerScrollOffset = !(hasOffscreenRect(node) && node->document() != mainDocument);
+
+ if (considerScrollOffset) {
+ if (FrameView* frameView = render->node()->document()->view())
+ rect.move(-frameView->scrollOffset());
+ }
+
+ // Handle nested frames.
+ for (Frame* frame = render->document()->frame(); frame; frame = frame->tree()->parent()) {
+ if (HTMLFrameOwnerElement* ownerElement = frame->ownerElement())
+ rect.move(ownerElement->offsetLeft(), ownerElement->offsetTop());
+ }
+
+ return rect;
+}
+
+static RectsAlignment alignmentForRects(FocusDirection direction, const IntRect& curRect, const IntRect& targetRect)
+{
+ if (areRectsFullyAligned(direction, curRect, targetRect))
+ return Full;
+
+ if (areRectsPartiallyAligned(direction, curRect, targetRect))
+ return Partial;
+
+ return None;
+}
+
+static inline bool isHorizontalMove(FocusDirection direction)
+{
+ return direction == FocusDirectionLeft || direction == FocusDirectionRight;
+}
+
+static inline int start(FocusDirection direction, const IntRect& rect)
+{
+ return isHorizontalMove(direction) ? rect.y() : rect.x();
+}
+
+static inline int middle(FocusDirection direction, const IntRect& rect)
+{
+ IntPoint center(rect.center());
+ return isHorizontalMove(direction) ? center.y(): center.x();
+}
+
+static inline int end(FocusDirection direction, const IntRect& rect)
+{
+ return isHorizontalMove(direction) ? rect.bottom() : rect.right();
+}
+
+// This method checks if rects |a| and |b| are fully aligned either vertically or
+// horizontally. In general, rects whose central point falls between the top or
+// bottom of each other are considered fully aligned.
+// Rects that match this criteria are preferable target nodes in move focus changing
+// operations.
+// * a = Current focused node's rect.
+// * b = Focus candidate node's rect.
+static bool areRectsFullyAligned(FocusDirection direction, const IntRect& a, const IntRect& b)
+{
+ int aStart, bStart, aEnd, bEnd;
+
+ switch (direction) {
+ case FocusDirectionLeft:
+ aStart = a.x();
+ bEnd = b.right();
+ break;
+ case FocusDirectionRight:
+ aStart = b.x();
+ bEnd = a.right();
+ break;
+ case FocusDirectionUp:
+ aStart = a.y();
+ bEnd = b.y();
+ break;
+ case FocusDirectionDown:
+ aStart = b.y();
+ bEnd = a.y();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ if (aStart < bEnd)
+ return false;
+
+ aStart = start(direction, a);
+ bStart = start(direction, b);
+
+ int aMiddle = middle(direction, a);
+ int bMiddle = middle(direction, b);
+
+ aEnd = end(direction, a);
+ bEnd = end(direction, b);
+
+ // Picture of the totally aligned logic:
+ //
+ // Horizontal Vertical Horizontal Vertical
+ // **************************** *****************************
+ // * _ * _ _ _ _ * * _ * _ _ *
+ // * |_| _ * |_|_|_|_| * * _ |_| * |_|_| *
+ // * |_|....|_| * . * * |_|....|_| * . *
+ // * |_| |_| (1) . * * |_| |_| (2) . *
+ // * |_| * _._ * * |_| * _ _._ _ *
+ // * * |_|_| * * * |_|_|_|_| *
+ // * * * * * *
+ // **************************** *****************************
+
+ // Horizontal Vertical Horizontal Vertical
+ // **************************** *****************************
+ // * _......_ * _ _ _ _ * * _ * _ _ _ _ *
+ // * |_| |_| * |_|_|_|_| * * |_| _ * |_|_|_|_| *
+ // * |_| |_| * . * * |_| |_| * . *
+ // * |_| (3) . * * |_|....|_| (4) . *
+ // * * ._ _ * * * _ _. *
+ // * * |_|_| * * * |_|_| *
+ // * * * * * *
+ // **************************** *****************************
+
+ return ((bMiddle >= aStart && bMiddle <= aEnd) // (1)
+ || (aMiddle >= bStart && aMiddle <= bEnd) // (2)
+ || (bStart == aStart) // (3)
+ || (bEnd == aEnd)); // (4)
+}
+
+// This method checks if |start| and |dest| have a partial intersection, either
+// horizontally or vertically.
+// * a = Current focused node's rect.
+// * b = Focus candidate node's rect.
+static bool areRectsPartiallyAligned(FocusDirection direction, const IntRect& a, const IntRect& b)
+{
+ int aStart = start(direction, a);
+ int bStart = start(direction, b);
+ int bMiddle = middle(direction, b);
+ int aEnd = end(direction, a);
+ int bEnd = end(direction, b);
+
+ // Picture of the partially aligned logic:
+ //
+ // Horizontal Vertical
+ // ********************************
+ // * _ * _ _ _ *
+ // * |_| * |_|_|_| *
+ // * |_|.... _ * . . *
+ // * |_| |_| * . . *
+ // * |_|....|_| * ._._ _ *
+ // * |_| * |_|_|_| *
+ // * |_| * *
+ // * * *
+ // ********************************
+ //
+ // ... and variants of the above cases.
+ return ((bStart >= aStart && bStart <= aEnd)
+ || (bStart >= aStart && bStart <= aEnd)
+ || (bEnd >= aStart && bEnd <= aEnd)
+ || (bMiddle >= aStart && bMiddle <= aEnd)
+ || (bEnd >= aStart && bEnd <= aEnd));
+}
+
+// Return true if rect |a| is below |b|. False otherwise.
+static inline bool below(const IntRect& a, const IntRect& b)
+{
+ return a.y() > b.bottom();
+}
+
+// Return true if rect |a| is on the right of |b|. False otherwise.
+static inline bool rightOf(const IntRect& a, const IntRect& b)
+{
+ return a.x() > b.right();
+}
+
+// * a = Current focused node's rect.
+// * b = Focus candidate node's rect.
+static long long spatialDistance(FocusDirection direction, const IntRect& a, const IntRect& b)
+{
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+
+ if (direction == FocusDirectionLeft) {
+ // #1 |--|
+ //
+ // #2 |--| |--|
+ //
+ // #3 |--|
+
+ x1 = a.x();
+ x2 = b.right();
+
+ if (below(a, b)) {
+ // #1 The a rect is below b.
+ y1 = a.y();
+ y2 = b.bottom();
+ } else if (below(b, a)) {
+ // #3 The b rect is below a.
+ y1 = a.bottom();
+ y2 = b.y();
+ } else {
+ // #2 Both b and a share some common y's.
+ y1 = 0;
+ y2 = 0;
+ }
+ } else if (direction == FocusDirectionRight) {
+ // |--| #1
+ //
+ // |--| |--| #2
+ //
+ // |--| #3
+
+ x1 = a.right();
+ x2 = b.x();
+
+ if (below(a, b)) {
+ // #1 The b rect is above a.
+ y1 = a.y();
+ y2 = b.bottom();
+ } else if (below(b, a)) {
+ // #3 The b rect is below a.
+ y1 = a.bottom();
+ y2 = b.y();
+ } else {
+ // #2 Both b and a share some common y's.
+ y1 = 0;
+ y2 = 0;
+ }
+ } else if (direction == FocusDirectionUp) {
+ //
+ // #1 #2 #3
+ //
+ // |--| |--| |--|
+ //
+ // |--|
+
+ y1 = a.y();
+ y2 = b.bottom();
+
+ if (rightOf(a, b)) {
+ // #1 The b rect is to the left of a.
+ x1 = a.x();
+ x2 = b.right();
+ } else if (rightOf(b, a)) {
+ // #3 The b rect is to the right of a.
+ x1 = a.right();
+ x2 = b.x();
+ } else {
+ // #2 Both b and a share some common x's.
+ x1 = 0;
+ x2 = 0;
+ }
+ } else if (direction == FocusDirectionDown) {
+ // |--|
+ //
+ // |--| |--| |--|
+ //
+ // #1 #2 #3
+
+ y1 = a.bottom();
+ y2 = b.y();
+
+ if (rightOf(a, b)) {
+ // #1 The b rect is to the left of a.
+ x1 = a.x();
+ x2 = b.right();
+ } else if (rightOf(b, a)) {
+ // #3 The b rect is to the right of a
+ x1 = a.right();
+ x2 = b.x();
+ } else {
+ // #2 Both b and a share some common x's.
+ x1 = 0;
+ x2 = 0;
+ }
+ }
+
+ long long dx = x1 - x2;
+ long long dy = y1 - y2;
+
+ long long distance = (dx * dx) + (dy * dy);
+
+ if (distance < 0)
+ distance *= -1;
+
+ return distance;
+}
+
+static bool isRectInDirection(FocusDirection direction, const IntRect& curRect, const IntRect& targetRect)
+{
+ IntPoint center(targetRect.center());
+ int targetMiddle = isHorizontalMove(direction) ? center.x() : center.y();
+
+ switch (direction) {
+ case FocusDirectionLeft:
+ return targetMiddle < curRect.x();
+ case FocusDirectionRight:
+ return targetMiddle > curRect.right();
+ case FocusDirectionUp:
+ return targetMiddle < curRect.y();
+ case FocusDirectionDown:
+ return targetMiddle > curRect.bottom();
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return false;
+}
+
+// Checks if |node| is offscreen the visible area (viewport) of its container
+// document. In case it is, one can scroll in direction or take any different
+// desired action later on.
+bool hasOffscreenRect(Node* node)
+{
+ // Get the FrameView in which |node| is (which means the current viewport if |node|
+ // is not in an inner document), so we can check if its content rect is visible
+ // before we actually move the focus to it.
+ FrameView* frameView = node->document()->view();
+ if (!frameView)
+ return true;
+
+ IntRect containerViewportRect = frameView->visibleContentRect();
+
+ RenderObject* render = node->renderer();
+ if (!render)
+ return true;
+
+ IntRect rect(render->absoluteClippedOverflowRect());
+ if (rect.isEmpty())
+ return true;
+
+ return !containerViewportRect.intersects(rect);
+}
+
+// In a bottom-up way, this method tries to scroll |frame| in a given direction
+// |direction|, going up in the frame tree hierarchy in case it does not succeed.
+bool scrollInDirection(Frame* frame, FocusDirection direction)
+{
+ if (!frame)
+ return false;
+
+ ScrollDirection scrollDirection;
+
+ switch (direction) {
+ case FocusDirectionLeft:
+ scrollDirection = ScrollLeft;
+ break;
+ case FocusDirectionRight:
+ scrollDirection = ScrollRight;
+ break;
+ case FocusDirectionUp:
+ scrollDirection = ScrollUp;
+ break;
+ case FocusDirectionDown:
+ scrollDirection = ScrollDown;
+ break;
+ default:
+ return false;
+ }
+
+ return frame->eventHandler()->scrollRecursively(scrollDirection, ScrollByLine);
+}
+
+void scrollIntoView(Element* element)
+{
+ // NOTE: Element's scrollIntoView method could had been used here, but
+ // it is preferable to inflate |element|'s bounding rect a bit before
+ // scrolling it for accurate reason.
+ // Element's scrollIntoView method does not provide this flexibility.
+ static const int fudgeFactor = 2;
+ IntRect bounds = element->getRect();
+ bounds.inflate(fudgeFactor);
+ element->renderer()->enclosingLayer()->scrollRectToVisible(bounds);
+}
+
+bool isInRootDocument(Node* node)
+{
+ if (!node)
+ return false;
+
+ Document* rootDocument = node->document()->page()->mainFrame()->document();
+ return node->document() == rootDocument;
+}
+
+static void deflateIfOverlapped(IntRect& a, IntRect& b)
+{
+ if (!a.intersects(b) || a.contains(b) || b.contains(a))
+ return;
+
+ static const int fudgeFactor = -2;
+
+ // Avoid negative width or height values.
+ if ((a.width() + 2 * fudgeFactor > 0) && (a.height() + 2 * fudgeFactor > 0))
+ a.inflate(fudgeFactor);
+
+ if ((b.width() + 2 * fudgeFactor > 0) && (b.height() + 2 * fudgeFactor > 0))
+ b.inflate(fudgeFactor);
+}
+
+static bool checkNegativeCoordsForNode(Node* node, const IntRect& curRect)
+{
+ ASSERT(node || node->renderer());
+
+ if (curRect.x() > 0 && curRect.y() > 0)
+ return true;
+
+ bool canBeScrolled = false;
+
+ RenderObject* renderer = node->renderer();
+ for (; renderer; renderer = renderer->parent()) {
+ if (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) {
+ canBeScrolled = true;
+ break;
+ }
+ }
+
+ return canBeScrolled;
+}
+
+} // namespace WebCore
diff --git a/WebCore/page/SpatialNavigation.h b/WebCore/page/SpatialNavigation.h
new file mode 100644
index 0000000..90ff1cf
--- /dev/null
+++ b/WebCore/page/SpatialNavigation.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2009 Antonio Gomes <tonikitoo@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SpatialNavigation_h
+#define SpatialNavigation_h
+
+#include "FocusDirection.h"
+#include "Node.h"
+
+#include <limits>
+
+namespace WebCore {
+
+class Element;
+class Frame;
+class IntRect;
+class RenderObject;
+
+using namespace std;
+
+inline long long maxDistance()
+{
+ return numeric_limits<long long>::max();
+}
+
+// Spatially speaking, two given elements in a web page can be:
+// 1) Fully aligned: There is a full intersection between the rects, either
+// vertically or horizontally.
+//
+// * Horizontally * Vertically
+// _
+// |_| _ _ _ _ _ _
+// |_|...... _ |_|_|_|_|_|_|
+// |_| |_| . .
+// |_|......|_| OR . .
+// |_| |_| . .
+// |_|......|_| _ _ _ _
+// |_| |_|_|_|_|
+//
+//
+// 2) Partially aligned: There is a partial intersection between the rects, either
+// vertically or horizontally.
+//
+// * Horizontally * Vertically
+// _ _ _ _ _ _
+// |_| |_|_|_|_|_|
+// |_|.... _ OR . .
+// |_| |_| . .
+// |_|....|_| ._._ _
+// |_| |_|_|_|
+// |_|
+//
+// 3) Or, otherwise, not aligned at all.
+//
+// * Horizontally * Vertically
+// _ _ _ _ _
+// |_| |_|_|_|_|
+// |_| .
+// |_| .
+// . OR .
+// _ . ._ _ _ _ _
+// |_| |_|_|_|_|_|
+// |_|
+// |_|
+//
+// "Totally Aligned" elements are preferable candidates to move
+// focus to over "Partially Aligned" ones, that on its turns are
+// more preferable than "Not Aligned".
+enum RectsAlignment {
+ None = 0,
+ Partial,
+ Full
+};
+
+struct FocusCandidate {
+ FocusCandidate()
+ : node(0)
+ , distance(maxDistance())
+ , parentDistance(maxDistance())
+ , alignment(None)
+ , parentAlignment(None)
+ {
+ }
+
+ FocusCandidate(Node* n)
+ : node(n)
+ , distance(maxDistance())
+ , parentDistance(maxDistance())
+ , alignment(None)
+ , parentAlignment(None)
+ {
+ }
+
+ bool isNull() const { return !node; }
+ Document* document() const { return node ? node->document() : 0; }
+
+ Node* node;
+ long long distance;
+ long long parentDistance;
+ RectsAlignment alignment;
+ RectsAlignment parentAlignment;
+};
+
+void distanceDataForNode(FocusDirection direction, Node* start, FocusCandidate& candidate);
+bool scrollInDirection(Frame*, FocusDirection);
+void scrollIntoView(Element*);
+bool hasOffscreenRect(Node*);
+bool isInRootDocument(Node*);
+
+} // namspace WebCore
+
+#endif // SpatialNavigation_h
diff --git a/WebCore/page/UserContentURLPattern.cpp b/WebCore/page/UserContentURLPattern.cpp
index 5f0a311..09eb678 100644
--- a/WebCore/page/UserContentURLPattern.cpp
+++ b/WebCore/page/UserContentURLPattern.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -75,28 +75,26 @@ bool UserContentURLPattern::parse(const String& pattern)
int pathStartPos = 0;
- if (m_scheme == "file")
+ if (equalIgnoringCase(m_scheme, "file"))
pathStartPos = hostStartPos;
else {
int hostEndPos = pattern.find("/", hostStartPos);
if (hostEndPos == -1)
return false;
-
+
m_host = pattern.substring(hostStartPos, hostEndPos - hostStartPos);
+ m_matchSubdomains = false;
- // The first component can be '*', which means to match all subdomains.
- Vector<String> hostComponents;
- m_host.split(".", hostComponents);
- if (hostComponents[0] == "*") {
- m_matchSubdomains = true;
+ if (m_host == "*") {
+ // The pattern can be just '*', which means match all domains.
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 + ".";
- }
+ m_matchSubdomains = true;
+ } else if (m_host.startsWith("*.")) {
+ // The first component can be '*', which means to match all subdomains.
+ m_host = m_host.substring(2); // Length of "*."
+ m_matchSubdomains = true;
}
-
+
// No other '*' can occur in the host.
if (m_host.find("*") != -1)
return false;
@@ -114,10 +112,10 @@ bool UserContentURLPattern::matches(const KURL& test) const
if (m_invalid)
return false;
- if (test.protocol() != m_scheme)
+ if (!equalIgnoringCase(test.protocol(), m_scheme))
return false;
- if (!matchesHost(test))
+ if (!equalIgnoringCase(m_scheme, "file") && !matchesHost(test))
return false;
return matchesPath(test);
@@ -125,7 +123,8 @@ bool UserContentURLPattern::matches(const KURL& test) const
bool UserContentURLPattern::matchesHost(const KURL& test) const
{
- if (test.host() == m_host)
+ const String& host = test.host();
+ if (equalIgnoringCase(host, m_host))
return true;
if (!m_matchSubdomains)
@@ -136,8 +135,14 @@ bool UserContentURLPattern::matchesHost(const KURL& test) const
if (!m_host.length())
return true;
- // Check if the test host is a subdomain of our host.
- return test.host().endsWith(m_host, false);
+ // Check if the domain is a subdomain of our host.
+ if (!host.endsWith(m_host, false))
+ return false;
+
+ ASSERT(host.length() > m_host.length());
+
+ // Check that the character before the suffix is a period.
+ return host[host.length() - m_host.length() - 1] == '.';
}
struct MatchTester
diff --git a/WebCore/page/UserContentURLPattern.h b/WebCore/page/UserContentURLPattern.h
index 0b1a248..3450ed1 100644
--- a/WebCore/page/UserContentURLPattern.h
+++ b/WebCore/page/UserContentURLPattern.h
@@ -35,12 +35,16 @@ class KURL;
class UserContentURLPattern {
public:
+ UserContentURLPattern() : m_invalid(true), m_matchSubdomains(false) { }
+
UserContentURLPattern(const String& pattern)
: m_matchSubdomains(false)
{
m_invalid = !parse(pattern);
}
+ bool isValid() const { return !m_invalid; }
+
bool matches(const KURL&) const;
const String& scheme() const { return m_scheme; }
diff --git a/WebCore/page/XSSAuditor.cpp b/WebCore/page/XSSAuditor.cpp
index b71fa49..9e225ff 100644
--- a/WebCore/page/XSSAuditor.cpp
+++ b/WebCore/page/XSSAuditor.cpp
@@ -31,7 +31,6 @@
#include <wtf/Vector.h>
#include "Console.h"
-#include "CString.h"
#include "DocumentLoader.h"
#include "DOMWindow.h"
#include "Frame.h"
@@ -41,6 +40,7 @@
#include "ScriptSourceCode.h"
#include "Settings.h"
#include "TextResourceDecoder.h"
+#include <wtf/text/CString.h>
using namespace WTF;
@@ -70,6 +70,16 @@ static bool isIllegalURICharacter(UChar c)
return (c == '\'' || c == '"' || c == '<' || c == '>');
}
+String XSSAuditor::CachingURLCanonicalizer::canonicalizeURL(FormData* formData, const TextEncoding& encoding, bool decodeEntities,
+ bool decodeURLEscapeSequencesTwice)
+{
+ if (decodeEntities == m_decodeEntities && decodeURLEscapeSequencesTwice == m_decodeURLEscapeSequencesTwice
+ && encoding == m_encoding && formData == m_formData)
+ return m_cachedCanonicalizedURL;
+ m_formData = formData;
+ return canonicalizeURL(formData->flattenToString(), encoding, decodeEntities, decodeURLEscapeSequencesTwice);
+}
+
String XSSAuditor::CachingURLCanonicalizer::canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities,
bool decodeURLEscapeSequencesTwice)
{
@@ -82,11 +92,19 @@ String XSSAuditor::CachingURLCanonicalizer::canonicalizeURL(const String& url, c
m_encoding = encoding;
m_decodeEntities = decodeEntities;
m_decodeURLEscapeSequencesTwice = decodeURLEscapeSequencesTwice;
+ ++m_generation;
return m_cachedCanonicalizedURL;
}
+void XSSAuditor::CachingURLCanonicalizer::clear()
+{
+ m_formData.clear();
+ m_inputURL = String();
+}
+
XSSAuditor::XSSAuditor(Frame* frame)
: m_frame(frame)
+ , m_generationOfSuffixTree(-1)
{
}
@@ -290,21 +308,15 @@ bool XSSAuditor::isSameOriginResource(const String& url) const
return (m_frame->document()->url().host() == resourceURL.host() && resourceURL.query().isEmpty());
}
-bool XSSAuditor::shouldFullPageBlockForXSSProtectionHeader() const
+XSSProtectionDisposition XSSAuditor::xssProtection() const
{
- // If we detect an XSS attack and find the HTTP header "X-XSS-Protection: 12" then
- // we will stop loading the page as opposed to ignoring the script. The value "12"
- // came from a personal communication, see <https://bugs.webkit.org/show_bug.cgi?id=27312>
- // for more details.
DEFINE_STATIC_LOCAL(String, XSSProtectionHeader, ("X-XSS-Protection"));
Frame* frame = m_frame;
if (frame->document()->url() == blankURL())
frame = m_frame->tree()->parent();
- // We strip any whitespace characters to conform to the behavior in Internet Explorer.
- String xssProtectionValue = frame->loader()->documentLoader()->response().httpHeaderField(XSSProtectionHeader).stripWhiteSpace();
- return (xssProtectionValue.length() >= 2 && xssProtectionValue[0] == '1' && xssProtectionValue[1] == '2');
+ return parseXSSProtectionHeader(frame->loader()->documentLoader()->response().httpHeaderField(XSSProtectionHeader));
}
bool XSSAuditor::findInRequest(const FindTask& task) const
@@ -318,11 +330,24 @@ bool XSSAuditor::findInRequest(const FindTask& task) const
result = findInRequest(m_frame, task);
blockFrame = m_frame;
}
- if (result && blockFrame && shouldFullPageBlockForXSSProtectionHeader()) {
- blockFrame->loader()->stopAllLoaders();
- blockFrame->redirectScheduler()->scheduleLocationChange(blankURL(), String());
+ if (!result)
+ return false;
+
+ switch (xssProtection()) {
+ case XSSProtectionDisabled:
+ return false;
+ case XSSProtectionEnabled:
+ break;
+ case XSSProtectionBlockEnabled:
+ if (blockFrame) {
+ blockFrame->loader()->stopAllLoaders();
+ blockFrame->redirectScheduler()->scheduleLocationChange(blankURL(), String());
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
}
- return result;
+ return true;
}
bool XSSAuditor::findInRequest(Frame* frame, const FindTask& task) const
@@ -341,6 +366,12 @@ bool XSSAuditor::findInRequest(Frame* frame, const FindTask& task) const
const bool hasFormData = formDataObj && !formDataObj->isEmpty();
String pageURL = frame->document()->url().string();
+ if (!hasFormData) {
+ // We clear out our form data caches, in case we're holding onto a bunch of memory.
+ m_formDataCache.clear();
+ m_formDataSuffixTree.clear();
+ }
+
String canonicalizedString;
if (!hasFormData && task.string.length() > 2 * pageURL.length()) {
// Q: Why do we bother to do this check at all?
@@ -368,7 +399,7 @@ bool XSSAuditor::findInRequest(Frame* frame, const FindTask& task) const
if (!task.context.isEmpty())
canonicalizedString = task.context + canonicalizedString;
- String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice);
+ String decodedPageURL = m_pageURLCache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice);
if (task.allowRequestIfNoIllegalURICharacters && !hasFormData && decodedPageURL.find(&isIllegalURICharacter, 0) == -1)
return false; // Injection is impossible because the request does not contain any illegal URI characters.
@@ -377,7 +408,17 @@ bool XSSAuditor::findInRequest(Frame* frame, const FindTask& task) const
return true; // We've found the string in the GET data.
if (hasFormData) {
- String decodedFormData = m_cache.canonicalizeURL(formDataObj->flattenToString(), frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice);
+ String decodedFormData = m_formDataCache.canonicalizeURL(formDataObj, frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice);
+
+ if (m_generationOfSuffixTree != m_formDataCache.generation()) {
+ m_formDataSuffixTree = new SuffixTree<ASCIICodebook>(decodedFormData, 5);
+ m_generationOfSuffixTree = m_formDataCache.generation();
+ }
+
+ // Try a fast-reject via the suffixTree.
+ if (m_formDataSuffixTree && !m_formDataSuffixTree->mightContain(canonicalizedString))
+ return false;
+
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 3ad50a1..d2f525d 100644
--- a/WebCore/page/XSSAuditor.h
+++ b/WebCore/page/XSSAuditor.h
@@ -27,11 +27,14 @@
#ifndef XSSAuditor_h
#define XSSAuditor_h
+#include "HTTPParsers.h"
#include "PlatformString.h"
+#include "SuffixTree.h"
#include "TextEncoding.h"
namespace WebCore {
+ class FormData;
class Frame;
class ScriptSourceCode;
@@ -105,16 +108,26 @@ namespace WebCore {
class CachingURLCanonicalizer
{
public:
- CachingURLCanonicalizer() : m_decodeEntities(false), m_decodeURLEscapeSequencesTwice(false) { }
+ CachingURLCanonicalizer() : m_decodeEntities(false), m_decodeURLEscapeSequencesTwice(false), m_generation(0) { }
+ String canonicalizeURL(FormData*, const TextEncoding& encoding, bool decodeEntities,
+ bool decodeURLEscapeSequencesTwice);
String canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities,
bool decodeURLEscapeSequencesTwice);
+ void clear();
+
+ int generation() const { return m_generation; }
+
private:
// The parameters we were called with last.
String m_inputURL;
TextEncoding m_encoding;
bool m_decodeEntities;
bool m_decodeURLEscapeSequencesTwice;
+ RefPtr<FormData> m_formData;
+
+ // Incremented every time we see a new URL.
+ int m_generation;
// The cached result.
String m_cachedCanonicalizedURL;
@@ -144,13 +157,22 @@ namespace WebCore {
bool findInRequest(const FindTask&) const;
bool findInRequest(Frame*, const FindTask&) const;
- bool shouldFullPageBlockForXSSProtectionHeader() const;
+ XSSProtectionDisposition xssProtection() const;
// The frame to audit.
Frame* m_frame;
// A state store to help us avoid canonicalizing the same URL repeated.
- mutable CachingURLCanonicalizer m_cache;
+ // When a page has form data, we need two caches: one to store the
+ // canonicalized URL and another to store the cannonicalized form
+ // data. If we only had one cache, we'd always generate a cache miss
+ // and load some pages extremely slowly.
+ // https://bugs.webkit.org/show_bug.cgi?id=35373
+ mutable CachingURLCanonicalizer m_pageURLCache;
+ mutable CachingURLCanonicalizer m_formDataCache;
+
+ mutable OwnPtr<SuffixTree<ASCIICodebook> > m_formDataSuffixTree;
+ mutable int m_generationOfSuffixTree;
};
} // namespace WebCore
diff --git a/WebCore/page/ZoomMode.h b/WebCore/page/ZoomMode.h
new file mode 100644
index 0000000..3f02184
--- /dev/null
+++ b/WebCore/page/ZoomMode.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 Research in Motion Ltd. http://www.rim.com/
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ZoomMode_h
+#define ZoomMode_h
+
+namespace WebCore {
+
+enum ZoomMode {
+ ZoomPage,
+ ZoomTextOnly
+};
+
+}
+
+#endif
diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp
index 2a2ab4b..d9282cb 100644
--- a/WebCore/page/animation/AnimationBase.cpp
+++ b/WebCore/page/animation/AnimationBase.cpp
@@ -33,7 +33,6 @@
#include "CSSMutableStyleDeclaration.h"
#include "CSSPropertyLonghand.h"
#include "CSSPropertyNames.h"
-#include "CString.h"
#include "CompositeAnimation.h"
#include "Document.h"
#include "EventNames.h"
@@ -136,9 +135,9 @@ static inline ShadowStyle blendFunc(const AnimationBase* anim, ShadowStyle from,
static inline ShadowData* blendFunc(const AnimationBase* anim, const ShadowData* from, const ShadowData* to, double progress)
{
ASSERT(from && to);
- return new ShadowData(blendFunc(anim, from->x, to->x, progress), blendFunc(anim, from->y, to->y, progress),
- blendFunc(anim, from->blur, to->blur, progress), blendFunc(anim, from->spread, to->spread, progress),
- blendFunc(anim, from->style, to->style, progress), blendFunc(anim, from->color, to->color, progress));
+ return new ShadowData(blendFunc(anim, from->x(), to->x(), progress), blendFunc(anim, from->y(), to->y(), progress),
+ blendFunc(anim, from->blur(), to->blur(), progress), blendFunc(anim, from->spread(), to->spread(), progress),
+ blendFunc(anim, from->style(), to->style(), progress), blendFunc(anim, from->color(), to->color(), progress));
}
static inline TransformOperations blendFunc(const AnimationBase* anim, const TransformOperations& from, const TransformOperations& to, double progress)
@@ -297,18 +296,19 @@ public:
};
#endif // USE(ACCELERATED_COMPOSITING)
-class PropertyWrapperShadow : public PropertyWrapperGetter<ShadowData*> {
+class PropertyWrapperShadow : public PropertyWrapperBase {
public:
- PropertyWrapperShadow(int prop, ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(ShadowData*, bool))
- : PropertyWrapperGetter<ShadowData*>(prop, getter)
+ PropertyWrapperShadow(int prop, const ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(ShadowData*, bool))
+ : PropertyWrapperBase(prop)
+ , m_getter(getter)
, m_setter(setter)
{
}
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
- ShadowData* shadowA = (a->*m_getter)();
- ShadowData* shadowB = (b->*m_getter)();
+ const ShadowData* shadowA = (a->*m_getter)();
+ const ShadowData* shadowB = (b->*m_getter)();
while (true) {
if (!shadowA && !shadowB) // end of both lists
@@ -320,8 +320,8 @@ public:
if (*shadowA != *shadowB)
return false;
- shadowA = shadowA->next;
- shadowB = shadowB->next;
+ shadowA = shadowA->next();
+ shadowB = shadowB->next();
}
return true;
@@ -329,29 +329,30 @@ public:
virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
{
- ShadowData* shadowA = (a->*m_getter)();
- ShadowData* shadowB = (b->*m_getter)();
+ const ShadowData* shadowA = (a->*m_getter)();
+ const ShadowData* shadowB = (b->*m_getter)();
ShadowData defaultShadowData(0, 0, 0, 0, Normal, Color::transparent);
ShadowData* newShadowData = 0;
while (shadowA || shadowB) {
- ShadowData* srcShadow = shadowA ? shadowA : &defaultShadowData;
- ShadowData* dstShadow = shadowB ? shadowB : &defaultShadowData;
+ const ShadowData* srcShadow = shadowA ? shadowA : &defaultShadowData;
+ const ShadowData* dstShadow = shadowB ? shadowB : &defaultShadowData;
if (!newShadowData)
newShadowData = blendFunc(anim, srcShadow, dstShadow, progress);
else
- newShadowData->next = blendFunc(anim, srcShadow, dstShadow, progress);
+ newShadowData->setNext(blendFunc(anim, srcShadow, dstShadow, progress));
- shadowA = shadowA ? shadowA->next : 0;
- shadowB = shadowB ? shadowB->next : 0;
+ shadowA = shadowA ? shadowA->next() : 0;
+ shadowB = shadowB ? shadowB->next() : 0;
}
(dst->*m_setter)(newShadowData, false);
}
private:
+ const ShadowData* (RenderStyle::*m_getter)() const;
void (RenderStyle::*m_setter)(ShadowData*, bool);
};
@@ -918,8 +919,8 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// Execute state machine
switch (m_animState) {
case AnimationStateNew:
- ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputPlayStatePaused);
- if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning) {
+ ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunning || input == AnimationStateInputPlayStatePaused);
+ if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunning) {
m_requestedStartTime = beginAnimationUpdateTime();
m_animState = AnimationStateStartWaitTimer;
}
@@ -1021,6 +1022,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
ASSERT(input == AnimationStateInputEndTimerFired || input == AnimationStateInputPlayStatePaused);
if (input == AnimationStateInputEndTimerFired) {
+
ASSERT(param >= 0);
// End timer fired, finish up
onAnimationEnd(param);
@@ -1028,7 +1030,10 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
m_animState = AnimationStateDone;
if (m_object) {
- resumeOverriddenAnimations();
+ if (m_animation->fillsForwards())
+ m_animState = AnimationStateFillingForwards;
+ else
+ resumeOverriddenAnimations();
// Fire off another style change so we can set the final value
m_compAnim->animationController()->addNodeChangeToDispatch(m_object->node());
@@ -1042,7 +1047,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// |this| may be deleted here
break;
case AnimationStatePausedWaitTimer:
- ASSERT(input == AnimationStateInputPlayStateRunnning);
+ ASSERT(input == AnimationStateInputPlayStateRunning);
ASSERT(paused());
// Update the times
m_startTime += beginAnimationUpdateTime() - m_pauseTime;
@@ -1058,7 +1063,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
// AnimationStatePausedWaitResponse, we don't yet have a valid startTime, so we send 0 to startAnimation.
// When the AnimationStateInputStartTimeSet comes in and we were in AnimationStatePausedRun, we will notice
// that we have already set the startTime and will ignore it.
- ASSERT(input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputStartTimeSet);
+ ASSERT(input == AnimationStateInputPlayStateRunning || input == AnimationStateInputStartTimeSet);
ASSERT(paused());
// If we are paused, but we get the callback that notifies us that an accelerated animation started,
@@ -1093,6 +1098,7 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param)
m_fallbackAnimating = !started;
}
break;
+ case AnimationStateFillingForwards:
case AnimationStateDone:
// We're done. Stay in this state until we are deleted
break;
@@ -1152,14 +1158,14 @@ void AnimationBase::fireAnimationEventsIfNeeded()
void AnimationBase::updatePlayState(bool run)
{
if (paused() == run || isNew())
- updateStateMachine(run ? AnimationStateInputPlayStateRunnning : AnimationStateInputPlayStatePaused, -1);
+ updateStateMachine(run ? AnimationStateInputPlayStateRunning : AnimationStateInputPlayStatePaused, -1);
}
double AnimationBase::timeToNextService()
{
// Returns the time at which next service is required. -1 means no service is required. 0 means
// service is required now, and > 0 means service is required that many seconds in the future.
- if (paused() || isNew())
+ if (paused() || isNew() || m_animState == AnimationStateFillingForwards)
return -1;
if (m_animState == AnimationStateStartWaitTimer) {
@@ -1184,8 +1190,10 @@ double AnimationBase::progress(double scale, double offset, const TimingFunction
if (m_animation->iterationCount() > 0)
dur *= m_animation->iterationCount();
- if (postActive() || !m_animation->duration() || (m_animation->iterationCount() > 0 && elapsedTime >= dur))
+ if (postActive() || !m_animation->duration())
return 1.0;
+ if (m_animation->iterationCount() > 0 && elapsedTime >= dur)
+ return (m_animation->iterationCount() % 2) ? 1.0 : 0.0;
// Compute the fractional time, taking into account direction.
// There is no need to worry about iterations, we assume that we would have
diff --git a/WebCore/page/animation/AnimationBase.h b/WebCore/page/animation/AnimationBase.h
index c367e0a..a957119 100644
--- a/WebCore/page/animation/AnimationBase.h
+++ b/WebCore/page/animation/AnimationBase.h
@@ -71,7 +71,8 @@ public:
AnimationStatePausedWaitTimer, // in pause mode when animation started
AnimationStatePausedWaitResponse, // animation paused when in STARTING state
AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state
- AnimationStateDone // end timer fired, animation finished and removed
+ AnimationStateDone, // end timer fired, animation finished and removed
+ AnimationStateFillingForwards // animation has ended and is retaining its final value
};
enum AnimStateInput {
@@ -85,7 +86,7 @@ public:
AnimationStateInputEndTimerFired, // end timer fired
AnimationStateInputPauseOverride, // pause an animation due to override
AnimationStateInputResumeOverride, // resume an overridden animation
- AnimationStateInputPlayStateRunnning, // play state paused -> running
+ AnimationStateInputPlayStateRunning, // play state paused -> running
AnimationStateInputPlayStatePaused, // play state running -> paused
AnimationStateInputEndAnimation // force an end from any state
};
diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp
index 422c154..cb609a5 100644
--- a/WebCore/page/animation/AnimationController.cpp
+++ b/WebCore/page/animation/AnimationController.cpp
@@ -134,6 +134,9 @@ void AnimationControllerPrivate::updateAnimationTimer(bool callSetChanged/* = fa
void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<AnimationControllerPrivate>*)
{
+ // Protect the frame from getting destroyed in the event handler
+ RefPtr<Frame> protector = m_frame;
+
// fire all the events
Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = m_eventsToDispatch.end();
for (Vector<EventToDispatch>::const_iterator it = m_eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) {
diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp
index 34f03c7..0f238fd 100644
--- a/WebCore/page/animation/CompositeAnimation.cpp
+++ b/WebCore/page/animation/CompositeAnimation.cpp
@@ -233,7 +233,7 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, Render
keyframeAnim->setAnimation(anim);
keyframeAnim->setIndex(i);
} else if ((anim->duration() || anim->delay()) && anim->iterationCount()) {
- keyframeAnim = KeyframeAnimation::create(const_cast<Animation*>(anim), renderer, i, this, currentStyle ? currentStyle : targetStyle);
+ keyframeAnim = KeyframeAnimation::create(const_cast<Animation*>(anim), renderer, i, this, targetStyle);
m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim);
}
diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp
index c5e3660..4c2cbc8 100644
--- a/WebCore/page/animation/KeyframeAnimation.cpp
+++ b/WebCore/page/animation/KeyframeAnimation.cpp
@@ -68,6 +68,11 @@ void KeyframeAnimation::getKeyframeAnimationInterval(const RenderStyle*& fromSty
double elapsedTime = getElapsedTime();
double t = m_animation->duration() ? (elapsedTime / m_animation->duration()) : 1;
+
+ ASSERT(t >= 0);
+ if (t < 0)
+ t = 0;
+
int i = static_cast<int>(t);
t -= i;
if (m_animation->direction() && (i & 1))
@@ -120,9 +125,11 @@ void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const Render
}
// If we are waiting for the start timer, we don't want to change the style yet.
- // Special case - if the delay time is 0, then we do want to set the first frame of the
+ // Special case 1 - if the delay time is 0, then we do want to set the first frame of the
// animation right away. This avoids a flash when the animation starts.
- if (waitingToStart() && m_animation->delay() > 0)
+ // Special case 2 - if there is a backwards fill mode, then we want to continue
+ // through to the style blend so that we get the fromStyle.
+ if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
return;
// FIXME: we need to be more efficient about determining which keyframes we are animating between.
@@ -163,6 +170,11 @@ void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const Render
void KeyframeAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
{
+ // If we're in the delay phase and we're not backwards filling, tell the caller
+ // to use the current style.
+ if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
+ return;
+
// Get the from/to styles and progress between
const RenderStyle* fromStyle = 0;
const RenderStyle* toStyle = 0;
@@ -260,7 +272,10 @@ void KeyframeAnimation::onAnimationIteration(double elapsedTime)
void KeyframeAnimation::onAnimationEnd(double elapsedTime)
{
sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime);
- endAnimation();
+ // End the animation if we don't fill forwards. Forward filling
+ // animations are ended properly in the class destructor.
+ if (!m_animation->fillsForwards())
+ endAnimation();
}
bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime)
diff --git a/WebCore/page/brew/EventHandlerBrew.cpp b/WebCore/page/brew/EventHandlerBrew.cpp
new file mode 100644
index 0000000..e3b6645
--- /dev/null
+++ b/WebCore/page/brew/EventHandlerBrew.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2010 Company 100, Inc.
+ * Copyright 2009, The Android Open Source Project
+ * Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "EventHandler.h"
+
+#include "ClipboardBrew.h"
+#include "EventNames.h"
+#include "FocusController.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "HitTestResult.h"
+#include "KeyboardEvent.h"
+#include "MouseEventWithHitTestResults.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "PlatformKeyboardEvent.h"
+#include "PlatformWheelEvent.h"
+#include "RenderWidget.h"
+
+namespace WebCore {
+
+bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
+{
+ return true;
+}
+
+void EventHandler::focusDocumentView()
+{
+ Page* page = m_frame->page();
+ if (page)
+ page->focusController()->setFocusedFrame(m_frame);
+}
+
+bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
+{
+ // Figure out which view to send the event to.
+ RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0;
+ if (!target || !target->isWidget())
+ return false;
+ return passMouseDownEventToWidget(toRenderWidget(target)->widget());
+}
+
+bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
+{
+ return passMouseDownEventToWidget(renderWidget->widget());
+}
+
+// This function is used to route the mouse down event to the native widgets, it seems like a
+// work around for the Mac platform which does not support double clicks, but browsers do.
+bool EventHandler::passMouseDownEventToWidget(Widget* widget)
+{
+ notImplemented();
+ return false;
+}
+
+bool EventHandler::eventActivatedView(const PlatformMouseEvent&) const
+{
+ notImplemented();
+ return false;
+}
+
+// This function is called for mouse events by FrameView::handleMousePressEvent().
+// It is used to ensure that events are sync'ed correctly between frames. For example
+// if the user presses down in one frame and up in another frame, this function will
+// returns true, and pass the event to the correct frame.
+bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& event, Frame* subframe, HitTestResult*)
+{
+ notImplemented();
+ return false;
+}
+
+// This is called to route wheel events to child widgets when they are RenderWidget
+// as the parent usually gets wheel event. Don't have a mouse with a wheel to confirm
+// the operation of this function.
+bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* widget)
+{
+ notImplemented();
+ return false;
+}
+
+bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+{
+ return passSubframeEventToSubframe(mev, subframe);
+}
+
+bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode)
+{
+ return passSubframeEventToSubframe(mev, subframe, hoveredNode);
+}
+
+bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+{
+ return passSubframeEventToSubframe(mev, subframe);
+}
+
+unsigned EventHandler::accessKeyModifiers()
+{
+ return PlatformKeyboardEvent::AltKey;
+}
+
+} // namespace WebCore
+
diff --git a/WebCore/page/chromium/ChromeClientChromium.h b/WebCore/page/chromium/ChromeClientChromium.h
index fc42250..e897c15 100644
--- a/WebCore/page/chromium/ChromeClientChromium.h
+++ b/WebCore/page/chromium/ChromeClientChromium.h
@@ -48,7 +48,10 @@ public:
// If handleExternal is true, then drawing and input handling for the
// popup will be handled by the external embedder.
virtual void popupOpened(PopupContainer* popupContainer, const IntRect& bounds,
- bool focusOnShow, bool handleExternal) = 0;
+ bool handleExternal) = 0;
+
+ // Notifies the client a popup was closed.
+ virtual void popupClosed(PopupContainer* popupContainer) = 0;
// Notifies embedder that the state of an accessibility object has changed.
virtual void didChangeAccessibilityObjectState(AccessibilityObject*) = 0;
diff --git a/WebCore/page/chromium/DragControllerChromium.cpp b/WebCore/page/chromium/DragControllerChromium.cpp
index 7b0958d..de53d19 100644
--- a/WebCore/page/chromium/DragControllerChromium.cpp
+++ b/WebCore/page/chromium/DragControllerChromium.cpp
@@ -66,7 +66,12 @@ bool DragController::isCopyKeyDown()
const IntSize& DragController::maxDragImageSize()
{
+#if OS(DARWIN)
+ // Match Safari's drag image size.
+ static const IntSize maxDragImageSize(400, 400);
+#else
static const IntSize maxDragImageSize(200, 200);
+#endif
return maxDragImageSize;
}
diff --git a/WebCore/page/efl/DragControllerEfl.cpp b/WebCore/page/efl/DragControllerEfl.cpp
new file mode 100644
index 0000000..0c5f002
--- /dev/null
+++ b/WebCore/page/efl/DragControllerEfl.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2007 Apple Inc.
+ * Copyright (C) 2009-2010 ProFUSION embedded systems
+ * Copyright (C) 2009-2010 Samsung Electronics
+ * 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 "DragController.h"
+
+#include "DragData.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "Page.h"
+
+namespace WebCore {
+
+const int DragController::LinkDragBorderInset = 2;
+const int DragController::MaxOriginalImageArea = 1500 * 1500;
+const int DragController::DragIconRightInset = 7;
+const int DragController::DragIconBottomInset = 3;
+
+const float DragController::DragImageAlpha = 0.75f;
+
+bool DragController::isCopyKeyDown()
+{
+ return false;
+}
+
+DragOperation DragController::dragOperation(DragData* dragData)
+{
+ if (dragData->containsURL())
+ return DragOperationCopy;
+
+ return DragOperationNone;
+}
+
+const IntSize& DragController::maxDragImageSize()
+{
+ static const IntSize maxDragImageSize(400, 400);
+
+ return maxDragImageSize;
+}
+
+void DragController::cleanupAfterSystemDrag()
+{}
+
+}
diff --git a/WebCore/page/efl/EventHandlerEfl.cpp b/WebCore/page/efl/EventHandlerEfl.cpp
new file mode 100644
index 0000000..df5c276
--- /dev/null
+++ b/WebCore/page/efl/EventHandlerEfl.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2006 Zack Rusin <zack@kde.org>
+ * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia
+ * Copyright (C) 2009,2010 ProFUSION embedded systems
+ * Copyright (C) 2009,2010 Samsung Electronics
+ *
+ * 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 "EventHandler.h"
+
+#include "ClipboardEfl.h"
+#include "EventNames.h"
+#include "FloatPoint.h"
+#include "FocusController.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "KeyboardEvent.h"
+#include "MouseEventWithHitTestResults.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "PlatformKeyboardEvent.h"
+#include "PlatformWheelEvent.h"
+#include "RenderWidget.h"
+#include "Scrollbar.h"
+
+namespace WebCore {
+
+const double EventHandler::TextDragDelay = 0.0;
+
+static bool isKeyboardOptionTab(KeyboardEvent* event)
+{
+ return event
+ && (event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent)
+ && event->altKey()
+ && event->keyIdentifier() == "U+0009";
+}
+
+bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const
+{
+ return isKeyboardOptionTab(event);
+}
+
+bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
+{
+ return true;
+}
+
+void EventHandler::focusDocumentView()
+{
+ if (Page* page = m_frame->page())
+ page->focusController()->setFocusedFrame(m_frame);
+}
+
+bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
+{
+ RenderObject* target = event.targetNode() ? event.targetNode()->renderer() : 0;
+
+ if (!target || !target->isWidget())
+ return false;
+
+ return passMouseDownEventToWidget(static_cast<RenderWidget*>(target)->widget());
+}
+
+bool EventHandler::passWidgetMouseDownEventToWidget(RenderWidget* renderWidget)
+{
+ return passMouseDownEventToWidget(renderWidget->widget());
+}
+
+bool EventHandler::passMouseDownEventToWidget(Widget* widget)
+{
+ notImplemented();
+ return false;
+}
+
+bool EventHandler::eventActivatedView(const PlatformMouseEvent&) const
+{
+ notImplemented();
+ return false;
+}
+
+bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* widget)
+{
+ ASSERT(widget);
+ if (!widget->isFrameView())
+ return false;
+
+ return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(event);
+}
+
+PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
+{
+ return new ClipboardEfl(ClipboardWritable, true);
+}
+
+bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+{
+ subframe->eventHandler()->handleMousePressEvent(mev.event());
+ return true;
+}
+
+bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode)
+{
+ subframe->eventHandler()->handleMouseMoveEvent(mev.event(), hoveredNode);
+ return true;
+}
+
+bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+{
+ subframe->eventHandler()->handleMouseReleaseEvent(mev.event());
+ return true;
+}
+
+unsigned EventHandler::accessKeyModifiers()
+{
+ return PlatformKeyboardEvent::AltKey;
+}
+}
diff --git a/WebCore/page/win/PageWin.cpp b/WebCore/page/efl/FrameEfl.cpp
index 3ef7728..783df7e 100644
--- a/WebCore/page/win/PageWin.cpp
+++ b/WebCore/page/efl/FrameEfl.cpp
@@ -1,5 +1,7 @@
/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia
+ * Copyright (C) 2009-2010 ProFUSION embedded systems
+ * Copyright (C) 2009-2010 Samsung Electronics
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -20,14 +22,20 @@
* 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.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-#include "Page.h"
+#include "Frame.h"
+
+#include "NotImplemented.h"
namespace WebCore {
-HINSTANCE Page::s_instanceHandle = 0;
+DragImageRef Frame::dragImageForSelection()
+{
+ notImplemented();
+ return 0;
+}
-} // namespace WebCore
+}
diff --git a/WebCore/page/haiku/EventHandlerHaiku.cpp b/WebCore/page/haiku/EventHandlerHaiku.cpp
index 203344e..450414d 100644
--- a/WebCore/page/haiku/EventHandlerHaiku.cpp
+++ b/WebCore/page/haiku/EventHandlerHaiku.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 2006 Zack Rusin <zack@kde.org>
* Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
* Copyright (C) 2009 Maxime Simon <simon.maxime@gmail.com>
+ * Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,7 +40,6 @@
#include "NotImplemented.h"
#include "Page.h"
#include "PlatformKeyboardEvent.h"
-#include "PlatformScrollBar.h"
#include "PlatformWheelEvent.h"
#include "RenderWidget.h"
@@ -56,7 +56,7 @@ static bool isKeyboardOptionTab(KeyboardEvent* event)
&& (event->type() == eventNames().keydownEvent
|| event->type() == eventNames().keypressEvent)
&& event->altKey()
- && event->keyIdentifier() == "U+000009";
+ && event->keyIdentifier() == "U+0009";
}
bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const
@@ -74,8 +74,10 @@ bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
void EventHandler::focusDocumentView()
{
BView* view = m_frame->view()->platformWidget();
- if (view)
- view->MakeFocus();
+ if (view && view->LockLooperWithTimeout(5000) == B_OK) {
+ view->MakeFocus(true);
+ view->UnlockLooper();
+ }
Page* page = m_frame->page();
if (page)
@@ -102,18 +104,14 @@ bool EventHandler::passMouseDownEventToWidget(Widget* widget)
return false;
}
-bool EventHandler::eventActivatedView(const PlatformMouseEvent&) const
+bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const
{
- notImplemented();
+ // On Haiku, clicks which activate the window in non focus-follows-mouse mode
+ // are not passed to the window, so any event we generate is not the activation
+ // event.
return false;
}
-bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& event, Frame* subframe, HitTestResult*)
-{
- notImplemented();
- return true;
-}
-
bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* widget)
{
if (!widget->isFrameView())
@@ -129,21 +127,27 @@ PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
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, HitTestResult* hoveredNode)
{
- return passSubframeEventToSubframe(mev, subframe, hoveredNode);
+ subframe->eventHandler()->handleMouseMoveEvent(mev.event(), hoveredNode);
+ return true;
}
bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
{
- return passSubframeEventToSubframe(mev, subframe);
+ subframe->eventHandler()->handleMouseReleaseEvent(mev.event());
+ return true;
}
unsigned EventHandler::accessKeyModifiers()
{
+ // NOTE: On Haiku, the user can choose Alt or Ctrl as access key, but
+ // the PlatformKeyboardEvent already takes care of this, internally,
+ // we always use Alt.
return PlatformKeyboardEvent::AltKey;
}
diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm
index 9e77387..356503f 100644
--- a/WebCore/page/mac/FrameMac.mm
+++ b/WebCore/page/mac/FrameMac.mm
@@ -416,12 +416,12 @@ NSDictionary* Frame::fontAttributesForSelectionStart() const
if (style->color().isValid() && style->color() != Color::black)
[result setObject:nsColor(style->color()) forKey:NSForegroundColorAttributeName];
- ShadowData* shadow = style->textShadow();
+ const ShadowData* shadow = style->textShadow();
if (shadow) {
NSShadow* s = [[NSShadow alloc] init];
- [s setShadowOffset:NSMakeSize(shadow->x, shadow->y)];
- [s setShadowBlurRadius:shadow->blur];
- [s setShadowColor:nsColor(shadow->color)];
+ [s setShadowOffset:NSMakeSize(shadow->x(), shadow->y())];
+ [s setShadowBlurRadius:shadow->blur()];
+ [s setShadowColor:nsColor(shadow->color())];
[result setObject:s forKey:NSShadowAttributeName];
}
diff --git a/WebCore/page/mac/WebCoreViewFactory.h b/WebCore/page/mac/WebCoreViewFactory.h
index fef856a..db70b6d 100644
--- a/WebCore/page/mac/WebCoreViewFactory.h
+++ b/WebCore/page/mac/WebCoreViewFactory.h
@@ -142,6 +142,9 @@
- (NSString *)AXMenuListPopupActionVerb;
- (NSString *)AXMenuListActionVerb;
+- (NSString *)missingPluginText;
+- (NSString *)crashedPluginText;
+
- (NSString *)multipleFileUploadTextForNumberOfFiles:(unsigned)numberOfFiles;
// FTP Directory Related
- (NSString *)unknownFileSizeText;
diff --git a/WebCore/page/qt/EventHandlerQt.cpp b/WebCore/page/qt/EventHandlerQt.cpp
index 3425289..d7982fa 100644
--- a/WebCore/page/qt/EventHandlerQt.cpp
+++ b/WebCore/page/qt/EventHandlerQt.cpp
@@ -132,7 +132,11 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
unsigned EventHandler::accessKeyModifiers()
{
- return PlatformKeyboardEvent::CtrlKey;
+#if OS(DARWIN)
+ return PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;
+#else
+ return PlatformKeyboardEvent::AltKey;
+#endif
}
}