diff options
Diffstat (limited to 'WebCore/page')
60 files changed, 1039 insertions, 450 deletions
diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp index 7e14b3e..0b85535 100644 --- a/WebCore/page/Chrome.cpp +++ b/WebCore/page/Chrome.cpp @@ -154,6 +154,11 @@ void Chrome::takeFocus(FocusDirection direction) const m_client->takeFocus(direction); } +void Chrome::focusedNodeChanged(Node* node) const +{ + m_client->focusedNodeChanged(node); +} + Page* Chrome::createWindow(Frame* frame, const FrameLoadRequest& request, const WindowFeatures& features) const { Page* newPage = m_client->createWindow(frame, request, features); @@ -309,6 +314,16 @@ bool Chrome::shouldInterruptJavaScript() return m_client->shouldInterruptJavaScript(); } +void Chrome::registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title) +{ + m_client->registerProtocolHandler(scheme, baseURL, url, title); +} + +void Chrome::registerContentHandler(const String& mimeType, const String& baseURL, const String& url, const String& title) +{ + m_client->registerContentHandler(mimeType, baseURL, url, title); +} + IntRect Chrome::windowResizerRect() const { return m_client->windowResizerRect(); @@ -399,11 +414,6 @@ void Chrome::print(Frame* frame) void Chrome::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation) { - // Defer loads in case the client method runs a new event loop that would - // otherwise cause the load to continue while we're in the middle of executing JavaScript. - PageGroupLoadDeferrer deferrer(m_page, true); - - ASSERT(frame); m_client->requestGeolocationPermissionForFrame(frame, geolocation); } diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h index c562f33..398548f 100644 --- a/WebCore/page/Chrome.h +++ b/WebCore/page/Chrome.h @@ -42,6 +42,7 @@ namespace WebCore { class Geolocation; class HitTestResult; class IntRect; + class Node; class Page; class String; #if ENABLE(NOTIFICATIONS) @@ -86,6 +87,8 @@ namespace WebCore { bool canTakeFocus(FocusDirection) const; void takeFocus(FocusDirection) const; + void focusedNodeChanged(Node*) const; + Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&) const; void show() const; @@ -118,6 +121,9 @@ namespace WebCore { void setStatusbarText(Frame*, const String&); bool shouldInterruptJavaScript(); + void registerProtocolHandler(const String& scheme, const String& baseURL, const String& url, const String& title); + void registerContentHandler(const String& mimeType, const String& baseURL, const String& url, const String& title); + IntRect windowResizerRect() const; void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); @@ -132,7 +138,7 @@ namespace WebCore { bool setCursor(PlatformCursorHandle); -#if PLATFORM(MAC) +#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) void focusNSView(NSView*); #endif diff --git a/WebCore/page/ChromeClient.h b/WebCore/page/ChromeClient.h index 194f855..117953c 100644 --- a/WebCore/page/ChromeClient.h +++ b/WebCore/page/ChromeClient.h @@ -87,6 +87,8 @@ namespace WebCore { virtual bool canTakeFocus(FocusDirection) = 0; virtual void takeFocus(FocusDirection) = 0; + virtual void focusedNodeChanged(Node*) = 0; + // The Frame pointer provides the ChromeClient with context about which // Frame wants to create the new Page. Also, the newly created window // should not be shown to the user until the ChromeClient of the newly @@ -125,6 +127,9 @@ namespace WebCore { virtual bool shouldInterruptJavaScript() = 0; virtual bool tabsToLinks() const = 0; + virtual void registerProtocolHandler(const String&, const String&, const String&, const String&) { } + virtual void registerContentHandler(const String&, const String&, const String&, const String&) { } + virtual IntRect windowResizerRect() const = 0; // Methods used by HostWindow. diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp index 7d0f697..b1b091a 100644 --- a/WebCore/page/Console.cpp +++ b/WebCore/page/Console.cpp @@ -191,7 +191,7 @@ void Console::addMessage(MessageType type, MessageLevel level, ScriptCallStack* for (unsigned i = 0; i < lastCaller.argumentCount(); ++i) { String argAsString; - if (lastCaller.argumentAt(i).getString(argAsString)) + if (lastCaller.argumentAt(i).getString(callStack->state(), argAsString)) printf(" %s", argAsString.utf8().data()); } printf("\n"); @@ -270,6 +270,23 @@ void Console::count(ScriptCallStack* callStack) #endif } +void Console::markTimeline(ScriptCallStack* callStack) +{ +#if ENABLE(INSPECTOR) + Page* page = this->page(); + if (!page) + return; + + const ScriptCallFrame& lastCaller = callStack->at(0); + String message; + getFirstArgumentAsString(callStack->state(), lastCaller, message); + + page->inspectorController()->markTimeline(message); +#else + UNUSED_PARAM(callStack); +#endif +} + #if ENABLE(WML) String Console::lastWMLErrorMessage() const { diff --git a/WebCore/page/Console.h b/WebCore/page/Console.h index 1b93a4a..ea3a161 100644 --- a/WebCore/page/Console.h +++ b/WebCore/page/Console.h @@ -95,6 +95,7 @@ namespace WebCore { void trace(ScriptCallStack*); void assertCondition(bool condition, ScriptCallStack*); void count(ScriptCallStack*); + void markTimeline(ScriptCallStack*); #if ENABLE(WML) String lastWMLErrorMessage() const; #endif diff --git a/WebCore/page/Console.idl b/WebCore/page/Console.idl index 0e9f3dc..a31b605 100644 --- a/WebCore/page/Console.idl +++ b/WebCore/page/Console.idl @@ -44,14 +44,15 @@ module window { [CustomArgumentHandling] void trace(); [CustomArgumentHandling, ImplementationFunction=assertCondition] void assert(in boolean condition); [CustomArgumentHandling] void count(); + [CustomArgumentHandling] void markTimeline(); #if defined(ENABLE_WML) && ENABLE_WML [DontEnum] DOMString lastWMLErrorMessage(); #endif -#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER - [CustomArgumentHandling] void profile(in [ConvertUndefinedOrNullToNullString] DOMString title); - [CustomArgumentHandling] void profileEnd(in [ConvertUndefinedOrNullToNullString] DOMString title); +#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER || defined(V8_BINDING) && V8_BINDING + [Custom] void profile(in [ConvertUndefinedOrNullToNullString] DOMString title); + [Custom] void profileEnd(in [ConvertUndefinedOrNullToNullString] DOMString title); #endif void time(in [ConvertUndefinedOrNullToNullString] DOMString title); diff --git a/WebCore/page/ContextMenuController.cpp b/WebCore/page/ContextMenuController.cpp index 7d773ca..726dee9 100644 --- a/WebCore/page/ContextMenuController.cpp +++ b/WebCore/page/ContextMenuController.cpp @@ -31,6 +31,7 @@ #include "Chrome.h" #include "ContextMenu.h" #include "ContextMenuClient.h" +#include "ContextMenuSelectionHandler.h" #include "Document.h" #include "DocumentFragment.h" #include "DocumentLoader.h" @@ -66,6 +67,7 @@ ContextMenuController::ContextMenuController(Page* page, ContextMenuClient* clie : m_page(page) , m_client(client) , m_contextMenu(0) + , m_selectionHandler(0) { ASSERT_ARG(page, page); ASSERT_ARG(client, client); @@ -79,13 +81,40 @@ ContextMenuController::~ContextMenuController() void ContextMenuController::clearContextMenu() { m_contextMenu.set(0); + if (m_selectionHandler) + m_selectionHandler->contextMenuCleared(); + m_selectionHandler = 0; } void ContextMenuController::handleContextMenuEvent(Event* event) { - ASSERT(event->type() == eventNames().contextmenuEvent); - if (!event->isMouseEvent()) + m_contextMenu.set(createContextMenu(event)); + if (!m_contextMenu) return; + m_contextMenu->populate(); + showContextMenu(event); +} + +void ContextMenuController::showContextMenu(Event* event, Vector<ContextMenuItem>& items, PassRefPtr<ContextMenuSelectionHandler> selectionHandler) +{ + m_selectionHandler = selectionHandler; + + m_contextMenu.set(createContextMenu(event)); + if (!m_contextMenu) { + clearContextMenu(); + return; + } + for (size_t i = 0; i < items.size(); ++i) { + ContextMenuItem& item = items[i]; + m_contextMenu->appendItem(item); + } + showContextMenu(event); +} + +ContextMenu* ContextMenuController::createContextMenu(Event* event) +{ + if (!event->isMouseEvent()) + return 0; MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); HitTestResult result(mouseEvent->absoluteLocation()); @@ -93,18 +122,18 @@ void ContextMenuController::handleContextMenuEvent(Event* event) result = frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false); if (!result.innerNonSharedNode()) - return; + return 0; + return new ContextMenu(result); +} - m_contextMenu.set(new ContextMenu(result)); - m_contextMenu->populate(); +void ContextMenuController::showContextMenu(Event* event) +{ #if ENABLE(INSPECTOR) if (m_page->inspectorController()->enabled()) m_contextMenu->addInspectElementItem(); #endif - PlatformMenuDescription customMenu = m_client->getCustomMenuFromDefaultItems(m_contextMenu.get()); m_contextMenu->setPlatformDescription(customMenu); - event->setDefaultHandled(); } @@ -126,6 +155,12 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item) return; } + if (item->action() >= ContextMenuItemBaseCustomTag) { + ASSERT(m_selectionHandler); + m_selectionHandler->contextMenuItemSelected(item); + return; + } + HitTestResult result = m_contextMenu->hitTestResult(); Frame* frame = result.innerNonSharedNode()->document()->frame(); if (!frame) diff --git a/WebCore/page/ContextMenuController.h b/WebCore/page/ContextMenuController.h index 38095f6..d51bc70 100644 --- a/WebCore/page/ContextMenuController.h +++ b/WebCore/page/ContextMenuController.h @@ -28,12 +28,16 @@ #include <wtf/Noncopyable.h> #include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> +#include <wtf/Vector.h> namespace WebCore { class ContextMenu; class ContextMenuClient; class ContextMenuItem; + class ContextMenuSelectionHandler; class Event; class Page; @@ -48,12 +52,18 @@ namespace WebCore { void clearContextMenu(); void handleContextMenuEvent(Event*); + void showContextMenu(Event*, Vector<ContextMenuItem>&, PassRefPtr<ContextMenuSelectionHandler>); + void contextMenuItemSelected(ContextMenuItem*); private: + ContextMenu* createContextMenu(Event*); + void showContextMenu(Event*); + Page* m_page; ContextMenuClient* m_client; OwnPtr<ContextMenu> m_contextMenu; + RefPtr<ContextMenuSelectionHandler> m_selectionHandler; }; } diff --git a/WebCore/page/ContextMenuSelectionHandler.h b/WebCore/page/ContextMenuSelectionHandler.h new file mode 100644 index 0000000..d5a6631 --- /dev/null +++ b/WebCore/page/ContextMenuSelectionHandler.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ContextMenuSelectionHandler_h +#define ContextMenuSelectionHandler_h + +#include <wtf/RefCounted.h> + +namespace WebCore { + + class ContextMenuItem; + + class ContextMenuSelectionHandler : public RefCounted<ContextMenuSelectionHandler> { + public: + ContextMenuSelectionHandler() { } + virtual ~ContextMenuSelectionHandler() { }; + + virtual void contextMenuItemSelected(ContextMenuItem*) = 0; + virtual void contextMenuCleared() = 0; + }; + +} + +#endif // ContextMenuSelectionHandler_h diff --git a/WebCore/page/DOMTimer.cpp b/WebCore/page/DOMTimer.cpp index 83bcb02..8971bb7 100644 --- a/WebCore/page/DOMTimer.cpp +++ b/WebCore/page/DOMTimer.cpp @@ -119,8 +119,7 @@ void DOMTimer::fired() timerNestingLevel = m_nestingLevel; #if ENABLE(INSPECTOR) - InspectorTimelineAgent* timelineAgent = InspectorTimelineAgent::retrieve(context); - if (timelineAgent) + if (InspectorTimelineAgent* timelineAgent = InspectorTimelineAgent::retrieve(context)) timelineAgent->willFireTimer(m_timeoutId); #endif @@ -135,7 +134,7 @@ void DOMTimer::fired() // No access to member variables after this point, it can delete the timer. m_action->execute(context); #if ENABLE(INSPECTOR) - if (timelineAgent) + if (InspectorTimelineAgent* timelineAgent = InspectorTimelineAgent::retrieve(context)) timelineAgent->didFireTimer(); #endif return; @@ -149,7 +148,7 @@ void DOMTimer::fired() action->execute(context); #if ENABLE(INSPECTOR) - if (timelineAgent) + if (InspectorTimelineAgent* timelineAgent = InspectorTimelineAgent::retrieve(context)) timelineAgent->didFireTimer(); #endif delete action; diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp index 8452e55..757e32f 100644 --- a/WebCore/page/DOMWindow.cpp +++ b/WebCore/page/DOMWindow.cpp @@ -53,6 +53,7 @@ #include "HTMLFrameOwnerElement.h" #include "History.h" #include "InspectorController.h" +#include "InspectorTimelineAgent.h" #include "Location.h" #include "Media.h" #include "MessageEvent.h" @@ -459,6 +460,8 @@ void DOMWindow::clear() #endif #if ENABLE(NOTIFICATIONS) + if (m_notifications) + m_notifications->disconnectFrame(); m_notifications = 0; #endif } @@ -568,14 +571,14 @@ Storage* DOMWindow::sessionStorage() const Document* document = this->document(); if (!document) return 0; + + if (!document->securityOrigin()->canAccessStorage()) + return 0; Page* page = document->page(); if (!page) return 0; - if (!page->settings()->sessionStorageEnabled()) - return 0; - RefPtr<StorageArea> storageArea = page->sessionStorage()->storageArea(document->securityOrigin()); #if ENABLE(INSPECTOR) page->inspectorController()->didUseDOMStorage(storageArea.get(), false, m_frame); @@ -593,6 +596,9 @@ Storage* DOMWindow::localStorage() const Document* document = this->document(); if (!document) return 0; + + if (!document->securityOrigin()->canAccessStorage()) + return 0; Page* page = document->page(); if (!page) @@ -625,9 +631,6 @@ NotificationCenter* DOMWindow::webkitNotifications() const if (!page) return 0; - if (!page->settings()->experimentalNotificationsEnabled()) - return 0; - NotificationPresenter* provider = page->chrome()->notificationPresenter(); if (provider) m_notifications = NotificationCenter::create(document, provider); @@ -1112,13 +1115,15 @@ PassRefPtr<Database> DOMWindow::openDatabase(const String& name, const String& v if (!m_frame) return 0; - Document* doc = m_frame->document(); + Document* document = m_frame->document(); + if (!document->securityOrigin()->canAccessDatabase()) + return 0; Settings* settings = m_frame->settings(); if (!settings || !settings->databasesEnabled()) return 0; - return Database::openDatabase(doc, name, version, displayName, estimatedSize, ec); + return Database::openDatabase(document, name, version, displayName, estimatedSize, ec); } #endif @@ -1304,6 +1309,15 @@ void DOMWindow::dispatchLoadEvent() #endif } +#if ENABLE(INSPECTOR) +InspectorTimelineAgent* DOMWindow::inspectorTimelineAgent() +{ + if (frame() && frame()->page()) + return frame()->page()->inspectorTimelineAgent(); + return 0; +} +#endif + bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget) { RefPtr<EventTarget> protect = this; @@ -1313,7 +1327,24 @@ bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget event->setCurrentTarget(this); event->setEventPhase(Event::AT_TARGET); - return fireEventListeners(event.get()); +#if ENABLE(INSPECTOR) + InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent(); + bool timelineAgentIsActive = timelineAgent && hasEventListeners(event->type()); + if (timelineAgentIsActive) + timelineAgent->willDispatchEvent(*event); +#endif + + bool result = fireEventListeners(event.get()); + +#if ENABLE(INSPECTOR) + if (timelineAgentIsActive) { + timelineAgent = inspectorTimelineAgent(); + if (timelineAgent) + timelineAgent->didDispatchEvent(); + } +#endif + + return result; } void DOMWindow::removeAllEventListeners() diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h index 235c9a0..5e2d990 100644 --- a/WebCore/page/DOMWindow.h +++ b/WebCore/page/DOMWindow.h @@ -52,6 +52,7 @@ namespace WebCore { class FloatRect; class Frame; class History; + class InspectorTimelineAgent; class Location; class Media; class Navigator; @@ -247,9 +248,13 @@ namespace WebCore { void dispatchLoadEvent(); DEFINE_ATTRIBUTE_EVENT_LISTENER(abort); + DEFINE_ATTRIBUTE_EVENT_LISTENER(beforeunload); DEFINE_ATTRIBUTE_EVENT_LISTENER(blur); + DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay); + DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough); DEFINE_ATTRIBUTE_EVENT_LISTENER(change); DEFINE_ATTRIBUTE_EVENT_LISTENER(click); + DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu); DEFINE_ATTRIBUTE_EVENT_LISTENER(dblclick); DEFINE_ATTRIBUTE_EVENT_LISTENER(drag); DEFINE_ATTRIBUTE_EVENT_LISTENER(dragend); @@ -258,13 +263,22 @@ namespace WebCore { DEFINE_ATTRIBUTE_EVENT_LISTENER(dragover); DEFINE_ATTRIBUTE_EVENT_LISTENER(dragstart); DEFINE_ATTRIBUTE_EVENT_LISTENER(drop); + DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied); + DEFINE_ATTRIBUTE_EVENT_LISTENER(ended); DEFINE_ATTRIBUTE_EVENT_LISTENER(error); DEFINE_ATTRIBUTE_EVENT_LISTENER(focus); DEFINE_ATTRIBUTE_EVENT_LISTENER(hashchange); + DEFINE_ATTRIBUTE_EVENT_LISTENER(input); + DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); DEFINE_ATTRIBUTE_EVENT_LISTENER(keydown); DEFINE_ATTRIBUTE_EVENT_LISTENER(keypress); DEFINE_ATTRIBUTE_EVENT_LISTENER(keyup); DEFINE_ATTRIBUTE_EVENT_LISTENER(load); + DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata); + DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata); + DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart); + DEFINE_ATTRIBUTE_EVENT_LISTENER(message); DEFINE_ATTRIBUTE_EVENT_LISTENER(mousedown); DEFINE_ATTRIBUTE_EVENT_LISTENER(mousemove); DEFINE_ATTRIBUTE_EVENT_LISTENER(mouseout); @@ -275,39 +289,30 @@ namespace WebCore { DEFINE_ATTRIBUTE_EVENT_LISTENER(online); DEFINE_ATTRIBUTE_EVENT_LISTENER(pagehide); DEFINE_ATTRIBUTE_EVENT_LISTENER(pageshow); + DEFINE_ATTRIBUTE_EVENT_LISTENER(pause); + DEFINE_ATTRIBUTE_EVENT_LISTENER(play); + DEFINE_ATTRIBUTE_EVENT_LISTENER(playing); + DEFINE_ATTRIBUTE_EVENT_LISTENER(popstate); + DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); + DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange); DEFINE_ATTRIBUTE_EVENT_LISTENER(reset); DEFINE_ATTRIBUTE_EVENT_LISTENER(resize); DEFINE_ATTRIBUTE_EVENT_LISTENER(scroll); DEFINE_ATTRIBUTE_EVENT_LISTENER(search); + DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked); + DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking); DEFINE_ATTRIBUTE_EVENT_LISTENER(select); + DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled); DEFINE_ATTRIBUTE_EVENT_LISTENER(storage); DEFINE_ATTRIBUTE_EVENT_LISTENER(submit); - DEFINE_ATTRIBUTE_EVENT_LISTENER(unload); - DEFINE_ATTRIBUTE_EVENT_LISTENER(beforeunload); - DEFINE_ATTRIBUTE_EVENT_LISTENER(canplay); - DEFINE_ATTRIBUTE_EVENT_LISTENER(canplaythrough); - DEFINE_ATTRIBUTE_EVENT_LISTENER(durationchange); - DEFINE_ATTRIBUTE_EVENT_LISTENER(emptied); - DEFINE_ATTRIBUTE_EVENT_LISTENER(ended); - DEFINE_ATTRIBUTE_EVENT_LISTENER(loadeddata); - DEFINE_ATTRIBUTE_EVENT_LISTENER(loadedmetadata); - DEFINE_ATTRIBUTE_EVENT_LISTENER(pause); - DEFINE_ATTRIBUTE_EVENT_LISTENER(play); - DEFINE_ATTRIBUTE_EVENT_LISTENER(playing); - DEFINE_ATTRIBUTE_EVENT_LISTENER(ratechange); - DEFINE_ATTRIBUTE_EVENT_LISTENER(seeked); - DEFINE_ATTRIBUTE_EVENT_LISTENER(seeking); + DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend); DEFINE_ATTRIBUTE_EVENT_LISTENER(timeupdate); + DEFINE_ATTRIBUTE_EVENT_LISTENER(unload); DEFINE_ATTRIBUTE_EVENT_LISTENER(volumechange); DEFINE_ATTRIBUTE_EVENT_LISTENER(waiting); - DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart); - DEFINE_ATTRIBUTE_EVENT_LISTENER(progress); - DEFINE_ATTRIBUTE_EVENT_LISTENER(stalled); - DEFINE_ATTRIBUTE_EVENT_LISTENER(suspend); - DEFINE_ATTRIBUTE_EVENT_LISTENER(input); - DEFINE_ATTRIBUTE_EVENT_LISTENER(message); - DEFINE_ATTRIBUTE_EVENT_LISTENER(contextmenu); - DEFINE_ATTRIBUTE_EVENT_LISTENER(invalid); + DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitbeginfullscreen); + DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitendfullscreen); + #if ENABLE(ORIENTATION_EVENTS) DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange); #endif @@ -359,6 +364,7 @@ namespace WebCore { virtual void derefEventTarget() { deref(); } virtual EventTargetData* eventTargetData(); virtual EventTargetData* ensureEventTargetData(); + InspectorTimelineAgent* inspectorTimelineAgent(); RefPtr<SecurityOrigin> m_securityOrigin; KURL m_url; diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl index c7bcf82..c4b08c6 100644 --- a/WebCore/page/DOMWindow.idl +++ b/WebCore/page/DOMWindow.idl @@ -31,7 +31,6 @@ module window { CustomDefineSetter, CustomDeleteProperty, CustomGetOwnPropertySlot, - CustomGetPropertyAttributes, CustomGetPropertyNames, CustomLookupGetter, CustomLookupSetter, @@ -157,7 +156,7 @@ module window { WebKitPoint webkitConvertPointFromNodeToPage(in Node node, in WebKitPoint p); #if defined(ENABLE_OFFLINE_WEB_APPLICATIONS) && ENABLE_OFFLINE_WEB_APPLICATIONS - readonly attribute DOMApplicationCache applicationCache; + readonly attribute [EnabledAtRuntime] DOMApplicationCache applicationCache; #endif #if defined(ENABLE_DATABASE) && ENABLE_DATABASE [EnabledAtRuntime] Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize) @@ -259,6 +258,7 @@ module window { attribute EventListener onpause; attribute EventListener onplay; attribute EventListener onplaying; + attribute EventListener onpopstate; attribute EventListener onprogress; attribute EventListener onratechange; attribute EventListener onresize; @@ -439,17 +439,17 @@ module window { attribute [CustomGetter] HTMLOptionElementConstructor Option; // Usable with new operator attribute CanvasRenderingContext2DConstructor CanvasRenderingContext2D; - attribute [Conditional=3D_CANVAS] CanvasRenderingContext3DConstructor CanvasRenderingContext3D; + attribute [Conditional=3D_CANVAS] WebGLRenderingContextConstructor WebGLRenderingContext; attribute TextMetricsConstructor TextMetrics; - attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasArrayBufferConstructor CanvasArrayBuffer; // Usable with new operator - attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasByteArrayConstructor CanvasByteArray; // Usable with new operator - attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasUnsignedByteArrayConstructor CanvasUnsignedByteArray; // Usable with new operator - attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasShortArrayConstructor CanvasShortArray; // Usable with new operator - attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasUnsignedShortArrayConstructor CanvasUnsignedShortArray; // Usable with new operator - attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasIntArrayConstructor CanvasIntArray; // Usable with new operator - attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasUnsignedIntArrayConstructor CanvasUnsignedIntArray; // Usable with new operator - attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasFloatArrayConstructor CanvasFloatArray; // Usable with new operator + attribute [JSCCustomGetter,Conditional=3D_CANVAS] 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 EventConstructor Event; attribute BeforeLoadEventConstructor BeforeLoadEvent; diff --git a/WebCore/page/DragController.h b/WebCore/page/DragController.h index 9472589..3d59ebf 100644 --- a/WebCore/page/DragController.h +++ b/WebCore/page/DragController.h @@ -47,7 +47,7 @@ namespace WebCore { class Range; class SelectionController; - class DragController { + class DragController : public Noncopyable { public: DragController(Page*, DragClient*); ~DragController(); diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index 6a92aa8..8b6b602 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -213,6 +213,7 @@ void EventHandler::clear() m_frameSetBeingResized = 0; #if ENABLE(DRAG_SUPPORT) m_dragTarget = 0; + m_shouldOnlyFireDragOverEvent = false; #endif m_currentMousePosition = IntPoint(); m_mousePressNode = 0; @@ -1520,6 +1521,35 @@ bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa return me->defaultPrevented(); } +bool EventHandler::canHandleDragAndDropForTarget(DragAndDropHandleType type, Node* target, const PlatformMouseEvent& event, Clipboard* clipboard, bool* accepted) +{ + bool canHandle = false; + bool wasAccepted = false; + + if (target->hasTagName(frameTag) || target->hasTagName(iframeTag)) { + Frame* frame = static_cast<HTMLFrameElementBase*>(target)->contentFrame(); + if (frame) { + switch (type) { + case UpdateDragAndDrop: + wasAccepted = frame->eventHandler()->updateDragAndDrop(event, clipboard); + break; + case CancelDragAndDrop: + frame->eventHandler()->cancelDragAndDrop(event, clipboard); + break; + case PerformDragAndDrop: + wasAccepted = frame->eventHandler()->performDragAndDrop(event, clipboard); + break; + } + } + } else + canHandle = true; + + if (accepted) + *accepted = wasAccepted; + + return canHandle; +} + bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard) { bool accept = false; @@ -1541,28 +1571,34 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* // FIXME: this ordering was explicitly chosen to match WinIE. However, // it is sometimes incorrect when dragging within subframes, as seen with // LayoutTests/fast/events/drag-in-frames.html. - if (newTarget) { - Frame* frame = (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame() : 0; - if (frame) - accept = frame->eventHandler()->updateDragAndDrop(event, clipboard); - else - accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard); + // + // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <http://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>. + if (newTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, newTarget, event, clipboard, &accept)) { + // As per section 7.9.4 of the HTML 5 spec., we must always fire a drag event before firing a dragenter, dragleave, or dragover event. + if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) { + // for now we don't care if event handler cancels default behavior, since there is none + dispatchDragSrcEvent(eventNames().dragEvent, event); + } + accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard); } - if (m_dragTarget) { - Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0; - if (frame) - accept = frame->eventHandler()->updateDragAndDrop(event, clipboard); - else - dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard); + if (m_dragTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, m_dragTarget.get(), event, clipboard, &accept)) + dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard); + + if (newTarget) { + // We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that + // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function. + m_shouldOnlyFireDragOverEvent = true; } } else { - if (newTarget) { - Frame* frame = (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame() : 0; - if (frame) - accept = frame->eventHandler()->updateDragAndDrop(event, clipboard); - else - accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard); + if (newTarget && canHandleDragAndDropForTarget(UpdateDragAndDrop, newTarget, event, clipboard, &accept)) { + // Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier. + if (!m_shouldOnlyFireDragOverEvent && dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) { + // for now we don't care if event handler cancels default behavior, since there is none + dispatchDragSrcEvent(eventNames().dragEvent, event); + } + accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard); + m_shouldOnlyFireDragOverEvent = false; } } m_dragTarget = newTarget; @@ -1572,13 +1608,10 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard) { - if (m_dragTarget) { - Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) - ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0; - if (frame) - frame->eventHandler()->cancelDragAndDrop(event, clipboard); - else - dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard); + if (m_dragTarget && canHandleDragAndDropForTarget(CancelDragAndDrop, m_dragTarget.get(), event, clipboard)) { + if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) + dispatchDragSrcEvent(eventNames().dragEvent, event); + dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard); } clearDragState(); } @@ -1586,14 +1619,8 @@ void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard) { bool accept = false; - if (m_dragTarget) { - Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) - ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0; - if (frame) - accept = frame->eventHandler()->performDragAndDrop(event, clipboard); - else - accept = dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard); - } + if (m_dragTarget && canHandleDragAndDropForTarget(PerformDragAndDrop, m_dragTarget.get(), event, clipboard, &accept)) + dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard); clearDragState(); return accept; } @@ -1602,6 +1629,7 @@ void EventHandler::clearDragState() { m_dragTarget = 0; m_capturingMouseEventsNode = 0; + m_shouldOnlyFireDragOverEvent = false; #if PLATFORM(MAC) m_sendingEventToSubview = false; #endif @@ -1775,7 +1803,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe return swallowEvent; } -#if !PLATFORM(GTK) +#if !PLATFORM(GTK) && !(PLATFORM(CHROMIUM) && PLATFORM(LINUX)) bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&) const { return false; @@ -2205,14 +2233,7 @@ bool EventHandler::shouldDragAutoNode(Node* node, const IntPoint& point) const Page* page = m_frame->page(); return page && page->dragController()->mayStartDragAtEventLocation(m_frame, point); } - -void EventHandler::dragSourceMovedTo(const PlatformMouseEvent& event) -{ - if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) - // for now we don't care if event handler cancels default behavior, since there is none - dispatchDragSrcEvent(eventNames().dragEvent, event); -} - + void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation) { if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) { @@ -2338,9 +2359,10 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event) // gather values from DHTML element, if it set any dragState().m_dragClipboard->sourceOperation(srcOp); - // Yuck, dragSourceMovedTo() can be called as a result of kicking off the drag with - // dragImage! Because of that dumb reentrancy, we may think we've not started the - // drag when that happens. So we have to assume it's started before we kick it off. + // Yuck, a draggedImage:moveTo: message can be fired as a result of kicking off the + // drag with dragImage! Because of that dumb reentrancy, we may think we've not + // started the drag when that happens. So we have to assume it's started before we + // kick it off. dragState().m_dragClipboard->setDragHasStarted(); } } diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h index d8cd3a2..0da44f2 100644 --- a/WebCore/page/EventHandler.h +++ b/WebCore/page/EventHandler.h @@ -33,7 +33,7 @@ #include <wtf/Forward.h> #include <wtf/RefPtr.h> -#if PLATFORM(MAC) && !defined(__OBJC__) +#if PLATFORM(MAC) && !defined(__OBJC__) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) class NSView; #endif @@ -176,7 +176,6 @@ public: #if ENABLE(DRAG_SUPPORT) bool eventMayStartDrag(const PlatformMouseEvent&) const; - void dragSourceMovedTo(const PlatformMouseEvent&); void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation); #endif @@ -187,7 +186,7 @@ public: void sendResizeEvent(); void sendScrollEvent(); -#if PLATFORM(MAC) && defined(__OBJC__) +#if PLATFORM(MAC) && defined(__OBJC__) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) PassRefPtr<KeyboardEvent> currentKeyboardEvent() const; void mouseDown(NSEvent *); @@ -211,7 +210,13 @@ public: private: #if ENABLE(DRAG_SUPPORT) - struct EventHandlerDragState { + enum DragAndDropHandleType { + UpdateDragAndDrop, + CancelDragAndDrop, + PerformDragAndDrop + }; + + struct EventHandlerDragState : Noncopyable { RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture bool m_dragSrcIsLink; bool m_dragSrcIsImage; @@ -223,6 +228,8 @@ private: }; static EventHandlerDragState& dragState(); static const double TextDragDelay; + + bool canHandleDragAndDropForTarget(DragAndDropHandleType, Node* target, const PlatformMouseEvent&, Clipboard*, bool* accepted = 0); PassRefPtr<Clipboard> createDraggingClipboard() const; #endif // ENABLE(DRAG_SUPPORT) @@ -328,7 +335,7 @@ private: bool capturesDragging() const { return m_capturesDragging; } -#if PLATFORM(MAC) && defined(__OBJC__) +#if PLATFORM(MAC) && defined(__OBJC__) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) NSView *mouseDownViewIfStillGood(); PlatformMouseEvent currentPlatformMouseEvent() const; @@ -388,6 +395,7 @@ private: #if ENABLE(DRAG_SUPPORT) RefPtr<Node> m_dragTarget; + bool m_shouldOnlyFireDragOverEvent; #endif RefPtr<HTMLFrameSetElement> m_frameSetBeingResized; @@ -405,7 +413,7 @@ private: RefPtr<Node> m_previousWheelScrolledNode; -#if PLATFORM(MAC) +#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) NSView *m_mouseDownView; bool m_sendingEventToSubview; int m_activationEventNumber; diff --git a/WebCore/page/EventSource.h b/WebCore/page/EventSource.h index 5b037a4..c7ff2c9 100644 --- a/WebCore/page/EventSource.h +++ b/WebCore/page/EventSource.h @@ -36,7 +36,6 @@ #include "ActiveDOMObject.h" #include "AtomicStringHash.h" -#include "EventListener.h" #include "EventNames.h" #include "EventTarget.h" #include "KURL.h" diff --git a/WebCore/page/FocusController.h b/WebCore/page/FocusController.h index 33debf1..d86408a 100644 --- a/WebCore/page/FocusController.h +++ b/WebCore/page/FocusController.h @@ -28,6 +28,7 @@ #include "FocusDirection.h" #include <wtf/Forward.h> +#include <wtf/Noncopyable.h> #include <wtf/RefPtr.h> namespace WebCore { @@ -37,7 +38,7 @@ namespace WebCore { class Node; class Page; - class FocusController { + class FocusController : public Noncopyable { public: FocusController(Page*); diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp index b9bf94e..7e81b3d 100644 --- a/WebCore/page/Frame.cpp +++ b/WebCore/page/Frame.cpp @@ -82,6 +82,10 @@ #include <wtf/RefCountedLeakCounter.h> #include <wtf/StdLibExtras.h> +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) +#import <Carbon/Carbon.h> +#endif + #if USE(JSC) #include "JSDOMWindowShell.h" #include "runtime_root.h" @@ -874,10 +878,10 @@ void Frame::injectUserScripts(UserScriptInjectionTime injectionTime) return; UserScriptMap::const_iterator end = userScripts->end(); for (UserScriptMap::const_iterator it = userScripts->begin(); it != end; ++it) - injectUserScriptsForWorld(it->first, *it->second, injectionTime); + injectUserScriptsForWorld(it->first.get(), *it->second, injectionTime); } -void Frame::injectUserScriptsForWorld(unsigned worldID, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime) +void Frame::injectUserScriptsForWorld(DOMWrapperWorld* world, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime) { if (userScripts.isEmpty()) return; @@ -891,9 +895,8 @@ void Frame::injectUserScriptsForWorld(unsigned worldID, const UserScriptVector& for (unsigned i = 0; i < count; ++i) { UserScript* script = userScripts[i].get(); if (script->injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(doc->url(), script->whitelist(), script->blacklist())) - sourceCode.append(ScriptSourceCode(script->source(), script->url())); + m_script.evaluateInWorld(ScriptSourceCode(script->source(), script->url()), world); } - script()->evaluateInIsolatedWorld(worldID, sourceCode); } bool Frame::shouldChangeSelection(const VisibleSelection& newSelection) const @@ -919,13 +922,36 @@ bool Frame::isContentEditable() const return m_doc->inDesignMode(); } -#if !PLATFORM(MAC) - -void Frame::setUseSecureKeyboardEntry(bool) +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(DARWIN)) +const short enableRomanKeyboardsOnly = -23; +#endif +void Frame::setUseSecureKeyboardEntry(bool enable) { -} - +#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && PLATFORM(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() { @@ -1244,7 +1270,7 @@ FloatRect Frame::selectionBounds(bool clipToVisibleContent) const return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect; } -void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleContent) const +void Frame::selectionTextRects(Vector<FloatRect>& rects, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent) const { RenderView* root = contentRenderer(); if (!root) @@ -1252,19 +1278,36 @@ void Frame::selectionTextRects(Vector<FloatRect>& rects, bool clipToVisibleConte RefPtr<Range> selectedRange = selection()->toNormalizedRange(); - Vector<IntRect> intRects; - selectedRange->textRects(intRects, true); - - unsigned size = intRects.size(); FloatRect visibleContentRect = m_view->visibleContentRect(); - for (unsigned i = 0; i < size; ++i) - if (clipToVisibleContent) - rects.append(intersection(intRects[i], visibleContentRect)); - else - rects.append(intRects[i]); + + // FIMXE: we are appending empty rects to the list for those that fall outside visibleContentRect. + // We may not want to do that. + if (respectTransforms) { + Vector<FloatQuad> quads; + selectedRange->textQuads(quads, true); + + unsigned size = quads.size(); + for (unsigned i = 0; i < size; ++i) { + IntRect currRect = quads[i].enclosingBoundingBox(); + if (clipToVisibleContent) + rects.append(intersection(currRect, visibleContentRect)); + else + rects.append(currRect); + } + } else { + Vector<IntRect> intRects; + selectedRange->textRects(intRects, true); + + unsigned size = intRects.size(); + for (unsigned i = 0; i < size; ++i) { + if (clipToVisibleContent) + rects.append(intersection(intRects[i], visibleContentRect)); + else + rects.append(intRects[i]); + } + } } - // Scans logically forward from "start", including any child frames static HTMLFormElement *scanForForm(Node *start) { diff --git a/WebCore/page/Frame.h b/WebCore/page/Frame.h index 6208bbd..ca9a6d4 100644 --- a/WebCore/page/Frame.h +++ b/WebCore/page/Frame.h @@ -131,7 +131,7 @@ namespace WebCore { void injectUserScripts(UserScriptInjectionTime); private: - void injectUserScriptsForWorld(unsigned worldID, const UserScriptVector&, UserScriptInjectionTime); + void injectUserScriptsForWorld(DOMWrapperWorld*, const UserScriptVector&, UserScriptInjectionTime); private: Frame(Page*, HTMLFrameOwnerElement*, FrameLoaderClient*); @@ -274,7 +274,8 @@ namespace WebCore { void clearTypingStyle(); FloatRect selectionBounds(bool clipToVisibleContent = true) const; - void selectionTextRects(Vector<FloatRect>&, bool clipToVisibleContent = true) const; + enum SelectionRectRespectTransforms { RespectTransforms = true, IgnoreTransforms = false }; + void selectionTextRects(Vector<FloatRect>&, SelectionRectRespectTransforms respectTransforms, bool clipToVisibleContent = true) const; HTMLFormElement* currentForm() const; diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp index 944f215..87d2d6c 100644 --- a/WebCore/page/FrameView.cpp +++ b/WebCore/page/FrameView.cpp @@ -107,13 +107,14 @@ static const double deferredRepaintDelayIncrementDuringLoading = 0; // The maximum number of updateWidgets iterations that should be done before returning. static const unsigned maxUpdateWidgetsIterations = 2; -struct ScheduledEvent { +struct ScheduledEvent : Noncopyable { RefPtr<Event> m_event; RefPtr<Node> m_eventTarget; }; FrameView::FrameView(Frame* frame) : m_frame(frame) + , m_canHaveScrollbars(true) , m_slowRepaintObjectCount(0) , m_layoutTimer(this, &FrameView::layoutTimerFired) , m_layoutRoot(0) @@ -206,7 +207,7 @@ void FrameView::reset() m_deferredRepaintDelay = initialDeferredRepaintDelayDuringLoading; m_deferredRepaintTimer.stop(); m_lastPaintTime = 0; - m_paintRestriction = PaintRestrictionNone; + m_paintBehavior = PaintBehaviorNormal; m_isPainting = false; m_isVisuallyNonEmpty = false; m_firstVisuallyNonEmptyLayoutCallbackPending = true; @@ -228,7 +229,10 @@ void FrameView::resetScrollbars() // Reset the document's scrollbars back to our defaults before we yield the floor. m_firstLayout = true; setScrollbarsSuppressed(true); - setScrollbarModes(ScrollbarAuto, ScrollbarAuto); + if (m_canHaveScrollbars) + setScrollbarModes(ScrollbarAuto, ScrollbarAuto); + else + setScrollbarModes(ScrollbarAlwaysOff, ScrollbarAlwaysOff); setScrollbarsSuppressed(false); } @@ -325,6 +329,23 @@ void FrameView::setMarginHeight(int h) m_margins.setHeight(h); } +void FrameView::setCanHaveScrollbars(bool canHaveScrollbars) +{ + m_canHaveScrollbars = canHaveScrollbars; + ScrollView::setCanHaveScrollbars(canHaveScrollbars); +} + +void FrameView::updateCanHaveScrollbars() +{ + ScrollbarMode hMode; + ScrollbarMode vMode; + scrollbarModes(hMode, vMode); + if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff) + m_canHaveScrollbars = false; + else + m_canHaveScrollbars = true; +} + PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation) { // FIXME: We need to update the scrollbar dynamically as documents change (or as doc elements and bodies get discovered that have custom styles). @@ -351,6 +372,9 @@ PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientatio void FrameView::setContentsSize(const IntSize& size) { + if (size == contentsSize()) + return; + m_deferSetNeedsLayouts++; ScrollView::setContentsSize(size); @@ -423,7 +447,7 @@ void FrameView::updateCompositingLayers() return; // This call will make sure the cached hasAcceleratedCompositing is updated from the pref - view->compositor()->cacheAcceleratedCompositingEnabledFlag(); + view->compositor()->cacheAcceleratedCompositingFlags(); if (!view->usesCompositing()) return; @@ -466,8 +490,9 @@ bool FrameView::syncCompositingStateRecursive() } } return allSubframesSynced; -#endif // USE(ACCELERATED_COMPOSITING) +#else // USE(ACCELERATED_COMPOSITING) return true; +#endif } void FrameView::didMoveOnscreen() @@ -513,9 +538,8 @@ void FrameView::layout(bool allowSubtree) if (isPainting()) return; -#if ENABLE(INSPECTOR) - InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent(); - if (timelineAgent) +#if ENABLE(INSPECTOR) + if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent()) timelineAgent->willLayout(); #endif @@ -577,7 +601,13 @@ void FrameView::layout(bool allowSubtree) ScrollbarMode hMode; ScrollbarMode vMode; - scrollbarModes(hMode, vMode); + if (m_canHaveScrollbars) { + hMode = ScrollbarAuto; + vMode = ScrollbarAuto; + } else { + hMode = ScrollbarAlwaysOff; + vMode = ScrollbarAlwaysOff; + } if (!subtree) { RenderObject* rootRenderer = document->documentElement() ? document->documentElement()->renderer() : 0; @@ -714,7 +744,7 @@ void FrameView::layout(bool allowSubtree) } #if ENABLE(INSPECTOR) - if (timelineAgent) + if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent()) timelineAgent->didLayout(); #endif @@ -756,6 +786,11 @@ bool FrameView::useSlowRepaints() const return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || m_isOverlapped || !m_contentIsOpaque; } +bool FrameView::useSlowRepaintsIfNotOverlapped() const +{ + return m_useSlowRepaints || m_slowRepaintObjectCount > 0 || !m_contentIsOpaque; +} + void FrameView::setUseSlowRepaints() { m_useSlowRepaints = true; @@ -939,6 +974,7 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate) double delay = adjustedDeferredRepaintDelay(); if ((m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) && !immediate) { +<<<<<<< HEAD:WebCore/page/FrameView.cpp IntRect visibleContent = visibleContentRect(); #ifdef ANDROID_CAPTURE_OFFSCREEN_PAINTS IntRect fullVis = visibleContent; @@ -949,6 +985,12 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate) ScrollView::platformOffscreenContentRectangle(fullVis, r); #endif if (visibleContent.isEmpty()) +======= + IntRect paintRect = r; + if (!paintsEntireContents()) + paintRect.intersect(visibleContentRect()); + if (paintRect.isEmpty()) +>>>>>>> webkit.org at r51976:WebCore/page/FrameView.cpp return; if (m_repaintCount == cRepaintRectUnionThreshold) { IntRect unionedRect; @@ -958,9 +1000,9 @@ void FrameView::repaintContentRectangle(const IntRect& r, bool immediate) m_repaintRects.append(unionedRect); } if (m_repaintCount < cRepaintRectUnionThreshold) - m_repaintRects.append(visibleContent); + m_repaintRects.append(paintRect); else - m_repaintRects[0].unite(visibleContent); + m_repaintRects[0].unite(paintRect); m_repaintCount++; if (!m_deferringRepaints && !m_deferredRepaintTimer.isActive()) @@ -1491,6 +1533,7 @@ void FrameView::valueChanged(Scrollbar* bar) ScrollView::valueChanged(bar); if (offset != scrollOffset()) frame()->eventHandler()->sendScrollEvent(); + frame()->loader()->client()->didChangeScrollOffset(); } void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect) @@ -1655,9 +1698,8 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect) return; #if ENABLE(INSPECTOR) - InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent(); - if (timelineAgent) - timelineAgent->willPaint(); + if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent()) + timelineAgent->willPaint(rect); #endif Document* document = frame()->document(); @@ -1670,7 +1712,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect) fillWithRed = false; // Subframe, don't fill with red. else if (isTransparent()) fillWithRed = false; // Transparent, don't fill with red. - else if (m_paintRestriction == PaintRestrictionSelectionOnly || m_paintRestriction == PaintRestrictionSelectionOnlyBlackText) + else if (m_paintBehavior & PaintBehaviorSelectionOnly) fillWithRed = false; // Selections are transparent, don't fill with red. else if (m_nodeToDraw) fillWithRed = false; // Element images are transparent, don't fill with red. @@ -1678,7 +1720,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect) fillWithRed = true; if (fillWithRed) - p->fillRect(rect, Color(0xFF, 0, 0)); + p->fillRect(rect, Color(0xFF, 0, 0), DeviceColorSpace); #endif bool isTopLevelPainter = !sCurrentPaintTimeStamp; @@ -1708,9 +1750,15 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect) // m_nodeToDraw is used to draw only one element (and its descendants) RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0; - if (m_paintRestriction == PaintRestrictionNone) + + PaintBehavior paintBehavior = m_paintBehavior; + if (paintBehavior == PaintBehaviorNormal) document->invalidateRenderedRectsForMarkersInRect(rect); - contentRenderer->layer()->paint(p, rect, m_paintRestriction, eltRenderer); + + if (document->printing()) + paintBehavior |= PaintBehaviorFlattenCompositingLayers; + + contentRenderer->layer()->paint(p, rect, paintBehavior, eltRenderer); m_isPainting = false; m_lastPaintTime = currentTime(); @@ -1725,14 +1773,14 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect) sCurrentPaintTimeStamp = 0; #if ENABLE(INSPECTOR) - if (timelineAgent) + if (InspectorTimelineAgent* timelineAgent = inspectorTimelineAgent()) timelineAgent->didPaint(); #endif } -void FrameView::setPaintRestriction(PaintRestriction pr) +void FrameView::setPaintBehavior(PaintBehavior behavior) { - m_paintRestriction = pr; + m_paintBehavior = behavior; } bool FrameView::isPainting() const diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h index 3d17d2c..11f8843 100644 --- a/WebCore/page/FrameView.h +++ b/WebCore/page/FrameView.h @@ -72,6 +72,9 @@ public: void setMarginWidth(int); void setMarginHeight(int); + virtual void setCanHaveScrollbars(bool); + void updateCanHaveScrollbars(); + virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation); virtual void setContentsSize(const IntSize&); @@ -167,7 +170,8 @@ public: void removeWidgetToUpdate(RenderPartObject*); virtual void paintContents(GraphicsContext*, const IntRect& damageRect); - void setPaintRestriction(PaintRestriction); + void setPaintBehavior(PaintBehavior); + PaintBehavior paintBehavior() const { return m_paintBehavior; } bool isPainting() const; void setNodeToDraw(Node*); @@ -206,6 +210,7 @@ private: friend class RenderWidget; bool useSlowRepaints() const; + bool useSlowRepaintsIfNotOverlapped() const; void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode); @@ -257,6 +262,7 @@ private: bool m_doFullRepaint; + bool m_canHaveScrollbars; bool m_useSlowRepaints; bool m_isOverlapped; bool m_contentIsOpaque; @@ -307,7 +313,7 @@ private: bool m_setNeedsLayoutWasDeferred; RefPtr<Node> m_nodeToDraw; - PaintRestriction m_paintRestriction; + PaintBehavior m_paintBehavior; bool m_isPainting; bool m_isVisuallyNonEmpty; diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp index 604802f..561d19c 100644 --- a/WebCore/page/Geolocation.cpp +++ b/WebCore/page/Geolocation.cpp @@ -87,8 +87,13 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*) { m_timer.stop(); +<<<<<<< HEAD:WebCore/page/Geolocation.cpp // Cache our pointer to the Geolocation object, as this object could be // deleted by a call to clearWatch in a callback. +======= + // Cache our pointer to the Geolocation object, as this GeoNotifier object + // could be deleted by a call to clearWatch in a callback. +>>>>>>> webkit.org at r51976:WebCore/page/Geolocation.cpp Geolocation* geolocation = m_geolocation; if (m_fatalError) { @@ -96,12 +101,15 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*) m_errorCallback->handleEvent(m_fatalError.get()); // This will cause this notifier to be deleted. geolocation->fatalErrorOccurred(this); +<<<<<<< HEAD:WebCore/page/Geolocation.cpp return; } if (m_cachedPosition) { m_successCallback->handleEvent(m_cachedPosition.get()); geolocation->requestReturnedCachedPosition(this); +======= +>>>>>>> webkit.org at r51976:WebCore/page/Geolocation.cpp return; } @@ -112,10 +120,12 @@ void Geolocation::GeoNotifier::timerFired(Timer<GeoNotifier>*) geolocation->requestTimedOut(this); } -void Geolocation::Watchers::set(int id, PassRefPtr<GeoNotifier> notifier) +void Geolocation::Watchers::set(int id, PassRefPtr<GeoNotifier> prpNotifier) { - m_idToNotifierMap.set(id, notifier); - m_notifierToIdMap.set(notifier, id); + RefPtr<GeoNotifier> notifier = prpNotifier; + + m_idToNotifierMap.set(id, notifier.get()); + m_notifierToIdMap.set(notifier.release(), id); } void Geolocation::Watchers::remove(int id) @@ -360,6 +370,7 @@ PassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<Positi if (isDenied()) notifier->setFatalError(PositionError::create(PositionError::PERMISSION_DENIED, permissionDeniedErrorMessage)); else { +<<<<<<< HEAD:WebCore/page/Geolocation.cpp if (haveSuitableCachedPosition(notifier->m_options.get())) { ASSERT(m_cachedPositionManager->cachedPosition()); if (isAllowed()) @@ -374,6 +385,12 @@ PassRefPtr<Geolocation::GeoNotifier> Geolocation::startRequest(PassRefPtr<Positi else notifier->setFatalError(PositionError::create(PositionError::UNKNOWN_ERROR, "Failed to start Geolocation service")); } +======= + if (notifier->hasZeroTimeout() || m_service->startUpdating(notifier->m_options.get())) + notifier->startTimerIfNeeded(); + else + notifier->setFatalError(PositionError::create(PositionError::POSITION_UNAVAILABLE, "Failed to start Geolocation service")); +>>>>>>> webkit.org at r51976:WebCore/page/Geolocation.cpp } return notifier.release(); diff --git a/WebCore/page/HaltablePlugin.h b/WebCore/page/HaltablePlugin.h index a5fe0f4..0f4aa41 100644 --- a/WebCore/page/HaltablePlugin.h +++ b/WebCore/page/HaltablePlugin.h @@ -37,6 +37,8 @@ public: virtual void halt() = 0; virtual void restart() = 0; virtual Node* node() const = 0; + virtual bool isWindowed() const = 0; + virtual String pluginName() const = 0; }; } // namespace WebCore diff --git a/WebCore/page/History.cpp b/WebCore/page/History.cpp index 9a27f1c..ea9819e 100644 --- a/WebCore/page/History.cpp +++ b/WebCore/page/History.cpp @@ -26,8 +26,12 @@ #include "config.h" #include "History.h" +#include "ExceptionCode.h" #include "Frame.h" #include "FrameLoader.h" +#include "FrameLoaderClient.h" +#include "HistoryItem.h" +#include "Page.h" namespace WebCore { @@ -76,4 +80,46 @@ void History::go(int distance) m_frame->redirectScheduler()->scheduleHistoryNavigation(distance); } +KURL History::urlForState(const String& urlString) +{ + KURL baseURL = m_frame->loader()->baseURL(); + if (urlString.isEmpty()) + return baseURL; + + KURL absoluteURL(baseURL, urlString); + if (!absoluteURL.isValid()) + return KURL(); + + if (absoluteURL.string().left(absoluteURL.pathStart()) != baseURL.string().left(baseURL.pathStart())) + return KURL(); + + return absoluteURL; +} + +void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const String& title, const String& urlString, StateObjectType stateObjectType, ExceptionCode& ec) +{ + if (!m_frame) + return; + ASSERT(m_frame->page()); + + KURL fullURL = urlForState(urlString); + if (!fullURL.isValid()) { + ec = SECURITY_ERR; + return; + } + + if (stateObjectType == StateObjectPush) + m_frame->loader()->history()->pushState(data, title, fullURL.string()); + else if (stateObjectType == StateObjectReplace) + m_frame->loader()->history()->replaceState(data, title, fullURL.string()); + + if (!urlString.isEmpty()) { + m_frame->document()->updateURLForPushOrReplaceState(fullURL); + if (stateObjectType == StateObjectPush) + m_frame->loader()->client()->dispatchDidPushStateWithinPage(); + else if (stateObjectType == StateObjectReplace) + m_frame->loader()->client()->dispatchDidReplaceStateWithinPage(); + } +} + } // namespace WebCore diff --git a/WebCore/page/History.h b/WebCore/page/History.h index f0df2de..66a6a03 100644 --- a/WebCore/page/History.h +++ b/WebCore/page/History.h @@ -26,30 +26,42 @@ #ifndef History_h #define History_h +#include "KURL.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> namespace WebCore { - class Frame; +class Frame; +class SerializedScriptValue; +class String; +typedef int ExceptionCode; - class History : public RefCounted<History> { - public: - static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); } - - Frame* frame() const; - void disconnectFrame(); +class History : public RefCounted<History> { +public: + static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); } + + Frame* frame() const; + void disconnectFrame(); - unsigned length() const; - void back(); - void forward(); - void go(int distance); + unsigned length() const; + void back(); + void forward(); + void go(int distance); - private: - History(Frame*); - - Frame* m_frame; + enum StateObjectType { + StateObjectPush, + StateObjectReplace }; + void stateObjectAdded(PassRefPtr<SerializedScriptValue>, const String& title, const String& url, StateObjectType, ExceptionCode&); + +private: + History(Frame*); + + KURL urlForState(const String& url); + + Frame* m_frame; +}; } // namespace WebCore diff --git a/WebCore/page/History.idl b/WebCore/page/History.idl index 914d441..3790552 100644 --- a/WebCore/page/History.idl +++ b/WebCore/page/History.idl @@ -39,6 +39,11 @@ module window { [DoNotCheckDomainSecurity] void back(); [DoNotCheckDomainSecurity] void forward(); [DoNotCheckDomainSecurity] void go(in long distance); + + [Custom] 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) + raises(DOMException); }; } diff --git a/WebCore/page/MouseEventWithHitTestResults.h b/WebCore/page/MouseEventWithHitTestResults.h index 7330d93..8c28574 100644 --- a/WebCore/page/MouseEventWithHitTestResults.h +++ b/WebCore/page/MouseEventWithHitTestResults.h @@ -1,4 +1,4 @@ -/* This file is part of the KDE project +/* Copyright (C) 2000 Simon Hausmann <hausmann@kde.org> Copyright (C) 2006 Apple Computer, Inc. diff --git a/WebCore/page/Navigator.cpp b/WebCore/page/Navigator.cpp index 4922860..a4193fc 100644 --- a/WebCore/page/Navigator.cpp +++ b/WebCore/page/Navigator.cpp @@ -24,10 +24,12 @@ #include "Navigator.h" #include "CookieJar.h" +#include "ExceptionCode.h" #include "Frame.h" #include "FrameLoader.h" #include "FrameLoaderClient.h" #include "Geolocation.h" +#include "KURL.h" #include "Language.h" #include "MimeTypeArray.h" #include "Page.h" @@ -169,4 +171,93 @@ void Navigator::getStorageUpdates() } #endif +static bool verifyCustomHandlerURL(const String& baseURL, const String& url, ExceptionCode& ec) +{ + // The specification requires that it is a SYNTAX_ERR if the the "%s" token is not present. + static const char token[] = "%s"; + int index = url.find(token); + if (-1 == index) { + ec = SYNTAX_ERR; + return false; + } + + // It is also a SYNTAX_ERR if the custom handler URL, as created by removing + // the "%s" token and prepending the base url, does not resolve. + String newURL = url; + newURL.remove(index, sizeof(token) / sizeof(token[0])); + + KURL base(ParsedURLString, baseURL); + KURL kurl(base, newURL); + + if (kurl.isEmpty() || !kurl.isValid()) { + ec = SYNTAX_ERR; + return false; + } + + return true; +} + +static bool verifyProtocolHandlerScheme(const String& scheme, ExceptionCode& ec) +{ + // It is a SECURITY_ERR for these schemes to be handled by a custom handler. + if (equalIgnoringCase(scheme, "http") || equalIgnoringCase(scheme, "https") || equalIgnoringCase(scheme, "file")) { + ec = SECURITY_ERR; + return false; + } + return true; +} + +void Navigator::registerProtocolHandler(const String& scheme, const String& url, const String& title, ExceptionCode& ec) +{ + if (!verifyProtocolHandlerScheme(scheme, ec)) + return; + + if (!m_frame) + return; + + Document* document = m_frame->document(); + if (!document) + return; + + String baseURL = document->baseURL().baseAsString(); + + if (!verifyCustomHandlerURL(baseURL, url, ec)) + return; + + if (Page* page = m_frame->page()) + page->chrome()->registerProtocolHandler(scheme, baseURL, url, m_frame->displayStringModifiedByEncoding(title)); +} + +static bool verifyProtocolHandlerMimeType(const String& type, ExceptionCode& ec) +{ + // It is a SECURITY_ERR for these mime types to be assigned to a custom + // handler. + if (equalIgnoringCase(type, "text/html") || equalIgnoringCase(type, "text/css") || equalIgnoringCase(type, "application/x-javascript")) { + ec = SECURITY_ERR; + return false; + } + return true; +} + +void Navigator::registerContentHandler(const String& mimeType, const String& url, const String& title, ExceptionCode& ec) +{ + if (!verifyProtocolHandlerMimeType(mimeType, ec)) + return; + + if (!m_frame) + return; + + Document* document = m_frame->document(); + if (!document) + return; + + String baseURL = document->baseURL().baseAsString(); + + if (!verifyCustomHandlerURL(baseURL, url, ec)) + return; + + if (Page* page = m_frame->page()) + page->chrome()->registerContentHandler(mimeType, baseURL, url, m_frame->displayStringModifiedByEncoding(title)); +} + } // namespace WebCore diff --git a/WebCore/page/Navigator.h b/WebCore/page/Navigator.h index 4adebe1..107082b 100644 --- a/WebCore/page/Navigator.h +++ b/WebCore/page/Navigator.h @@ -34,6 +34,8 @@ namespace WebCore { class PluginArray; class String; + typedef int ExceptionCode; + class Navigator : public NavigatorBase, public RefCounted<Navigator> { public: static PassRefPtr<Navigator> create(Frame* frame) { return adoptRef(new Navigator(frame)); } @@ -60,6 +62,9 @@ namespace WebCore { void getStorageUpdates(); #endif + void registerProtocolHandler(const String& scheme, const String& url, const String& title, ExceptionCode& ec); + void registerContentHandler(const String& mimeType, const String& url, const String& title, ExceptionCode& ec); + private: Navigator(Frame*); Frame* m_frame; diff --git a/WebCore/page/Navigator.idl b/WebCore/page/Navigator.idl index 80ef4fb..99b22af 100644 --- a/WebCore/page/Navigator.idl +++ b/WebCore/page/Navigator.idl @@ -46,6 +46,11 @@ module window { #if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE void getStorageUpdates(); #endif + + void registerProtocolHandler(in DOMString scheme, in DOMString url, in DOMString title) + raises(DomException); + void registerContentHandler(in DOMString mimeType, in DOMString url, in DOMString title) + raises(DomException); }; } diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp index 8a685f4..c4f33d6 100644 --- a/WebCore/page/Page.cpp +++ b/WebCore/page/Page.cpp @@ -21,6 +21,7 @@ #include "config.h" #include "Page.h" +#include "BackForwardList.h" #include "Base64.h" #include "CSSStyleSelector.h" #include "Chrome.h" @@ -277,20 +278,30 @@ void Page::goBackOrForward(int distance) void Page::goToItem(HistoryItem* item, FrameLoadType type) { - // Abort any current load if we're going to a history item +#if !ASSERT_DISABLED + // If we're navigating to an item with history state for a Document other than the + // current Document, the new Document had better be in the page cache. + if (item->stateObject() && item->document() != m_mainFrame->document()) + ASSERT(item->document()->inPageCache()); +#endif - // Define what to do with any open database connections. By default we stop them and terminate the database thread. - DatabasePolicy databasePolicy = DatabasePolicyStop; + // Abort any current load unless we're navigating the current document to a new state object + if (!item->stateObject() || item->document() != m_mainFrame->document()) { + // Define what to do with any open database connections. By default we stop them and terminate the database thread. + DatabasePolicy databasePolicy = DatabasePolicyStop; #if ENABLE(DATABASE) - // If we're navigating the history via a fragment on the same document, then we do not want to stop databases. - const KURL& currentURL = m_mainFrame->loader()->url(); - const KURL& newURL = item->url(); - - if (newURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(currentURL, newURL)) - databasePolicy = DatabasePolicyContinue; + // If we're navigating the history via a fragment on the same document, then we do not want to stop databases. + const KURL& currentURL = m_mainFrame->loader()->url(); + const KURL& newURL = item->url(); + + if (newURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(currentURL, newURL)) + databasePolicy = DatabasePolicyContinue; #endif - m_mainFrame->loader()->stopAllLoaders(databasePolicy); + + m_mainFrame->loader()->stopAllLoaders(databasePolicy); + } + m_mainFrame->loader()->history()->goToItem(item, type); } @@ -542,7 +553,7 @@ void Page::userStyleSheetLocationChanged() Vector<char> styleSheetAsUTF8; if (base64Decode(encodedData, styleSheetAsUTF8)) - m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data()); + m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data(), styleSheetAsUTF8.size()); } for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) { diff --git a/WebCore/page/PageGroup.cpp b/WebCore/page/PageGroup.cpp index 427c240..558c5cb 100644 --- a/WebCore/page/PageGroup.cpp +++ b/WebCore/page/PageGroup.cpp @@ -200,29 +200,29 @@ StorageNamespace* PageGroup::localStorage() } #endif -void PageGroup::addUserScriptToWorld(unsigned worldID, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist, +void PageGroup::addUserScriptToWorld(DOMWrapperWorld* world, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist, UserScriptInjectionTime injectionTime) { - if (worldID == UINT_MAX) - return; - OwnPtr<UserScript> userScript(new UserScript(source, url, whitelist, blacklist, worldID, injectionTime)); + ASSERT_ARG(world, world); + + OwnPtr<UserScript> userScript(new UserScript(source, url, whitelist, blacklist, injectionTime)); if (!m_userScripts) m_userScripts.set(new UserScriptMap); - UserScriptVector*& scriptsInWorld = m_userScripts->add(worldID, 0).first->second; + UserScriptVector*& scriptsInWorld = m_userScripts->add(world, 0).first->second; if (!scriptsInWorld) scriptsInWorld = new UserScriptVector; scriptsInWorld->append(userScript.release()); } -void PageGroup::addUserStyleSheetToWorld(unsigned worldID, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist, +void PageGroup::addUserStyleSheetToWorld(DOMWrapperWorld* world, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist) { - if (worldID == UINT_MAX) - return; - OwnPtr<UserStyleSheet> userStyleSheet(new UserStyleSheet(source, url, whitelist, blacklist, worldID)); + ASSERT_ARG(world, world); + + OwnPtr<UserStyleSheet> userStyleSheet(new UserStyleSheet(source, url, whitelist, blacklist)); if (!m_userStyleSheets) m_userStyleSheets.set(new UserStyleSheetMap); - UserStyleSheetVector*& styleSheetsInWorld = m_userStyleSheets->add(worldID, 0).first->second; + UserStyleSheetVector*& styleSheetsInWorld = m_userStyleSheets->add(world, 0).first->second; if (!styleSheetsInWorld) styleSheetsInWorld = new UserStyleSheetVector; styleSheetsInWorld->append(userStyleSheet.release()); @@ -235,12 +235,14 @@ void PageGroup::addUserStyleSheetToWorld(unsigned worldID, const String& source, } } -void PageGroup::removeUserScriptFromWorld(unsigned worldID, const KURL& url) +void PageGroup::removeUserScriptFromWorld(DOMWrapperWorld* world, const KURL& url) { + ASSERT_ARG(world, world); + if (!m_userScripts) return; - UserScriptMap::iterator it = m_userScripts->find(worldID); + UserScriptMap::iterator it = m_userScripts->find(world); if (it == m_userScripts->end()) return; @@ -257,12 +259,14 @@ void PageGroup::removeUserScriptFromWorld(unsigned worldID, const KURL& url) m_userScripts->remove(it); } -void PageGroup::removeUserStyleSheetFromWorld(unsigned worldID, const KURL& url) +void PageGroup::removeUserStyleSheetFromWorld(DOMWrapperWorld* world, const KURL& url) { + ASSERT_ARG(world, world); + if (!m_userStyleSheets) return; - UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID); + UserStyleSheetMap::iterator it = m_userStyleSheets->find(world); bool sheetsChanged = false; if (it == m_userStyleSheets->end()) return; @@ -291,12 +295,14 @@ void PageGroup::removeUserStyleSheetFromWorld(unsigned worldID, const KURL& url) } } -void PageGroup::removeUserScriptsFromWorld(unsigned worldID) +void PageGroup::removeUserScriptsFromWorld(DOMWrapperWorld* world) { + ASSERT_ARG(world, world); + if (!m_userScripts) return; - UserScriptMap::iterator it = m_userScripts->find(worldID); + UserScriptMap::iterator it = m_userScripts->find(world); if (it == m_userScripts->end()) return; @@ -304,12 +310,14 @@ void PageGroup::removeUserScriptsFromWorld(unsigned worldID) m_userScripts->remove(it); } -void PageGroup::removeUserStyleSheetsFromWorld(unsigned worldID) +void PageGroup::removeUserStyleSheetsFromWorld(DOMWrapperWorld* world) { + ASSERT_ARG(world, world); + if (!m_userStyleSheets) return; - UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID); + UserStyleSheetMap::iterator it = m_userStyleSheets->find(world); if (it == m_userStyleSheets->end()) return; diff --git a/WebCore/page/PageGroup.h b/WebCore/page/PageGroup.h index c233cd1..446f0c7 100644 --- a/WebCore/page/PageGroup.h +++ b/WebCore/page/PageGroup.h @@ -70,17 +70,17 @@ namespace WebCore { bool hasLocalStorage() { return m_localStorage; } #endif - void addUserScriptToWorld(unsigned worldID, const String& source, const KURL&, + void addUserScriptToWorld(DOMWrapperWorld*, const String& source, const KURL&, PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist, UserScriptInjectionTime); - void addUserStyleSheetToWorld(unsigned worldID, const String& source, const KURL&, + void addUserStyleSheetToWorld(DOMWrapperWorld*, const String& source, const KURL&, PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist); - void removeUserScriptFromWorld(unsigned, const KURL&); - void removeUserStyleSheetFromWorld(unsigned, const KURL&); + void removeUserScriptFromWorld(DOMWrapperWorld*, const KURL&); + void removeUserStyleSheetFromWorld(DOMWrapperWorld*, const KURL&); - void removeUserScriptsFromWorld(unsigned); - void removeUserStyleSheetsFromWorld(unsigned); + void removeUserScriptsFromWorld(DOMWrapperWorld*); + void removeUserStyleSheetsFromWorld(DOMWrapperWorld*); void removeAllUserContent(); diff --git a/WebCore/page/PluginHalter.cpp b/WebCore/page/PluginHalter.cpp index 63f5469..c0a6452 100644 --- a/WebCore/page/PluginHalter.cpp +++ b/WebCore/page/PluginHalter.cpp @@ -28,6 +28,7 @@ #include "PluginHalter.h" #include "HaltablePlugin.h" +#include "PlatformString.h" #include <wtf/CurrentTime.h> #include <wtf/Vector.h> @@ -93,7 +94,7 @@ void PluginHalter::timerFired(Timer<PluginHalter>*) continue; } - if (m_client->shouldHaltPlugin(plugins[i]->node())) + if (m_client->shouldHaltPlugin(plugins[i]->node(), plugins[i]->isWindowed(), plugins[i]->pluginName())) plugins[i]->halt(); m_plugins.remove(plugins[i]); diff --git a/WebCore/page/PluginHalter.h b/WebCore/page/PluginHalter.h index eddce34..af8b31e 100644 --- a/WebCore/page/PluginHalter.h +++ b/WebCore/page/PluginHalter.h @@ -35,7 +35,7 @@ namespace WebCore { class HaltablePlugin; -class PluginHalter { +class PluginHalter : public Noncopyable { public: PluginHalter(PluginHalterClient*); diff --git a/WebCore/page/PluginHalterClient.h b/WebCore/page/PluginHalterClient.h index f77091f..0251547 100644 --- a/WebCore/page/PluginHalterClient.h +++ b/WebCore/page/PluginHalterClient.h @@ -29,12 +29,13 @@ namespace WebCore { class Node; +class String; class PluginHalterClient { public: virtual ~PluginHalterClient() { } - virtual bool shouldHaltPlugin(Node*) const = 0; + virtual bool shouldHaltPlugin(Node*, bool isWindowed, const String& pluginName) const = 0; virtual bool enabled() const = 0; }; diff --git a/WebCore/page/PositionError.h b/WebCore/page/PositionError.h index f6f56f0..1467170 100644 --- a/WebCore/page/PositionError.h +++ b/WebCore/page/PositionError.h @@ -35,7 +35,6 @@ namespace WebCore { class PositionError : public RefCounted<PositionError> { public: enum ErrorCode { - UNKNOWN_ERROR = 0, PERMISSION_DENIED = 1, POSITION_UNAVAILABLE = 2, TIMEOUT = 3 diff --git a/WebCore/page/PositionError.idl b/WebCore/page/PositionError.idl index cb2ef5e..91027df 100644 --- a/WebCore/page/PositionError.idl +++ b/WebCore/page/PositionError.idl @@ -31,7 +31,6 @@ module core { readonly attribute unsigned short code; readonly attribute DOMString message; - const unsigned short UNKNOWN_ERROR = 0; const unsigned short PERMISSION_DENIED = 1; const unsigned short POSITION_UNAVAILABLE = 2; const unsigned short TIMEOUT = 3; diff --git a/WebCore/page/PrintContext.cpp b/WebCore/page/PrintContext.cpp index bba678a..4d3a839 100644 --- a/WebCore/page/PrintContext.cpp +++ b/WebCore/page/PrintContext.cpp @@ -25,7 +25,6 @@ #include "Frame.h" #include "FrameView.h" #include "RenderView.h" -#include "Settings.h" using namespace WebCore; @@ -96,23 +95,18 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig void PrintContext::begin(float width) { - float PrintingMinimumShrinkFactor = m_frame->settings() ? m_frame->settings()->printingMinimumShrinkFactor() : 0.0f; - float PrintingMaximumShrinkFactor = m_frame->settings() ? m_frame->settings()->printingMaximumShrinkFactor() : 0.0f; - - if (PrintingMaximumShrinkFactor < PrintingMinimumShrinkFactor || PrintingMinimumShrinkFactor <= 0.0f) { - // 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 - // would otherwise, which is presumably why other browsers do this. - // Wide pages will be scaled down more than this. - PrintingMinimumShrinkFactor = 1.25f; - - // This number determines how small we are willing to reduce the page content - // in order to accommodate the widest line. If the page would have to be - // reduced smaller to make the widest line fit, we just clip instead (this - // behavior matches MacIE and Mozilla, at least) - PrintingMaximumShrinkFactor = 2.0f; - } + // 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 + // would otherwise, which is presumably why other browsers do this. + // Wide pages will be scaled down more than this. + const float PrintingMinimumShrinkFactor = 1.25f; + + // This number determines how small we are willing to reduce the page content + // in order to accommodate the widest line. If the page would have to be + // reduced smaller to make the widest line fit, we just clip instead (this + // behavior matches MacIE and Mozilla, at least) + const float PrintingMaximumShrinkFactor = 2.0f; float minLayoutWidth = width * PrintingMinimumShrinkFactor; float maxLayoutWidth = width * PrintingMaximumShrinkFactor; diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp index 338bf9f..f53dbf1 100644 --- a/WebCore/page/SecurityOrigin.cpp +++ b/WebCore/page/SecurityOrigin.cpp @@ -75,26 +75,11 @@ static URLSchemesMap& noAccessSchemes() return noAccessSchemes; } -bool SecurityOrigin::isDefaultPortForProtocol(unsigned short port, const String& protocol) -{ - if (protocol.isEmpty()) - return false; - - typedef HashMap<String, unsigned> DefaultPortsMap; - DEFINE_STATIC_LOCAL(DefaultPortsMap, defaultPorts, ()); - if (defaultPorts.isEmpty()) { - defaultPorts.set("http", 80); - defaultPorts.set("https", 443); - defaultPorts.set("ftp", 21); - defaultPorts.set("ftps", 990); - } - return defaultPorts.get(protocol) == port; -} - SecurityOrigin::SecurityOrigin(const KURL& url) : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower()) , m_host(url.host().isNull() ? "" : url.host().lower()) , m_port(url.port()) + , m_sandboxFlags(SandboxNone) , m_noAccess(false) , m_universalAccess(false) , m_domainWasSetInDOM(false) @@ -112,6 +97,11 @@ SecurityOrigin::SecurityOrigin(const KURL& url) // By default, only local SecurityOrigins can load local resources. m_canLoadLocalResources = isLocal(); + if (m_canLoadLocalResources) { + // Directories should never be readable. + if (!url.hasPath() || url.path().endsWith("/")) + m_noAccess = true; + } if (isDefaultPortForProtocol(m_port, m_protocol)) m_port = 0; @@ -122,6 +112,7 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) , m_host(other->m_host.threadsafeCopy()) , m_domain(other->m_domain.threadsafeCopy()) , m_port(other->m_port) + , m_sandboxFlags(other->m_sandboxFlags) , m_noAccess(other->m_noAccess) , m_universalAccess(other->m_universalAccess) , m_domainWasSetInDOM(other->m_domainWasSetInDOM) @@ -162,7 +153,7 @@ bool SecurityOrigin::canAccess(const SecurityOrigin* other) const if (m_universalAccess) return true; - if (m_noAccess || other->m_noAccess) + if (m_noAccess || other->m_noAccess || isSandboxed(SandboxOrigin) || other->isSandboxed(SandboxOrigin)) return false; // Here are two cases where we should permit access: @@ -203,10 +194,12 @@ bool SecurityOrigin::canRequest(const KURL& url) const if (m_universalAccess) return true; - if (m_noAccess) + if (m_noAccess || isSandboxed(SandboxOrigin)) return false; RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url); + if (targetOrigin->m_noAccess) + return false; // We call isSameSchemeHostPort here instead of canAccess because we want // to ignore document.domain effects. @@ -289,7 +282,7 @@ String SecurityOrigin::toString() const if (isEmpty()) return "null"; - if (m_noAccess) + if (m_noAccess || isSandboxed(SandboxOrigin)) return "null"; if (m_protocol == "file") @@ -399,14 +392,10 @@ void SecurityOrigin::removeURLSchemeRegisteredAsLocal(const String& scheme) if (scheme == "applewebdata") return; #endif -#if PLATFORM(QT) - if (scheme == "qrc") - return; -#endif localSchemes().remove(scheme); } -const URLSchemesMap& SecurityOrigin::localURLSchemes() +const URLSchemesMap& SecurityOrigin::localURLSchemes() { return localSchemes(); } diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h index 6d4ce1f..af83f02 100644 --- a/WebCore/page/SecurityOrigin.h +++ b/WebCore/page/SecurityOrigin.h @@ -34,6 +34,7 @@ #include <wtf/PassRefPtr.h> #include <wtf/Threading.h> +#include "FrameLoaderTypes.h" #include "PlatformString.h" #include "StringHash.h" @@ -110,6 +111,13 @@ namespace WebCore { // WARNING: This is an extremely powerful ability. Use with caution! void grantUniversalAccess(); + // Sandboxing status as determined by the frame. + void setSandboxFlags(SandboxFlags flags) { m_sandboxFlags = flags; } + bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; } + + bool canAccessDatabase() const { return !isSandboxed(SandboxOrigin); } + bool canAccessStorage() const { return !isSandboxed(SandboxOrigin); } + bool isSecureTransitionTo(const KURL&) const; // The local SecurityOrigin is the most privileged SecurityOrigin. @@ -123,8 +131,14 @@ namespace WebCore { // Convert this SecurityOrigin into a string. The string // representation of a SecurityOrigin is similar to a URL, except it // lacks a path component. The string representation does not encode - // the value of the SecurityOrigin's domain property. The empty - // SecurityOrigin is represented with the string "null". + // the value of the SecurityOrigin's domain property. + // + // When using the string value, it's important to remember that it + // might be "null". This happens when this SecurityOrigin has + // noAccess to other SecurityOrigins. For example, this SecurityOrigin + // might have come from a data URL, the SecurityOrigin might be empty, + // or we might have explicitly decided that we + // shouldTreatURLSchemeAsNoAccess. String toString() const; // Serialize the security origin to a string that could be used as part of @@ -165,8 +179,6 @@ namespace WebCore { static void whiteListAccessFromOrigin(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains); static void resetOriginAccessWhiteLists(); - static bool isDefaultPortForProtocol(unsigned short port, const String& protocol); - private: explicit SecurityOrigin(const KURL&); explicit SecurityOrigin(const SecurityOrigin*); @@ -175,6 +187,7 @@ namespace WebCore { String m_host; String m_domain; unsigned short m_port; + SandboxFlags m_sandboxFlags; bool m_noAccess; bool m_universalAccess; bool m_domainWasSetInDOM; diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp index 3964d74..b250e4d 100644 --- a/WebCore/page/Settings.cpp +++ b/WebCore/page/Settings.cpp @@ -75,8 +75,6 @@ Settings::Settings(Page* page) , m_maximumDecodedImageSize(numeric_limits<size_t>::max()) , m_localStorageQuota(5 * 1024 * 1024) // Suggested by the HTML5 spec. , m_pluginAllowedRunTime(numeric_limits<unsigned>::max()) - , m_printingMinimumShrinkFactor(0.0f) - , m_printingMaximumShrinkFactor(0.0f) , m_isJavaEnabled(false) , m_loadsImagesAutomatically(false) , m_privateBrowsingEnabled(false) @@ -84,7 +82,6 @@ Settings::Settings(Page* page) , m_arePluginsEnabled(false) , m_databasesEnabled(false) , m_localStorageEnabled(false) - , m_sessionStorageEnabled(true) , m_isJavaScriptEnabled(false) , m_isWebSecurityEnabled(true) , m_allowUniversalAccessFromFileURLs(true) @@ -130,8 +127,11 @@ Settings::Settings(Page* page) , m_downloadableBinaryFontsEnabled(true) , m_xssAuditorEnabled(false) , m_acceleratedCompositingEnabled(true) + , m_showDebugBorders(false) + , m_showRepaintCounter(false) , m_experimentalNotificationsEnabled(false) , m_webGLEnabled(false) + , m_geolocationEnabled(true) { // A Frame may not have been created yet, so we initialize the AtomicString // hash before trying to use it. @@ -278,11 +278,6 @@ void Settings::setLocalStorageEnabled(bool localStorageEnabled) m_localStorageEnabled = localStorageEnabled; } -void Settings::setSessionStorageEnabled(bool sessionStorageEnabled) -{ - m_sessionStorageEnabled = sessionStorageEnabled; -} - void Settings::setLocalStorageQuota(unsigned localStorageQuota) { m_localStorageQuota = localStorageQuota; @@ -703,6 +698,24 @@ void Settings::setAcceleratedCompositingEnabled(bool enabled) setNeedsReapplyStylesInAllFrames(m_page); } +void Settings::setShowDebugBorders(bool enabled) +{ + if (m_showDebugBorders == enabled) + return; + + m_showDebugBorders = enabled; + setNeedsReapplyStylesInAllFrames(m_page); +} + +void Settings::setShowRepaintCounter(bool enabled) +{ + if (m_showRepaintCounter == enabled) + return; + + m_showRepaintCounter = enabled; + setNeedsReapplyStylesInAllFrames(m_page); +} + void Settings::setExperimentalNotificationsEnabled(bool enabled) { m_experimentalNotificationsEnabled = enabled; @@ -726,14 +739,9 @@ void Settings::setWebGLEnabled(bool enabled) m_webGLEnabled = enabled; } -void Settings::setPrintingMinimumShrinkFactor(float printingMinimumShrinkFactor) -{ - m_printingMinimumShrinkFactor = printingMinimumShrinkFactor; -} - -void Settings::setPrintingMaximumShrinkFactor(float printingMaximumShrinkFactor) +void Settings::setGeolocationEnabled(bool enabled) { - m_printingMaximumShrinkFactor = printingMaximumShrinkFactor; -} + m_geolocationEnabled = enabled; +} } // namespace WebCore diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h index de1030d..fbb70b0 100644 --- a/WebCore/page/Settings.h +++ b/WebCore/page/Settings.h @@ -64,7 +64,7 @@ namespace WebCore { // if possible in the future. enum EditingBehavior { EditingMacBehavior, EditingWindowsBehavior }; - class Settings { + class Settings : public Noncopyable { public: Settings(Page*); @@ -148,9 +148,6 @@ namespace WebCore { void setLocalStorageEnabled(bool); bool localStorageEnabled() const { return m_localStorageEnabled; } - void setSessionStorageEnabled(bool); - bool sessionStorageEnabled() const { return m_sessionStorageEnabled; } - void setLocalStorageQuota(unsigned); unsigned localStorageQuota() const { return m_localStorageQuota; } @@ -317,6 +314,12 @@ namespace WebCore { void setAcceleratedCompositingEnabled(bool); bool acceleratedCompositingEnabled() const { return m_acceleratedCompositingEnabled; } + void setShowDebugBorders(bool); + bool showDebugBorders() const { return m_showDebugBorders; } + + void setShowRepaintCounter(bool); + bool showRepaintCounter() const { return m_showRepaintCounter; } + void setExperimentalNotificationsEnabled(bool); bool experimentalNotificationsEnabled() const { return m_experimentalNotificationsEnabled; } @@ -331,11 +334,8 @@ namespace WebCore { void setWebGLEnabled(bool); bool webGLEnabled() const { return m_webGLEnabled; } - void setPrintingMinimumShrinkFactor(float); - float printingMinimumShrinkFactor() const { return m_printingMinimumShrinkFactor; } - - void setPrintingMaximumShrinkFactor(float); - float printingMaximumShrinkFactor() const { return m_printingMaximumShrinkFactor; } + void setGeolocationEnabled(bool); + bool geolocationEnabled() const { return m_geolocationEnabled; } private: Page* m_page; @@ -396,8 +396,6 @@ namespace WebCore { size_t m_maximumDecodedImageSize; unsigned m_localStorageQuota; unsigned m_pluginAllowedRunTime; - float m_printingMinimumShrinkFactor; - float m_printingMaximumShrinkFactor; bool m_isJavaEnabled : 1; bool m_loadsImagesAutomatically : 1; bool m_privateBrowsingEnabled : 1; @@ -405,7 +403,6 @@ namespace WebCore { bool m_arePluginsEnabled : 1; bool m_databasesEnabled : 1; bool m_localStorageEnabled : 1; - bool m_sessionStorageEnabled : 1; bool m_isJavaScriptEnabled : 1; bool m_isWebSecurityEnabled : 1; bool m_allowUniversalAccessFromFileURLs: 1; @@ -442,8 +439,11 @@ namespace WebCore { bool m_downloadableBinaryFontsEnabled : 1; bool m_xssAuditorEnabled : 1; bool m_acceleratedCompositingEnabled : 1; + bool m_showDebugBorders : 1; + bool m_showRepaintCounter : 1; bool m_experimentalNotificationsEnabled : 1; bool m_webGLEnabled : 1; + bool m_geolocationEnabled : 1; #if USE(SAFARI_THEME) static bool gShouldPaintNativeControls; diff --git a/WebCore/page/UserScript.h b/WebCore/page/UserScript.h index dbbb879..8b3703f 100644 --- a/WebCore/page/UserScript.h +++ b/WebCore/page/UserScript.h @@ -34,16 +34,15 @@ namespace WebCore { -class UserScript { +class UserScript : public Noncopyable { public: UserScript(const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist, - unsigned worldID, UserScriptInjectionTime injectionTime) + UserScriptInjectionTime injectionTime) : m_source(source) , m_url(url) , m_whitelist(whitelist) , m_blacklist(blacklist) - , m_worldID(worldID) , m_injectionTime(injectionTime) { } @@ -52,7 +51,6 @@ public: const KURL& url() const { return m_url; } const Vector<String>* whitelist() const { return m_whitelist.get(); } const Vector<String>* blacklist() const { return m_blacklist.get(); } - unsigned worldID() const { return m_worldID; } UserScriptInjectionTime injectionTime() const { return m_injectionTime; } private: @@ -60,7 +58,6 @@ private: KURL m_url; OwnPtr<Vector<String> > m_whitelist; OwnPtr<Vector<String> > m_blacklist; - unsigned m_worldID; UserScriptInjectionTime m_injectionTime; }; diff --git a/WebCore/page/UserScriptTypes.h b/WebCore/page/UserScriptTypes.h index ac37662..ad27e79 100644 --- a/WebCore/page/UserScriptTypes.h +++ b/WebCore/page/UserScriptTypes.h @@ -33,10 +33,11 @@ namespace WebCore { enum UserScriptInjectionTime { InjectAtDocumentStart, InjectAtDocumentEnd }; +class DOMWrapperWorld; class UserScript; typedef Vector<OwnPtr<UserScript> > UserScriptVector; -typedef HashMap<unsigned, UserScriptVector*> UserScriptMap; +typedef HashMap<RefPtr<DOMWrapperWorld>, UserScriptVector*> UserScriptMap; } // namespace WebCore diff --git a/WebCore/page/UserStyleSheet.h b/WebCore/page/UserStyleSheet.h index 56bec40..610778f 100644 --- a/WebCore/page/UserStyleSheet.h +++ b/WebCore/page/UserStyleSheet.h @@ -34,16 +34,14 @@ namespace WebCore { -class UserStyleSheet { +class UserStyleSheet : public Noncopyable { public: UserStyleSheet(const String& source, const KURL& url, - PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist, - unsigned worldID) + PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist) : m_source(source) , m_url(url) , m_whitelist(whitelist) , m_blacklist(blacklist) - , m_worldID(worldID) { } @@ -51,14 +49,12 @@ public: const KURL& url() const { return m_url; } const Vector<String>* whitelist() const { return m_whitelist.get(); } const Vector<String>* blacklist() const { return m_blacklist.get(); } - unsigned worldID() const { return m_worldID; } private: String m_source; KURL m_url; OwnPtr<Vector<String> > m_whitelist; OwnPtr<Vector<String> > m_blacklist; - unsigned m_worldID; }; } // namespace WebCore diff --git a/WebCore/page/UserStyleSheetTypes.h b/WebCore/page/UserStyleSheetTypes.h index 094b2cf..ef662f2 100644 --- a/WebCore/page/UserStyleSheetTypes.h +++ b/WebCore/page/UserStyleSheetTypes.h @@ -31,10 +31,11 @@ namespace WebCore { +class DOMWrapperWorld; class UserStyleSheet; typedef Vector<OwnPtr<UserStyleSheet> > UserStyleSheetVector; -typedef HashMap<unsigned, UserStyleSheetVector*> UserStyleSheetMap; +typedef HashMap<RefPtr<DOMWrapperWorld>, UserStyleSheetVector*> UserStyleSheetMap; } // namespace WebCore diff --git a/WebCore/page/XSSAuditor.cpp b/WebCore/page/XSSAuditor.cpp index 890c3fa..72c2591 100644 --- a/WebCore/page/XSSAuditor.cpp +++ b/WebCore/page/XSSAuditor.cpp @@ -144,14 +144,7 @@ bool XSSAuditor::canLoadExternalScriptFromSrc(const String& context, const Strin if (!isEnabled()) return true; - // If the script is loaded from the same URL as the enclosing page, it's - // probably not an XSS attack, so we reduce false positives by allowing the - // script. If the script has a query string, we're more suspicious, - // however, because that's pretty rare and the attacker might be able to - // trick a server-side script into doing something dangerous with the query - // string. - KURL scriptURL(m_frame->document()->url(), url); - if (m_frame->document()->url().host() == scriptURL.host() && scriptURL.query().isEmpty()) + if (isSameOriginResource(url)) return true; if (findInRequest(context + url)) { @@ -167,8 +160,11 @@ bool XSSAuditor::canLoadObject(const String& url) const if (!isEnabled()) return true; + if (isSameOriginResource(url)) + return true; + if (findInRequest(url)) { - DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request")); + String consoleMessage = String::format("Refused to load an object. URL found within request: \"%s\".\n", url.utf8().data()); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; } @@ -179,10 +175,12 @@ bool XSSAuditor::canSetBaseElementURL(const String& url) const { if (!isEnabled()) return true; - - KURL baseElementURL(m_frame->document()->url(), url); - if (m_frame->document()->url().host() != baseElementURL.host() && findInRequest(url)) { - DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request")); + + if (isSameOriginResource(url)) + return true; + + if (findInRequest(url)) { + DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to load from document base URL. URL found within request.\n")); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; } @@ -255,6 +253,18 @@ String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodabl return String::adopt(result); } +bool XSSAuditor::isSameOriginResource(const String& url) const +{ + // If the resource is loaded from the same URL as the enclosing page, it's + // probably not an XSS attack, so we reduce false positives by allowing the + // request. If the resource has a query string, we're more suspicious, + // however, because that's pretty rare and the attacker might be able to + // trick a server-side script into doing something dangerous with the query + // string. + KURL resourceURL(m_frame->document()->url(), url); + return (m_frame->document()->url().host() == resourceURL.host() && resourceURL.query().isEmpty()); +} + bool XSSAuditor::findInRequest(const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, bool decodeURLEscapeSequencesTwice) const { diff --git a/WebCore/page/XSSAuditor.h b/WebCore/page/XSSAuditor.h index adfa5c7..b64665b 100644 --- a/WebCore/page/XSSAuditor.h +++ b/WebCore/page/XSSAuditor.h @@ -42,14 +42,14 @@ namespace WebCore { // a script is to be allowed or denied based on the content of any // user-submitted data, including: // - // * the query string of the URL. + // * the URL. // * the HTTP-POST data. // // If the source code of a script resembles any user-submitted data then it // is denied execution. // - // When you instantiate the XSSAuditor you must specify the {@link Frame} - // of the page that you wish to audit. + // When you instantiate the XSSAuditor you must specify the Frame of the + // page that you wish to audit. // // Bindings // @@ -59,11 +59,14 @@ namespace WebCore { // JavaScript script is safe to execute before executing it. The following // methods call into XSSAuditor: // - // * ScriptController::evaluate - used to evaluate JavaScript scripts. - // * ScriptController::createInlineEventListener - used to create JavaScript event handlers. - // * HTMLTokenizer::scriptHandler - used to load external JavaScript scripts. + // * ScriptController::evaluateInWorld - used to evaluate JavaScript scripts. + // * ScriptController::executeIfJavaScriptURL - used to evaluate JavaScript URLs. + // * ScriptEventListener::createAttributeEventListener - used to create JavaScript event handlers. + // * HTMLBaseElement::process - used to set the document base URL. + // * HTMLTokenizer::parseTag - used to load external JavaScript scripts. + // * FrameLoader::requestObject - used to load <object>/<embed> elements. // - class XSSAuditor { + class XSSAuditor : public Noncopyable { public: XSSAuditor(Frame*); ~XSSAuditor(); @@ -122,6 +125,7 @@ namespace WebCore { bool decodeURLEscapeSequencesTwice = false); static String decodeHTMLEntities(const String&, bool leaveUndecodableEntitiesUntouched = true); + bool isSameOriginResource(const String& url) const; bool findInRequest(const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, bool decodeURLEscapeSequencesTwice = false) const; bool findInRequest(Frame*, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp index 59797da..f1ee750 100644 --- a/WebCore/page/animation/AnimationBase.cpp +++ b/WebCore/page/animation/AnimationBase.cpp @@ -190,7 +190,7 @@ class PropertyWrapperBase; static void addShorthandProperties(); static PropertyWrapperBase* wrapperForProperty(int propertyID); -class PropertyWrapperBase { +class PropertyWrapperBase : public Noncopyable { public: PropertyWrapperBase(int prop) : m_prop(prop) diff --git a/WebCore/page/animation/KeyframeAnimation.cpp b/WebCore/page/animation/KeyframeAnimation.cpp index 7e37e5f..500bf6f 100644 --- a/WebCore/page/animation/KeyframeAnimation.cpp +++ b/WebCore/page/animation/KeyframeAnimation.cpp @@ -36,6 +36,7 @@ #include "EventNames.h" #include "RenderLayer.h" #include "RenderLayerBacking.h" +#include "RenderStyle.h" #include <wtf/UnusedParam.h> namespace WebCore { diff --git a/WebCore/page/animation/KeyframeAnimation.h b/WebCore/page/animation/KeyframeAnimation.h index 4905fc3..e3b8f53 100644 --- a/WebCore/page/animation/KeyframeAnimation.h +++ b/WebCore/page/animation/KeyframeAnimation.h @@ -32,10 +32,11 @@ #include "AnimationBase.h" #include "Document.h" #include "KeyframeList.h" -#include "RenderStyle.h" namespace WebCore { +class RenderStyle; + // A KeyframeAnimation tracks the state of an explicit animation // for a single RenderObject. class KeyframeAnimation : public AnimationBase { diff --git a/WebCore/page/chromium/EventHandlerChromium.cpp b/WebCore/page/chromium/EventHandlerChromium.cpp index 467f94e..ac76a29 100644 --- a/WebCore/page/chromium/EventHandlerChromium.cpp +++ b/WebCore/page/chromium/EventHandlerChromium.cpp @@ -154,4 +154,14 @@ unsigned EventHandler::accessKeyModifiers() #endif } +#if PLATFORM(LINUX) +// GTK+ must scroll horizontally if the mouse pointer is on top of the +// horizontal scrollbar while scrolling with the wheel. +// This code comes from gtk/EventHandlerGtk.cpp. +bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult& result) const +{ + return result.scrollbar() && result.scrollbar()->orientation() == HorizontalScrollbar; +} +#endif + } // namespace WebCore diff --git a/WebCore/page/mac/ChromeMac.mm b/WebCore/page/mac/ChromeMac.mm index aba3449..14c07de 100644 --- a/WebCore/page/mac/ChromeMac.mm +++ b/WebCore/page/mac/ChromeMac.mm @@ -25,6 +25,8 @@ namespace WebCore { +#if !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) + void Chrome::focusNSView(NSView* view) { BEGIN_BLOCK_OBJC_EXCEPTIONS; @@ -48,4 +50,6 @@ void Chrome::focusNSView(NSView* view) END_BLOCK_OBJC_EXCEPTIONS; } +#endif + } // namespace WebCore diff --git a/WebCore/page/mac/DragControllerMac.mm b/WebCore/page/mac/DragControllerMac.mm index 8a04809..adf89fa 100644 --- a/WebCore/page/mac/DragControllerMac.mm +++ b/WebCore/page/mac/DragControllerMac.mm @@ -42,6 +42,15 @@ const int DragController::DragIconBottomInset = 3; const float DragController::DragImageAlpha = 0.75f; +#if ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) + +DragOperation DragController::dragOperation(DragData*) +{ + return DragOperationNone; +} + +#else + bool DragController::isCopyKeyDown() { return [[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask; @@ -58,7 +67,9 @@ DragOperation DragController::dragOperation(DragData* dragData) return DragOperationCopy; return DragOperationNone; -} +} + +#endif const IntSize& DragController::maxDragImageSize() { diff --git a/WebCore/page/mac/EventHandlerMac.mm b/WebCore/page/mac/EventHandlerMac.mm index 7da1d36..92895d9 100644 --- a/WebCore/page/mac/EventHandlerMac.mm +++ b/WebCore/page/mac/EventHandlerMac.mm @@ -64,6 +64,8 @@ namespace WebCore { const double EventHandler::TextDragDelay = 0.15; #endif +#if !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) + static RetainPtr<NSEvent>& currentNSEventSlot() { DEFINE_STATIC_LOCAL(RetainPtr<NSEvent>, event, ()); @@ -136,65 +138,6 @@ PassRefPtr<KeyboardEvent> EventHandler::currentKeyboardEvent() const } } -static inline 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 -{ - Page* page = m_frame->page(); - if (!page) - return false; - - KeyboardUIMode keyboardUIMode = page->chrome()->client()->keyboardUIMode(); - bool handlingOptionTab = isKeyboardOptionTab(event); - - // If tab-to-links is off, option-tab always highlights all controls - if ((keyboardUIMode & KeyboardAccessTabsToLinks) == 0 && handlingOptionTab) - return true; - - // If system preferences say to include all controls, we always include all controls - if (keyboardUIMode & KeyboardAccessFull) - return true; - - // Otherwise tab-to-links includes all controls, unless the sense is flipped via option-tab. - if (keyboardUIMode & KeyboardAccessTabsToLinks) - return !handlingOptionTab; - - return handlingOptionTab; -} - -bool EventHandler::needsKeyboardEventDisambiguationQuirks() const -{ - Document* document = m_frame->document(); - - // RSS view needs arrow key keypress events. - if (applicationIsSafari() && document->url().protocolIs("feed") || document->url().protocolIs("feeds")) - return true; - Settings* settings = m_frame->settings(); - if (!settings) - return false; - -#if ENABLE(DASHBOARD_SUPPORT) - if (settings->usesDashboardBackwardCompatibilityMode()) - return true; -#endif - - if (settings->needsKeyboardEventDisambiguationQuirks()) - return true; - - return false; -} - bool EventHandler::keyEvent(NSEvent *event) { BEGIN_BLOCK_OBJC_EXCEPTIONS; @@ -369,11 +312,6 @@ NSView *EventHandler::mouseDownViewIfStillGood() return mouseDownView; } -bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const -{ - return m_activationEventNumber == event.eventNumber(); -} - #if ENABLE(DRAG_SUPPORT) bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&) { @@ -393,15 +331,6 @@ bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResult return true; } - -PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const -{ - NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; - // Must be done before ondragstart adds types and data to the pboard, - // also done for security, as it erases data from the last drag - [pasteboard declareTypes:[NSArray array] owner:nil]; - return ClipboardMac::create(true, pasteboard, ClipboardWritable, m_frame); -} #endif // ENABLE(DRAG_SUPPORT) bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&) @@ -697,17 +626,6 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& return passSubframeEventToSubframe(mev, subframe); } -unsigned EventHandler::accessKeyModifiers() -{ - // Control+Option key combinations are usually unused on Mac OS X, but not when VoiceOver is enabled. - // So, we use Control in this case, even though it conflicts with Emacs-style key bindings. - // See <https://bugs.webkit.org/show_bug.cgi?id=21107> for more detail. - if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled()) - return PlatformKeyboardEvent::CtrlKey; - - return PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey; -} - PlatformMouseEvent EventHandler::currentPlatformMouseEvent() const { NSView *windowView = nil; @@ -736,4 +654,144 @@ bool EventHandler::eventMayStartDrag(NSEvent *event) } #endif // ENABLE(DRAG_SUPPORT) +bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const +{ + return m_activationEventNumber == event.eventNumber(); +} + +#else // ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) + +bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) +{ + subframe->eventHandler()->handleMousePressEvent(mev.event()); + return true; +} + +bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode) +{ + if (m_mouseDownMayStartDrag && !m_mouseDownWasInSubframe) + return false; + subframe->eventHandler()->handleMouseMoveEvent(mev.event(), hoveredNode); + return true; +} + +bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) +{ + subframe->eventHandler()->handleMouseReleaseEvent(mev.event()); + return true; +} + +bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& wheelEvent, Widget* widget) +{ + if (!widget->isFrameView()) + return false; + + return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(wheelEvent); +} + +void EventHandler::focusDocumentView() +{ + Page* page = m_frame->page(); + if (!page) + return; + page->focusController()->setFocusedFrame(m_frame); +} + +bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&) +{ + notImplemented(); + return false; +} + +bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const +{ + notImplemented(); + return false; +} + +#endif + +#if ENABLE(DRAG_SUPPORT) + +PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const +{ + NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard]; + // Must be done before ondragstart adds types and data to the pboard, + // also done for security, as it erases data from the last drag + [pasteboard declareTypes:[NSArray array] owner:nil]; + return ClipboardMac::create(true, pasteboard, ClipboardWritable, m_frame); +} + +#endif + +static inline 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 +{ + Page* page = m_frame->page(); + if (!page) + return false; + + KeyboardUIMode keyboardUIMode = page->chrome()->client()->keyboardUIMode(); + bool handlingOptionTab = isKeyboardOptionTab(event); + + // If tab-to-links is off, option-tab always highlights all controls + if ((keyboardUIMode & KeyboardAccessTabsToLinks) == 0 && handlingOptionTab) + return true; + + // If system preferences say to include all controls, we always include all controls + if (keyboardUIMode & KeyboardAccessFull) + return true; + + // Otherwise tab-to-links includes all controls, unless the sense is flipped via option-tab. + if (keyboardUIMode & KeyboardAccessTabsToLinks) + return !handlingOptionTab; + + return handlingOptionTab; +} + +bool EventHandler::needsKeyboardEventDisambiguationQuirks() const +{ + Document* document = m_frame->document(); + + // RSS view needs arrow key keypress events. + if (applicationIsSafari() && document->url().protocolIs("feed") || document->url().protocolIs("feeds")) + return true; + Settings* settings = m_frame->settings(); + if (!settings) + return false; + +#if ENABLE(DASHBOARD_SUPPORT) + if (settings->usesDashboardBackwardCompatibilityMode()) + return true; +#endif + + if (settings->needsKeyboardEventDisambiguationQuirks()) + return true; + + return false; +} + +unsigned EventHandler::accessKeyModifiers() +{ + // Control+Option key combinations are usually unused on Mac OS X, but not when VoiceOver is enabled. + // So, we use Control in this case, even though it conflicts with Emacs-style key bindings. + // See <https://bugs.webkit.org/show_bug.cgi?id=21107> for more detail. + if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled()) + return PlatformKeyboardEvent::CtrlKey; + + return PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey; +} + } diff --git a/WebCore/page/mac/FrameMac.mm b/WebCore/page/mac/FrameMac.mm index d9faa8b..fce5704 100644 --- a/WebCore/page/mac/FrameMac.mm +++ b/WebCore/page/mac/FrameMac.mm @@ -271,7 +271,9 @@ NSImage* Frame::imageFromRect(NSRect rect) const if (![view respondsToSelector:@selector(drawSingleRect:)]) return nil; - NSImage* resultImage; + PaintBehavior oldPaintBehavior = m_view->paintBehavior(); + m_view->setPaintBehavior(oldPaintBehavior | PaintBehaviorFlattenCompositingLayers); + BEGIN_BLOCK_OBJC_EXCEPTIONS; NSRect bounds = [view bounds]; @@ -282,7 +284,7 @@ NSImage* Frame::imageFromRect(NSRect rect) const rect.size.width = roundf(rect.size.width); rect = [view convertRect:rect fromView:nil]; - resultImage = [[[NSImage alloc] initWithSize:rect.size] autorelease]; + NSImage* resultImage = [[[NSImage alloc] initWithSize:rect.size] autorelease]; if (rect.size.width != 0 && rect.size.height != 0) { [resultImage setFlipped:YES]; @@ -301,19 +303,21 @@ NSImage* Frame::imageFromRect(NSRect rect) const [resultImage setFlipped:NO]; } + m_view->setPaintBehavior(oldPaintBehavior); return resultImage; END_BLOCK_OBJC_EXCEPTIONS; + m_view->setPaintBehavior(oldPaintBehavior); return nil; } NSImage* Frame::selectionImage(bool forceBlackText) const { - m_view->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly); + m_view->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0)); m_doc->updateLayout(); NSImage* result = imageFromRect(selectionBounds()); - m_view->setPaintRestriction(PaintRestrictionNone); + m_view->setPaintBehavior(PaintBehaviorNormal); return result; } @@ -459,33 +463,6 @@ NSWritingDirection Frame::baseWritingDirectionForSelectionStart() const return result; } -const short enableRomanKeyboardsOnly = -23; -void Frame::setUseSecureKeyboardEntry(bool enable) -{ - 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 - } -} - #if ENABLE(DASHBOARD_SUPPORT) NSMutableDictionary* Frame::dashboardRegionsDictionary() { diff --git a/WebCore/page/mac/WebCoreViewFactory.h b/WebCore/page/mac/WebCoreViewFactory.h index 249d696..43f3f0a 100644 --- a/WebCore/page/mac/WebCoreViewFactory.h +++ b/WebCore/page/mac/WebCoreViewFactory.h @@ -150,6 +150,13 @@ - (NSString*)localizedMediaControlElementHelpText:(NSString*)name; - (NSString*)localizedMediaTimeDescription:(float)time; +- (NSString *)validationMessageValueMissingText; +- (NSString *)validationMessageTypeMismatchText; +- (NSString *)validationMessagePatternMismatchText; +- (NSString *)validationMessageTooLongText; +- (NSString *)validationMessageRangeUnderflowText; +- (NSString *)validationMessageRangeOverflowText; +- (NSString *)validationMessageStepMismatchText; @end diff --git a/WebCore/page/win/FrameCGWin.cpp b/WebCore/page/win/FrameCGWin.cpp index 7483627..d9e577b 100644 --- a/WebCore/page/win/FrameCGWin.cpp +++ b/WebCore/page/win/FrameCGWin.cpp @@ -52,6 +52,9 @@ static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext* static HBITMAP imageFromRect(const Frame* frame, IntRect& ir) { + PaintBehavior oldPaintBehavior = frame->view()->paintBehavior(); + frame->view()->setPaintBehavior(oldPaintBehavior | PaintBehaviorFlattenCompositingLayers); + void* bits; HDC hdc = CreateCompatibleDC(0); int w = ir.width(); @@ -74,6 +77,8 @@ static HBITMAP imageFromRect(const Frame* frame, IntRect& ir) SelectObject(hdc, hbmpOld); DeleteDC(hdc); + frame->view()->setPaintBehavior(oldPaintBehavior); + return hbmp; } @@ -81,12 +86,12 @@ HBITMAP imageFromSelection(Frame* frame, bool forceBlackText) { frame->document()->updateLayout(); - frame->view()->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly); + frame->view()->setPaintBehavior(PaintBehaviorSelectionOnly | (forceBlackText ? PaintBehaviorForceBlackText : 0)); FloatRect fr = frame->selectionBounds(); IntRect ir(static_cast<int>(fr.x()), static_cast<int>(fr.y()), static_cast<int>(fr.width()), static_cast<int>(fr.height())); HBITMAP image = imageFromRect(frame, ir); - frame->view()->setPaintRestriction(PaintRestrictionNone); + frame->view()->setPaintBehavior(PaintBehaviorNormal); return image; } |