diff options
Diffstat (limited to 'WebCore/page')
34 files changed, 296 insertions, 262 deletions
diff --git a/WebCore/page/AbstractView.idl b/WebCore/page/AbstractView.idl index 290bf48..e4ece0f 100644 --- a/WebCore/page/AbstractView.idl +++ b/WebCore/page/AbstractView.idl @@ -32,7 +32,7 @@ module views { OmitConstructor ] AbstractView { readonly attribute Document document; - readonly attribute Media media; + readonly attribute Media styleMedia; }; } diff --git a/WebCore/page/Chrome.cpp b/WebCore/page/Chrome.cpp index 841908d..799aaee 100644 --- a/WebCore/page/Chrome.cpp +++ b/WebCore/page/Chrome.cpp @@ -107,9 +107,10 @@ void Chrome::contentsSizeChanged(Frame* frame, const IntSize& size) const m_client->contentsSizeChanged(frame, size); } -void Chrome::scrollRectIntoView(const IntRect& rect, const ScrollView* scrollView) const +void Chrome::scrollRectIntoView(const IntRect& rect) const { - m_client->scrollRectIntoView(rect, scrollView); + // FIXME: The unused ScrollView* argument can and should be removed from ChromeClient::scrollRectIntoView. + m_client->scrollRectIntoView(rect, 0); } void Chrome::scrollbarsModeDidChange() const diff --git a/WebCore/page/Chrome.h b/WebCore/page/Chrome.h index 658404a..3882f5e 100644 --- a/WebCore/page/Chrome.h +++ b/WebCore/page/Chrome.h @@ -68,9 +68,10 @@ namespace WebCore { virtual IntPoint screenToWindow(const IntPoint&) const; virtual IntRect windowToScreen(const IntRect&) const; virtual PlatformPageClient platformPageClient() const; - virtual void scrollRectIntoView(const IntRect&, const ScrollView*) const; virtual void scrollbarsModeDidChange() const; + void scrollRectIntoView(const IntRect&) const; + void contentsSizeChanged(Frame*, const IntSize&) const; void setWindowRect(const FloatRect&) const; diff --git a/WebCore/page/Console.cpp b/WebCore/page/Console.cpp index d5ff7bc..864b834 100644 --- a/WebCore/page/Console.cpp +++ b/WebCore/page/Console.cpp @@ -289,6 +289,7 @@ void Console::markTimeline(ScriptCallStack* callStack) #if ENABLE(WML) String Console::lastWMLErrorMessage() const { +#if ENABLE(INSPECTOR) Page* page = this->page(); if (!page) return String(); @@ -307,7 +308,7 @@ String Console::lastWMLErrorMessage() const return message->message(); } - +#endif return String(); } #endif diff --git a/WebCore/page/DOMWindow.cpp b/WebCore/page/DOMWindow.cpp index c74cfaf..633feb6 100644 --- a/WebCore/page/DOMWindow.cpp +++ b/WebCore/page/DOMWindow.cpp @@ -58,7 +58,7 @@ #include "InspectorController.h" #include "InspectorTimelineAgent.h" #include "Location.h" -#include "Media.h" +#include "StyleMedia.h" #include "MessageEvent.h" #include "Navigator.h" #include "NotificationCenter.h" @@ -575,7 +575,7 @@ Location* DOMWindow::location() const } #if ENABLE(DOM_STORAGE) -Storage* DOMWindow::sessionStorage() const +Storage* DOMWindow::sessionStorage(ExceptionCode& ec) const { if (m_sessionStorage) return m_sessionStorage.get(); @@ -584,6 +584,11 @@ Storage* DOMWindow::sessionStorage() const if (!document) return 0; + if (!document->securityOrigin()->canAccessLocalStorage()) { + ec = SECURITY_ERR; + return 0; + } + Page* page = document->page(); if (!page) return 0; @@ -601,16 +606,16 @@ Storage* DOMWindow::localStorage(ExceptionCode& ec) const { if (m_localStorage) return m_localStorage.get(); - + Document* document = this->document(); if (!document) return 0; - + if (!document->securityOrigin()->canAccessLocalStorage()) { ec = SECURITY_ERR; return 0; } - + Page* page = document->page(); if (!page) return 0; @@ -1136,10 +1141,10 @@ Document* DOMWindow::document() const return m_frame->document(); } -PassRefPtr<Media> DOMWindow::media() const +PassRefPtr<StyleMedia> DOMWindow::styleMedia() const { if (!m_media) - m_media = Media::create(m_frame); + m_media = StyleMedia::create(m_frame); return m_media.get(); } diff --git a/WebCore/page/DOMWindow.h b/WebCore/page/DOMWindow.h index c3a781c..e4aa4cb 100644 --- a/WebCore/page/DOMWindow.h +++ b/WebCore/page/DOMWindow.h @@ -56,7 +56,7 @@ namespace WebCore { class IndexedDatabaseRequest; class InspectorTimelineAgent; class Location; - class Media; + class StyleMedia; class Navigator; class Node; class NotificationCenter; @@ -187,7 +187,7 @@ namespace WebCore { // DOM Level 2 AbstractView Interface Document* document() const; // CSSOM View Module - PassRefPtr<Media> media() const; + PassRefPtr<StyleMedia> styleMedia() const; // DOM Level 2 Style Interface PassRefPtr<CSSStyleDeclaration> getComputedStyle(Element*, const String& pseudoElt) const; @@ -206,7 +206,7 @@ namespace WebCore { #if ENABLE(DOM_STORAGE) // HTML 5 key/value storage - Storage* sessionStorage() const; + Storage* sessionStorage(ExceptionCode&) const; Storage* localStorage(ExceptionCode&) const; #endif @@ -353,7 +353,7 @@ namespace WebCore { Console* optionalConsole() const { return m_console.get(); } Navigator* optionalNavigator() const { return m_navigator.get(); } Location* optionalLocation() const { return m_location.get(); } - Media* optionalMedia() const { return m_media.get(); } + StyleMedia* optionalMedia() const { return m_media.get(); } #if ENABLE(DOM_STORAGE) Storage* optionalSessionStorage() const { return m_sessionStorage.get(); } Storage* optionalLocalStorage() const { return m_localStorage.get(); } @@ -390,7 +390,7 @@ namespace WebCore { mutable RefPtr<Console> m_console; mutable RefPtr<Navigator> m_navigator; mutable RefPtr<Location> m_location; - mutable RefPtr<Media> m_media; + mutable RefPtr<StyleMedia> m_media; #if ENABLE(DOM_STORAGE) mutable RefPtr<Storage> m_sessionStorage; mutable RefPtr<Storage> m_localStorage; diff --git a/WebCore/page/DOMWindow.idl b/WebCore/page/DOMWindow.idl index 018b4de..a1ce419 100644 --- a/WebCore/page/DOMWindow.idl +++ b/WebCore/page/DOMWindow.idl @@ -141,7 +141,7 @@ module window { readonly attribute Document document; // CSSOM View Module - readonly attribute Media media; + readonly attribute StyleMedia styleMedia; // DOM Level 2 Style Interface CSSStyleDeclaration getComputedStyle(in Element element, @@ -164,7 +164,8 @@ module window { raises(DOMException); #endif #if defined(ENABLE_DOM_STORAGE) && ENABLE_DOM_STORAGE - readonly attribute [EnabledAtRuntime] Storage sessionStorage; + readonly attribute [EnabledAtRuntime] Storage sessionStorage + getter raises(DOMException); readonly attribute [EnabledAtRuntime] Storage localStorage getter raises(DOMException); #endif @@ -294,10 +295,10 @@ module window { #if defined(ENABLE_ORIENTATION_EVENTS) && ENABLE_ORIENTATION_EVENTS attribute EventListener onorientationchange; #endif - attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchstart; - attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchmove; - attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchend; - attribute [DontEnum,Conditional=TOUCH_EVENTS] EventListener ontouchcancel; + attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchstart; + attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchmove; + attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchend; + attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchcancel; // EventTarget interface [Custom] void addEventListener(in DOMString type, @@ -715,6 +716,8 @@ module window { attribute DOMFormDataConstructor FormData; + attribute [Conditional=FILE_READER|FILE_WRITER] FileErrorConstructor FileError; + #endif // defined(LANGUAGE_JAVASCRIPT) #if defined(V8_BINDING) && V8_BINDING diff --git a/WebCore/page/DragController.cpp b/WebCore/page/DragController.cpp index f238b27..c603996 100644 --- a/WebCore/page/DragController.cpp +++ b/WebCore/page/DragController.cpp @@ -115,8 +115,15 @@ static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragD if (!url.isEmpty()) { RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(document); anchor->setHref(url); - ExceptionCode ec; + if (title.isEmpty()) { + // Try the plain text first because the url might be normalized or escaped. + if (dragData->containsPlainText()) + title = dragData->asPlainText(); + if (title.isEmpty()) + title = url; + } RefPtr<Node> anchorText = document->createTextNode(title); + ExceptionCode ec; anchor->appendChild(anchorText, ec); RefPtr<DocumentFragment> fragment = document->createDocumentFragment(); fragment->appendChild(anchor, ec); @@ -313,7 +320,7 @@ bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction a } IntPoint point = frameView->windowToContents(dragData->clientPosition()); - Element* element = elementUnderMouse(m_documentUnderMouse, point); + Element* element = elementUnderMouse(m_documentUnderMouse.get(), point); if (!asFileInput(element)) { VisibleSelection dragCaret = m_documentUnderMouse->frame()->visiblePositionForPoint(point); m_page->dragCaretController()->setSelection(dragCaret); @@ -363,7 +370,7 @@ bool DragController::concludeEditDrag(DragData* dragData) return false; IntPoint point = m_documentUnderMouse->view()->windowToContents(dragData->clientPosition()); - Element* element = elementUnderMouse(m_documentUnderMouse, point); + Element* element = elementUnderMouse(m_documentUnderMouse.get(), point); Frame* innerFrame = element->ownerDocument()->frame(); ASSERT(innerFrame); @@ -439,7 +446,7 @@ bool DragController::concludeEditDrag(DragData* dragData) applyCommand(MoveSelectionCommand::create(fragment, dragCaret.base(), smartInsert, smartDelete)); } else { if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) - applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse, fragment, true, dragData->canSmartReplace(), chosePlainText)); + applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse.get(), fragment, true, dragData->canSmartReplace(), chosePlainText)); } } else { String text = dragData->asPlainText(); @@ -450,7 +457,7 @@ bool DragController::concludeEditDrag(DragData* dragData) m_client->willPerformDragDestinationAction(DragDestinationActionEdit, dragData); if (setSelectionToDragCaret(innerFrame, dragCaret, range, point)) - applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse, createFragmentFromText(range.get(), text), true, false, true)); + applyCommand(ReplaceSelectionCommand::create(m_documentUnderMouse.get(), createFragmentFromText(range.get(), text), true, false, true)); } loader->setAllowStaleResources(false); diff --git a/WebCore/page/DragController.h b/WebCore/page/DragController.h index 3b2b083..712f9ab 100644 --- a/WebCore/page/DragController.h +++ b/WebCore/page/DragController.h @@ -67,13 +67,11 @@ namespace WebCore { DragOperation sourceDragOperation() const { return m_sourceDragOperation; } void setDraggingImageURL(const KURL& url) { m_draggingImageURL = url; } const KURL& draggingImageURL() const { return m_draggingImageURL; } - void setDragInitiator(Document* initiator) { m_dragInitiator = initiator; m_didInitiateDrag = true; } - Document* dragInitiator() const { return m_dragInitiator; } void setDragOffset(const IntPoint& offset) { m_dragOffset = offset; } const IntPoint& dragOffset() const { return m_dragOffset; } DragSourceAction dragSourceAction() const { return m_dragSourceAction; } - Document* documentUnderMouse() const { return m_documentUnderMouse; } + Document* documentUnderMouse() const { return m_documentUnderMouse.get(); } DragDestinationAction dragDestinationAction() const { return m_dragDestinationAction; } DragSourceAction delegateDragSourceAction(const IntPoint& pagePoint); @@ -114,8 +112,8 @@ namespace WebCore { Page* m_page; DragClient* m_client; - Document* m_documentUnderMouse; // The document the mouse was last dragged over. - Document* m_dragInitiator; // The Document (if any) that initiated the drag. + RefPtr<Document> m_documentUnderMouse; // The document the mouse was last dragged over. + RefPtr<Document> m_dragInitiator; // The Document (if any) that initiated the drag. DragDestinationAction m_dragDestinationAction; DragSourceAction m_dragSourceAction; diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index d775e89..8f63144 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -69,6 +69,7 @@ #include "SelectionController.h" #include "Settings.h" #include "TextEvent.h" +#include "TextIterator.h" #include "UserGestureIndicator.h" #include "WheelEvent.h" #include "htmlediting.h" // for comparePositions() @@ -145,7 +146,7 @@ static inline bool scrollNode(float delta, WheelEvent::Granularity granularity, return false; } -#if !PLATFORM(MAC) || ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) +#if !PLATFORM(MAC) inline bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&) { @@ -190,7 +191,7 @@ EventHandler::EventHandler(Frame* frame) , m_mouseDownTimestamp(0) , m_useLatchedWheelEventNode(false) , m_widgetIsLatched(false) -#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) +#if PLATFORM(MAC) , m_mouseDownView(nil) , m_sendingEventToSubview(false) , m_activationEventNumber(0) @@ -339,6 +340,12 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR return true; } +static int textDistance(const Position& start, const Position& end) +{ + RefPtr<Range> range = Range::create(start.node()->document(), start, end); + return TextIterator::rangeLength(range.get(), true); +} + bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event) { Node* innerNode = event.targetNode(); @@ -369,14 +376,21 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR if (extendSelection && newSelection.isCaretOrRange()) { m_frame->selection()->setIsDirectional(false); - // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection - // was created right-to-left - Position start = newSelection.start(); - Position end = newSelection.end(); - if (comparePositions(pos, start) <= 0) - newSelection = VisibleSelection(pos, end); - else - newSelection = VisibleSelection(start, pos); + ASSERT(m_frame->settings()); + if (m_frame->settings()->editingBehavior() == EditingMacBehavior) { + // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection + // was created right-to-left + Position start = newSelection.start(); + Position end = newSelection.end(); + int distanceToStart = textDistance(start, pos); + int distanceToEnd = textDistance(pos, end); + if (distanceToStart <= distanceToEnd) + newSelection = VisibleSelection(end, pos); + else + newSelection = VisibleSelection(start, pos); + } else { + newSelection.setExtent(pos); + } if (m_frame->selectionGranularity() != CharacterGranularity) { granularity = m_frame->selectionGranularity(); @@ -449,7 +463,6 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve #endif bool swallowEvent = false; - m_frame->selection()->setCaretBlinkingSuspended(true); m_mousePressed = true; m_beganSelectingText = false; @@ -466,6 +479,30 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve return swallowEvent; } +// There are two kinds of renderer that can autoscroll. +static bool canAutoscroll(RenderObject* renderer) +{ + if (!renderer->isBox()) + return false; + + // Check for a box that can be scrolled in its own right. + if (toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) + return true; + + // Check for a box that represents the top level of a web page. + // This can be scrolled by calling Chrome::scrollRectIntoView. + // This only has an effect on the Mac platform in applications + // that put web views into scrolling containers, such as Mac OS X Mail. + // The code for this is in RenderLayer::scrollRectToVisible. + if (renderer->node() != renderer->document()) + return false; + Frame* frame = renderer->document()->frame(); + if (!frame) + return false; + Page* page = frame->page(); + return page && page->mainFrame() == frame; +} + #if ENABLE(DRAG_SUPPORT) bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event) { @@ -486,10 +523,9 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e m_mouseDownMayStartDrag = false; if (m_mouseDownMayStartAutoscroll && !m_panScrollInProgress) { - // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll - // Otherwise, let the bridge handle it so the view can scroll itself. + // Find a renderer that can autoscroll. RenderObject* renderer = targetNode->renderer(); - while (renderer && (!renderer->isBox() || !toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())) { + while (renderer && !canAutoscroll(renderer)) { if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement()) renderer = renderer->document()->ownerElement()->renderer(); else @@ -607,7 +643,12 @@ void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint& } } #endif // ENABLE(DRAG_SUPPORT) - + +void EventHandler::lostMouseCapture() +{ + m_frame->selection()->setCaretBlinkingSuspended(false); +} + bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event) { if (eventLoopHandleMouseUp(event)) @@ -792,7 +833,7 @@ void EventHandler::updateAutoscrollRenderer() if (Node* nodeAtPoint = hitTest.innerNode()) m_autoscrollRenderer = nodeAtPoint->renderer(); - while (m_autoscrollRenderer && (!m_autoscrollRenderer->isBox() || !toRenderBox(m_autoscrollRenderer)->canBeScrolledAndHasScrollableArea())) + while (m_autoscrollRenderer && !canAutoscroll(m_autoscrollRenderer)) m_autoscrollRenderer = m_autoscrollRenderer->parent(); } @@ -1256,6 +1297,8 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent) } } + m_frame->selection()->setCaretBlinkingSuspended(true); + bool swallowEvent = dispatchMouseEvent(eventNames().mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true); m_capturesDragging = !swallowEvent; @@ -1483,7 +1526,7 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent) if (mouseEvent.button() == MiddleButton) m_panScrollButtonPressed = false; if (m_springLoadedPanScrollInProgress) - stopAutoscrollTimer(); + stopAutoscrollTimer(); #endif m_mousePressed = false; @@ -1666,7 +1709,7 @@ void EventHandler::clearDragState() m_dragTarget = 0; m_capturingMouseEventsNode = 0; m_shouldOnlyFireDragOverEvent = false; -#if PLATFORM(MAC) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) +#if PLATFORM(MAC) m_sendingEventToSubview = false; #endif } @@ -1790,8 +1833,15 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe if (m_nodeUnderMouse) swallowEvent = m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount); - + if (!swallowEvent && eventType == eventNames().mousedownEvent) { + + // If clicking on a frame scrollbar, do not mess up with content focus. + if (FrameView* view = m_frame->view()) { + if (view->scrollbarAtPoint(mouseEvent.pos())) + return false; + } + // The layout needs to be up to date to determine if an element is focusable. m_frame->document()->updateLayoutIgnorePendingStylesheets(); @@ -2178,7 +2228,9 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent) if (initialKeyEvent.type() == PlatformKeyboardEvent::RawKeyDown) { node->dispatchEvent(keydown, ec); - return keydown->defaultHandled() || keydown->defaultPrevented(); + // If frame changed as a result of keydown dispatch, then return true to avoid sending a subsequent keypress message to the new frame. + bool changedFocusedFrame = m_frame->page() && m_frame != m_frame->page()->focusController()->focusedOrMainFrame(); + return keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame; } // Run input method in advance of DOM event handling. This may result in the IM @@ -2198,7 +2250,9 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent) } node->dispatchEvent(keydown, ec); - bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented(); + // If frame changed as a result of keydown dispatch, then return early to avoid sending a subsequent keypress message to the new frame. + bool changedFocusedFrame = m_frame->page() && m_frame != m_frame->page()->focusController()->focusedOrMainFrame(); + bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame; if (handledByInputMethod || (keydownResult && !backwardCompatibilityMode)) return keydownResult; diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h index 282100d..c83925c 100644 --- a/WebCore/page/EventHandler.h +++ b/WebCore/page/EventHandler.h @@ -147,6 +147,8 @@ public: bool mouseMoved(const PlatformMouseEvent&); + void lostMouseCapture(); + bool handleMousePressEvent(const PlatformMouseEvent&); bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0); bool handleMouseReleaseEvent(const PlatformMouseEvent&); @@ -342,7 +344,7 @@ private: bool capturesDragging() const { return m_capturesDragging; } -#if PLATFORM(MAC) && defined(__OBJC__) && !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) +#if PLATFORM(MAC) && defined(__OBJC__) NSView *mouseDownViewIfStillGood(); PlatformMouseEvent currentPlatformMouseEvent() const; @@ -420,10 +422,8 @@ private: RefPtr<Node> m_previousWheelScrolledNode; #if PLATFORM(MAC) -#if !ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) NSView *m_mouseDownView; bool m_sendingEventToSubview; -#endif int m_activationEventNumber; #endif #if ENABLE(TOUCH_EVENTS) diff --git a/WebCore/page/EventSource.idl b/WebCore/page/EventSource.idl index 57bd807..be01098 100644 --- a/WebCore/page/EventSource.idl +++ b/WebCore/page/EventSource.idl @@ -53,12 +53,12 @@ module window { void close(); // EventTarget interface - [JSCCustom] void addEventListener(in DOMString type, - in EventListener listener, - in boolean useCapture); - [JSCCustom] void removeEventListener(in DOMString type, - in EventListener listener, - in boolean useCapture); + void addEventListener(in DOMString type, + in EventListener listener, + in boolean useCapture); + void removeEventListener(in DOMString type, + in EventListener listener, + in boolean useCapture); boolean dispatchEvent(in Event evt) raises(EventException); diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp index e07e2ea..372cb32 100644 --- a/WebCore/page/FocusController.cpp +++ b/WebCore/page/FocusController.cpp @@ -304,7 +304,7 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa frame = frame->tree()->top(); FocusCandidate focusCandidate; - findFocusableNodeInDirection(frame->document(), focusedNode, direction, event, focusCandidate); + findFocusableNodeInDirection(frame->document()->firstChild(), focusedNode, direction, event, focusCandidate); Node* node = focusCandidate.node; if (!node || !node->isElementNode()) { @@ -389,20 +389,23 @@ static void updateFocusCandidateIfCloser(Node* focusedNode, const FocusCandidate } } -void FocusController::findFocusableNodeInDirection(Document* document, Node* focusedNode, +void FocusController::findFocusableNodeInDirection(Node* outer, Node* focusedNode, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closestFocusCandidate, const FocusCandidate& candidateParent) { - ASSERT(document); - ASSERT(candidateParent.isNull() || static_cast<HTMLFrameOwnerElement*>(candidateParent.node)); + ASSERT(outer); + ASSERT(candidateParent.isNull() + || candidateParent.node->hasTagName(frameTag) + || candidateParent.node->hasTagName(iframeTag)); // Walk all the child nodes and update closestFocusCandidate if we find a nearer node. - for (Node* candidate = document->firstChild(); candidate; candidate = candidate->traverseNextNode()) { + Node* candidate = outer; + while (candidate) { // Inner documents case. if (candidate->isFrameOwnerElement()) - deepFindFocusableNodeInDirection(focusedNode, candidate, direction, event, closestFocusCandidate); + deepFindFocusableNodeInDirection(candidate, focusedNode, direction, event, closestFocusCandidate); else if (candidate != focusedNode && candidate->isKeyboardFocusable(event)) { FocusCandidate currentFocusCandidate(candidate); @@ -410,8 +413,10 @@ void FocusController::findFocusableNodeInDirection(Document* document, Node* foc distanceDataForNode(direction, focusedNode, currentFocusCandidate); // Bail out if distance is maximum. - if (currentFocusCandidate.distance == maxDistance()) + if (currentFocusCandidate.distance == maxDistance()) { + candidate = candidate->traverseNextNode(outer->parent()); continue; + } // If candidateParent is not null, it means that we are in a recursive call // from deepFineFocusableNodeInDirection (i.e. processing an element in an iframe), @@ -423,33 +428,54 @@ void FocusController::findFocusableNodeInDirection(Document* document, Node* foc updateFocusCandidateIfCloser(focusedNode, currentFocusCandidate, closestFocusCandidate); } + + candidate = candidate->traverseNextNode(outer->parent()); } } -void FocusController::deepFindFocusableNodeInDirection(Node* focusedNode, Node* candidate, +void FocusController::deepFindFocusableNodeInDirection(Node* container, Node* focusedNode, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closestFocusCandidate) { - HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(candidate); - if (!owner->contentFrame()) + ASSERT(container->hasTagName(frameTag) || container->hasTagName(iframeTag)); + + // Track if focusedNode is a descendant of the current container node being processed. + bool descendantOfContainer = false; + Node* firstChild = 0; + + // Iframe or Frame. + if (container->hasTagName(frameTag) || container->hasTagName(iframeTag)) { + + HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(container); + if (!owner->contentFrame()) + return; + + Document* innerDocument = owner->contentFrame()->document(); + if (!innerDocument) + return; + + descendantOfContainer = innerDocument == focusedNode->document(); + firstChild = innerDocument->firstChild(); + + } + + if (descendantOfContainer) { + findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closestFocusCandidate); return; + } - Document* innerDocument = owner->contentFrame()->document(); - if (!innerDocument) + // Check if the current container element itself is a good candidate + // to move focus to. If it is, then we traverse its inner nodes. + FocusCandidate candidateParent = FocusCandidate(container); + distanceDataForNode(direction, focusedNode, candidateParent); + + // Bail out if distance is maximum. + if (candidateParent.distance == maxDistance()) return; - if (innerDocument == focusedNode->document()) - findFocusableNodeInDirection(innerDocument, focusedNode, direction, event, closestFocusCandidate); - else { - // Check if the current {i}frame element itself is a good candidate - // to move focus to. If it is, then we traverse its inner nodes. - FocusCandidate candidateParent = FocusCandidate(candidate); - distanceDataForNode(direction, focusedNode, candidateParent); - - // FIXME: Consider alignment? - if (candidateParent.distance < closestFocusCandidate.distance) - findFocusableNodeInDirection(innerDocument, focusedNode, direction, event, closestFocusCandidate, candidateParent); - } + // FIXME: Consider alignment? + if (candidateParent.distance < closestFocusCandidate.distance) + findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closestFocusCandidate, candidateParent); } static bool relinquishesEditingFocus(Node *node) diff --git a/WebCore/page/FocusController.h b/WebCore/page/FocusController.h index dfa3780..4410833 100644 --- a/WebCore/page/FocusController.h +++ b/WebCore/page/FocusController.h @@ -63,9 +63,10 @@ private: bool advanceFocusDirectionally(FocusDirection, KeyboardEvent*); bool advanceFocusInDocumentOrder(FocusDirection, KeyboardEvent*, bool initialFocus); - void findFocusableNodeInDirection(Document*, Node*, FocusDirection, KeyboardEvent*, FocusCandidate& closestFocusCandidate, + void findFocusableNodeInDirection(Node* outter, Node*, FocusDirection, KeyboardEvent*, + FocusCandidate& closestFocusCandidate, const FocusCandidate& parentCandidate = FocusCandidate()); - void deepFindFocusableNodeInDirection(Node*, Node*, FocusDirection, KeyboardEvent*, FocusCandidate&); + void deepFindFocusableNodeInDirection(Node* container, Node* focused, FocusDirection, KeyboardEvent*, FocusCandidate&); Page* m_page; RefPtr<Frame> m_focusedFrame; diff --git a/WebCore/page/FrameView.cpp b/WebCore/page/FrameView.cpp index c69b514..d6b6e71 100644 --- a/WebCore/page/FrameView.cpp +++ b/WebCore/page/FrameView.cpp @@ -484,8 +484,19 @@ void FrameView::setNeedsOneShotDrawingSynchronization() if (page) page->chrome()->client()->setNeedsOneShotDrawingSynchronization(); } + #endif // USE(ACCELERATED_COMPOSITING) +bool FrameView::isEnclosedInCompositingLayer() const +{ +#if USE(ACCELERATED_COMPOSITING) + RenderObject* frameOwnerRenderer = m_frame->ownerRenderer(); + return frameOwnerRenderer && frameOwnerRenderer->containerForRepaint(); +#else + return false; +#endif +} + bool FrameView::syncCompositingStateRecursive() { #if USE(ACCELERATED_COMPOSITING) @@ -1009,15 +1020,6 @@ void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode) scrollToAnchor(); } -void FrameView::scrollRectIntoViewRecursively(const IntRect& r) -{ - bool wasInProgrammaticScroll = m_inProgrammaticScroll; - m_inProgrammaticScroll = true; - m_maintainScrollPositionAnchor = 0; - ScrollView::scrollRectIntoViewRecursively(r); - m_inProgrammaticScroll = wasInProgrammaticScroll; -} - void FrameView::setScrollPosition(const IntPoint& scrollPoint) { bool wasInProgrammaticScroll = m_inProgrammaticScroll; @@ -1460,7 +1462,7 @@ void FrameView::scrollToAnchor() if (AXObjectCache::accessibilityEnabled()) m_frame->document()->axObjectCache()->handleScrolledToAnchor(anchorNode.get()); - // scrollRectToVisible can call into scrollRectIntoViewRecursively(), which resets m_maintainScrollPositionAnchor. + // scrollRectToVisible can call into setScrollPosition(), which resets m_maintainScrollPositionAnchor. m_maintainScrollPositionAnchor = anchorNode; } @@ -1853,14 +1855,16 @@ 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; - PaintBehavior paintBehavior = m_paintBehavior; - if (paintBehavior == PaintBehaviorNormal) + PaintBehavior oldPaintBehavior = m_paintBehavior; + if (m_paintBehavior == PaintBehaviorNormal) document->invalidateRenderedRectsForMarkersInRect(rect); if (document->printing()) - paintBehavior |= PaintBehaviorFlattenCompositingLayers; + m_paintBehavior |= PaintBehaviorFlattenCompositingLayers; - contentRenderer->layer()->paint(p, rect, paintBehavior, eltRenderer); + contentRenderer->layer()->paint(p, rect, m_paintBehavior, eltRenderer); + + m_paintBehavior = oldPaintBehavior; m_isPainting = false; m_lastPaintTime = currentTime(); diff --git a/WebCore/page/FrameView.h b/WebCore/page/FrameView.h index cbd0cb9..efceebe 100644 --- a/WebCore/page/FrameView.h +++ b/WebCore/page/FrameView.h @@ -104,6 +104,9 @@ public: // content rendered via the normal painting path. void setNeedsOneShotDrawingSynchronization(); #endif + + bool isEnclosedInCompositingLayer() const; + // Only used with accelerated compositing, but outside the #ifdef to make linkage easier. // Returns true if the sync was completed. bool syncCompositingStateRecursive(); @@ -137,9 +140,8 @@ public: virtual IntRect windowResizerRect() const; - virtual void scrollRectIntoViewRecursively(const IntRect&); - virtual void setScrollPosition(const IntPoint&); - void scrollPositionChanged(); + void setScrollPosition(const IntPoint&); + virtual void scrollPositionChanged(); String mediaType() const; void setMediaType(const String&); diff --git a/WebCore/page/Geolocation.cpp b/WebCore/page/Geolocation.cpp index 36e14f6..88e8941 100644 --- a/WebCore/page/Geolocation.cpp +++ b/WebCore/page/Geolocation.cpp @@ -710,6 +710,8 @@ void Geolocation::handleEvent(ScriptExecutionContext*, Event* event) namespace WebCore { +void Geolocation::clearWatch(int watchId) {} + void Geolocation::disconnectFrame() {} Geolocation::Geolocation(Frame*) {} diff --git a/WebCore/page/Page.cpp b/WebCore/page/Page.cpp index ee5c052..4d7aa7c 100644 --- a/WebCore/page/Page.cpp +++ b/WebCore/page/Page.cpp @@ -420,7 +420,6 @@ void Page::addMediaCanStartListener(MediaCanStartListener* listener) void Page::removeMediaCanStartListener(MediaCanStartListener* listener) { - ASSERT(!m_canStartMedia); ASSERT(m_mediaCanStartListeners.contains(listener)); m_mediaCanStartListeners.remove(listener); } @@ -432,16 +431,14 @@ void Page::setCanStartMedia(bool canStartMedia) m_canStartMedia = canStartMedia; - if (!m_canStartMedia || m_mediaCanStartListeners.isEmpty()) - return; - - Vector<MediaCanStartListener*> listeners; - copyToVector(m_mediaCanStartListeners, listeners); - m_mediaCanStartListeners.clear(); - - size_t size = listeners.size(); - for (size_t i = 0; i < size; ++i) - listeners[i]->mediaCanStart(); + while (m_canStartMedia) { + HashSet<MediaCanStartListener*>::iterator slot = m_mediaCanStartListeners.begin(); + if (slot == m_mediaCanStartListeners.end()) + break; + MediaCanStartListener* listener = *slot; + m_mediaCanStartListeners.remove(slot); + listener->mediaCanStart(); + } } static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag) diff --git a/WebCore/page/PrintContext.cpp b/WebCore/page/PrintContext.cpp index e0235de..ffde0be 100644 --- a/WebCore/page/PrintContext.cpp +++ b/WebCore/page/PrintContext.cpp @@ -38,7 +38,8 @@ PrintContext::PrintContext(Frame* frame) PrintContext::~PrintContext() { - ASSERT(!m_isPrinting); + if (m_isPrinting) + end(); m_pageRects.clear(); } @@ -192,10 +193,9 @@ int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSi for (; pageNumber < printContext.pageCount(); pageNumber++) { const IntRect& page = printContext.pageRect(pageNumber); if (page.x() <= left && left < page.right() && page.y() <= top && top < page.bottom()) - break; + return pageNumber; } - printContext.end(); - return (pageNumber < printContext.pageCount() ? pageNumber : -1); + return -1; } int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels) @@ -206,7 +206,6 @@ int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels) PrintContext printContext(frame); printContext.begin(pageRect.width()); printContext.computePageRectsWithPageSize(pageSizeInPixels, false); - printContext.end(); return printContext.pageCount(); } diff --git a/WebCore/page/SecurityOrigin.cpp b/WebCore/page/SecurityOrigin.cpp index 265c643..aab8866 100644 --- a/WebCore/page/SecurityOrigin.cpp +++ b/WebCore/page/SecurityOrigin.cpp @@ -89,6 +89,20 @@ static URLSchemesMap& schemesWithUniqueOrigins() return schemesWithUniqueOrigins; } +static bool schemeRequiresAuthority(const String& scheme) +{ + DEFINE_STATIC_LOCAL(URLSchemesMap, schemes, ()); + + if (schemes.isEmpty()) { + schemes.add("http"); + schemes.add("https"); + schemes.add("ftp"); + } + + return schemes.contains(scheme); +} + + SecurityOrigin::SecurityOrigin(const KURL& url, SandboxFlags sandboxFlags) : m_sandboxFlags(sandboxFlags) , m_protocol(url.protocol().isNull() ? "" : url.protocol().lower()) @@ -103,6 +117,10 @@ SecurityOrigin::SecurityOrigin(const KURL& url, SandboxFlags sandboxFlags) if (m_protocol == "about" || m_protocol == "javascript") m_protocol = ""; + // For edge case URLs that were probably misparsed, make sure that the origin is unique. + if (schemeRequiresAuthority(m_protocol) && m_host.isEmpty()) + m_isUnique = true; + // document.domain starts as m_host, but can be set by the DOM. m_domain = m_host; diff --git a/WebCore/page/SecurityOrigin.h b/WebCore/page/SecurityOrigin.h index d732664..a6c3a7a 100644 --- a/WebCore/page/SecurityOrigin.h +++ b/WebCore/page/SecurityOrigin.h @@ -120,6 +120,11 @@ public: bool canAccessLocalStorage() const { return !isUnique(); } bool canAccessCookies() const { return !isUnique(); } + // Technically, we should always allow access to sessionStorage, but we + // currently don't handle creating a sessionStorage area for unique + // origins. + bool canAccessSessionStorage() const { return !isUnique(); } + bool isSecureTransitionTo(const KURL&) const; // The local SecurityOrigin is the most privileged SecurityOrigin. diff --git a/WebCore/page/Settings.cpp b/WebCore/page/Settings.cpp index 33c9c0d..58c9629 100644 --- a/WebCore/page/Settings.cpp +++ b/WebCore/page/Settings.cpp @@ -96,6 +96,7 @@ Settings::Settings(Page* page) , m_allowUniversalAccessFromFileURLs(true) , m_allowFileAccessFromFileURLs(true) , m_javaScriptCanOpenWindowsAutomatically(false) + , m_javaScriptCanAccessClipboard(false) , m_shouldPrintBackgrounds(false) , m_textAreasAreResizable(false) #if ENABLE(DASHBOARD_SUPPORT) @@ -333,6 +334,11 @@ void Settings::setJavaScriptCanOpenWindowsAutomatically(bool javaScriptCanOpenWi m_javaScriptCanOpenWindowsAutomatically = javaScriptCanOpenWindowsAutomatically; } +void Settings::setJavaScriptCanAccessClipboard(bool javaScriptCanAccessClipboard) +{ + m_javaScriptCanAccessClipboard = javaScriptCanAccessClipboard; +} + void Settings::setDefaultTextEncodingName(const String& defaultTextEncodingName) { m_defaultTextEncodingName = defaultTextEncodingName; diff --git a/WebCore/page/Settings.h b/WebCore/page/Settings.h index 04487b1..5f567c2 100644 --- a/WebCore/page/Settings.h +++ b/WebCore/page/Settings.h @@ -145,6 +145,9 @@ namespace WebCore { void setJavaScriptCanOpenWindowsAutomatically(bool); bool javaScriptCanOpenWindowsAutomatically() const { return m_javaScriptCanOpenWindowsAutomatically; } + void setJavaScriptCanAccessClipboard(bool); + bool javaScriptCanAccessClipboard() const { return m_javaScriptCanAccessClipboard; } + void setSpatialNavigationEnabled(bool); bool isSpatialNavigationEnabled() const { return m_isSpatialNavigationEnabled; } @@ -448,6 +451,7 @@ namespace WebCore { bool m_allowUniversalAccessFromFileURLs: 1; bool m_allowFileAccessFromFileURLs: 1; bool m_javaScriptCanOpenWindowsAutomatically : 1; + bool m_javaScriptCanAccessClipboard : 1; bool m_shouldPrintBackgrounds : 1; bool m_textAreasAreResizable : 1; #if ENABLE(DASHBOARD_SUPPORT) diff --git a/WebCore/page/WindowFeatures.cpp b/WebCore/page/WindowFeatures.cpp index c499a4a..1654ff5 100644 --- a/WebCore/page/WindowFeatures.cpp +++ b/WebCore/page/WindowFeatures.cpp @@ -155,6 +155,8 @@ void WindowFeatures::setWindowFeature(const String& keyString, const String& val fullscreen = value; else if (keyString == "scrollbars") scrollbarsVisible = value; + else if (value == 1) + additionalFeatures.append(keyString); } bool WindowFeatures::boolFeature(const HashMap<String, String>& features, const char* key, bool defaultValue) diff --git a/WebCore/page/WindowFeatures.h b/WebCore/page/WindowFeatures.h index a12cf05..a414552 100644 --- a/WebCore/page/WindowFeatures.h +++ b/WebCore/page/WindowFeatures.h @@ -76,6 +76,8 @@ namespace WebCore { bool fullscreen; bool dialog; + + Vector<String> additionalFeatures; }; } // namespace WebCore diff --git a/WebCore/page/animation/AnimationBase.cpp b/WebCore/page/animation/AnimationBase.cpp index d9282cb..a49c754 100644 --- a/WebCore/page/animation/AnimationBase.cpp +++ b/WebCore/page/animation/AnimationBase.cpp @@ -952,9 +952,6 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) overrideAnimations(); - // Send start event, if needed - onAnimationStart(0); // The elapsedTime is always 0 here - // Start the animation if (overridden()) { // We won't try to start accelerated animations if we are overridden and @@ -987,6 +984,9 @@ void AnimationBase::updateStateMachine(AnimStateInput input, double param) m_startTime += m_animation->delay(); } + // Now that we know the start time, fire the start event. + onAnimationStart(0); // The elapsedTime is 0. + // Decide whether to go into looping or ending state goIntoEndingOrLoopingState(); diff --git a/WebCore/page/animation/AnimationController.cpp b/WebCore/page/animation/AnimationController.cpp index cb609a5..3761c5a 100644 --- a/WebCore/page/animation/AnimationController.cpp +++ b/WebCore/page/animation/AnimationController.cpp @@ -134,9 +134,16 @@ void AnimationControllerPrivate::updateAnimationTimer(bool callSetChanged/* = fa void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<AnimationControllerPrivate>*) { + fireEventsAndUpdateStyle(); +} + +void AnimationControllerPrivate::fireEventsAndUpdateStyle() +{ // Protect the frame from getting destroyed in the event handler RefPtr<Frame> protector = m_frame; + bool updateStyle = !m_eventsToDispatch.isEmpty() || !m_nodeChangesToDispatch.isEmpty(); + // fire all the events Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = m_eventsToDispatch.end(); for (Vector<EventToDispatch>::const_iterator it = m_eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) { @@ -155,7 +162,7 @@ void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<Animat m_nodeChangesToDispatch.clear(); - if (m_frame) + if (updateStyle && m_frame) m_frame->document()->updateStyleIfNeeded(); } @@ -196,6 +203,10 @@ void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPr // When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate // updateStyleIfNeeded. It will then call back to us with new information. updateAnimationTimer(true); + + // Fire events right away, to avoid a flash of unanimated style after an animation completes, and before + // the 'end' event fires. + fireEventsAndUpdateStyle(); } bool AnimationControllerPrivate::isAnimatingPropertyOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const diff --git a/WebCore/page/animation/AnimationControllerPrivate.h b/WebCore/page/animation/AnimationControllerPrivate.h index 682dd75..5ef9098 100644 --- a/WebCore/page/animation/AnimationControllerPrivate.h +++ b/WebCore/page/animation/AnimationControllerPrivate.h @@ -92,6 +92,7 @@ public: private: void styleAvailable(); + void fireEventsAndUpdateStyle(); typedef HashMap<RenderObject*, RefPtr<CompositeAnimation> > RenderObjectAnimationMap; diff --git a/WebCore/page/animation/CompositeAnimation.cpp b/WebCore/page/animation/CompositeAnimation.cpp index 0f238fd..7619b1f 100644 --- a/WebCore/page/animation/CompositeAnimation.cpp +++ b/WebCore/page/animation/CompositeAnimation.cpp @@ -205,6 +205,8 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, Render // Toss the animation order map. m_keyframeAnimationOrderMap.clear(); + + DEFINE_STATIC_LOCAL(const AtomicString, none, ("none")); // Now mark any still active animations as active and add any new animations. if (targetStyle->animations()) { @@ -232,7 +234,7 @@ void CompositeAnimation::updateKeyframeAnimations(RenderObject* renderer, Render // Set the saved animation to this new one, just in case the play state has changed. keyframeAnim->setAnimation(anim); keyframeAnim->setIndex(i); - } else if ((anim->duration() || anim->delay()) && anim->iterationCount()) { + } else if ((anim->duration() || anim->delay()) && anim->iterationCount() && animationName != none) { keyframeAnim = KeyframeAnimation::create(const_cast<Animation*>(anim), renderer, i, this, targetStyle); m_keyframeAnimations.set(keyframeAnim->name().impl(), keyframeAnim); } diff --git a/WebCore/page/chromium/EventHandlerChromium.cpp b/WebCore/page/chromium/EventHandlerChromium.cpp index ff161af..bf9acb7 100644 --- a/WebCore/page/chromium/EventHandlerChromium.cpp +++ b/WebCore/page/chromium/EventHandlerChromium.cpp @@ -54,11 +54,12 @@ const double EventHandler::TextDragDelay = 0.0; bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) { + const PlatformMouseEvent& mouseEvent = mev.event(); // If we're clicking into a frame that is selected, the frame will appear // greyed out even though we're clicking on the selection. This looks // really strange (having the whole frame be greyed out), so we deselect the // selection. - IntPoint p = m_frame->view()->windowToContents(mev.event().pos()); + IntPoint p = m_frame->view()->windowToContents(mouseEvent.pos()); if (m_frame->selection()->contains(p)) { VisiblePosition visiblePos( mev.targetNode()->renderer()->positionForPoint(mev.localPoint())); @@ -67,7 +68,19 @@ bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m m_frame->selection()->setSelection(newSelection); } - subframe->eventHandler()->handleMousePressEvent(mev.event()); + // If the click hits a scrollbar, we pass the mouse press event to the + // scrollbar directly. This prevents selected text from being unselected. + // This matches the WebKit mac code which passes the mouse press event + // to an NSScroller. + FrameView* view = subframe->view(); + Scrollbar* scrollbar = view ? view->scrollbarAtPoint(mouseEvent.pos()) : 0; + if (scrollbar) { + HitTestRequest request(HitTestRequest::Active); + IntPoint documentPoint = view->windowToContents(mouseEvent.pos()); + MouseEventWithHitTestResults subframeMouseEvent = subframe->document()->prepareMouseEvent(request, documentPoint, mouseEvent); + subframe->eventHandler()->passMousePressEventToScrollbar(subframeMouseEvent, scrollbar); + } else + subframe->eventHandler()->handleMousePressEvent(mouseEvent); return true; } diff --git a/WebCore/page/gtk/EventHandlerGtk.cpp b/WebCore/page/gtk/EventHandlerGtk.cpp index 7051391..0ff67d2 100644 --- a/WebCore/page/gtk/EventHandlerGtk.cpp +++ b/WebCore/page/gtk/EventHandlerGtk.cpp @@ -96,7 +96,7 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* wid PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const { - return ClipboardGtk::create(ClipboardWritable, true); + return ClipboardGtk::create(ClipboardWritable, DataObjectGtk::create(), true); } bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe) diff --git a/WebCore/page/mac/DragControllerMac.mm b/WebCore/page/mac/DragControllerMac.mm index f080232..a09c418 100644 --- a/WebCore/page/mac/DragControllerMac.mm +++ b/WebCore/page/mac/DragControllerMac.mm @@ -42,20 +42,6 @@ const int DragController::DragIconBottomInset = 3; const float DragController::DragImageAlpha = 0.75f; -#if ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) - -DragOperation DragController::dragOperation(DragData*) -{ - return DragOperationNone; -} - -bool DragController::isCopyKeyDown() -{ - return false; -} - -#else - bool DragController::isCopyKeyDown() { return [[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask; @@ -74,8 +60,6 @@ DragOperation DragController::dragOperation(DragData* dragData) return DragOperationNone; } -#endif - const IntSize& DragController::maxDragImageSize() { static const IntSize maxDragImageSize(400, 400); diff --git a/WebCore/page/mac/EventHandlerMac.mm b/WebCore/page/mac/EventHandlerMac.mm index 650c0e1..8842e31 100644 --- a/WebCore/page/mac/EventHandlerMac.mm +++ b/WebCore/page/mac/EventHandlerMac.mm @@ -66,8 +66,6 @@ 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, ()); @@ -661,119 +659,6 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent& event) const return m_activationEventNumber == event.eventNumber(); } -#else // ENABLE(EXPERIMENTAL_SINGLE_VIEW_MODE) - -NSEvent *EventHandler::currentNSEvent() -{ - return 0; -} - -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&) const -{ - notImplemented(); - return false; -} - -PassRefPtr<KeyboardEvent> EventHandler::currentKeyboardEvent() const -{ - return 0; -} - -void EventHandler::mouseDown(NSEvent *) -{ - notImplemented(); -} - -void EventHandler::mouseDragged(NSEvent *) -{ - notImplemented(); -} - -void EventHandler::mouseUp(NSEvent *) -{ - notImplemented(); -} - -void EventHandler::mouseMoved(NSEvent *) -{ - notImplemented(); -} - -bool EventHandler::keyEvent(NSEvent *) -{ - notImplemented(); - return false; -} - -bool EventHandler::wheelEvent(NSEvent *) -{ - notImplemented(); - return false; -} - -#if ENABLE(CONTEXT_MENUS) -bool EventHandler::sendContextMenuEvent(NSEvent *) -{ - notImplemented(); - return false; -} -#endif - -bool EventHandler::eventMayStartDrag(NSEvent *) -{ - notImplemented(); - return false; -} - -void EventHandler::sendFakeEventsAfterWidgetTracking(NSEvent *) -{ -} - - -#endif - #if ENABLE(DRAG_SUPPORT) PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const diff --git a/WebCore/page/qt/EventHandlerQt.cpp b/WebCore/page/qt/EventHandlerQt.cpp index d7982fa..5b24eae 100644 --- a/WebCore/page/qt/EventHandlerQt.cpp +++ b/WebCore/page/qt/EventHandlerQt.cpp @@ -51,7 +51,7 @@ #include "NotImplemented.h" QT_BEGIN_NAMESPACE -extern Q_GUI_EXPORT bool qt_tab_all_widgets; // from qapplication.cpp +Q_GUI_EXPORT extern bool qt_tab_all_widgets; // from qapplication.cpp QT_END_NAMESPACE namespace WebCore { |