Diff
Modified: trunk/LayoutTests/ChangeLog (202242 => 202243)
--- trunk/LayoutTests/ChangeLog 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/LayoutTests/ChangeLog 2016-06-20 21:22:54 UTC (rev 202243)
@@ -1,3 +1,16 @@
+2016-06-20 Simon Fraser <[email protected]>
+
+ Focus event dispatched in iframe causes parent document to scroll incorrectly
+ https://bugs.webkit.org/show_bug.cgi?id=158629
+ rdar://problem/26521616
+
+ Reviewed by Tim Horton.
+
+ * fast/forms/ios/focus-input-in-iframe-expected.txt: Added.
+ * fast/forms/ios/focus-input-in-iframe.html: Added.
+ * fast/forms/ios/programmatic-focus-input-in-iframe-expected.txt: Added.
+ * fast/forms/ios/programmatic-focus-input-in-iframe.html: Added.
+
2016-06-20 Commit Queue <[email protected]>
Unreviewed, rolling out r202179.
Added: trunk/LayoutTests/fast/forms/ios/focus-input-in-iframe-expected.txt (0 => 202243)
--- trunk/LayoutTests/fast/forms/ios/focus-input-in-iframe-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/forms/ios/focus-input-in-iframe-expected.txt 2016-06-20 21:22:54 UTC (rev 202243)
@@ -0,0 +1,7 @@
+Tests zooming into a text input on tap.
+
+Click to focus input
+
+tap location { x: 20.000, y: 62.000 }
+scale 1.455
+visibleRect { left: 0.000, top: 1201.976, width: 219.979, height: 329.968 }
Added: trunk/LayoutTests/fast/forms/ios/focus-input-in-iframe.html (0 => 202243)
--- trunk/LayoutTests/fast/forms/ios/focus-input-in-iframe.html (rev 0)
+++ trunk/LayoutTests/fast/forms/ios/focus-input-in-iframe.html 2016-06-20 21:22:54 UTC (rev 202243)
@@ -0,0 +1,48 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=0.5">
+ <style>
+ button {
+ display: block;
+ }
+ iframe {
+ margin-top: 800px;
+ }
+ </style>
+
+ <script src=""
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ if (window.internals)
+ internals.settings.setFrameFlatteningEnabled(true);
+
+ function buttonClicked()
+ {
+ document.getElementById('frame').contentDocument.getElementById('input').focus();
+ }
+
+ function doTest()
+ {
+ testZoomAfterTap(document.getElementById('target'), 10, 10);
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body>
+
+<p>Tests zooming into a text input on tap.</p>
+<button id="target" _onclick_="buttonClicked()">Click to focus input</button>
+
+<iframe id="frame" srcdoc="<style>input { margin: 400px 20px; }</style>
+<input id='input' type='text'>
+"></iframe>
+
+</body>
+</html>
Added: trunk/LayoutTests/fast/forms/ios/programmatic-focus-input-in-iframe-expected.txt (0 => 202243)
--- trunk/LayoutTests/fast/forms/ios/programmatic-focus-input-in-iframe-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/forms/ios/programmatic-focus-input-in-iframe-expected.txt 2016-06-20 21:22:54 UTC (rev 202243)
@@ -0,0 +1,4 @@
+Tests that a programmatic focus should not scroll into view
+
+PASS: page did not scroll.
+
Added: trunk/LayoutTests/fast/forms/ios/programmatic-focus-input-in-iframe.html (0 => 202243)
--- trunk/LayoutTests/fast/forms/ios/programmatic-focus-input-in-iframe.html (rev 0)
+++ trunk/LayoutTests/fast/forms/ios/programmatic-focus-input-in-iframe.html 2016-06-20 21:22:54 UTC (rev 202243)
@@ -0,0 +1,57 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+<head>
+ <meta name="viewport" content="initial-scale=0.5">
+ <style>
+ button {
+ display: block;
+ }
+ iframe {
+ margin-top: 800px;
+ }
+ </style>
+
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ if (window.internals)
+ internals.settings.setFrameFlatteningEnabled(true);
+
+ function pageDidScroll()
+ {
+ document.getElementById('result').textContent = 'FAIL: page scrolled to ' + document.scrollingElement.scrollTop;
+ }
+
+ function doTest()
+ {
+ window.setTimeout(function() {
+ document.getElementById('frame').contentDocument.getElementById('input').focus();
+ }, 0);
+
+ // Wait for any scroll to happen.
+ window.setTimeout(function() {
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, 100);
+ }
+
+ window.addEventListener('load', doTest, false);
+ </script>
+</head>
+<body _onscroll_="pageDidScroll()">
+
+<p>Tests that a programmatic focus should not scroll into view</p>
+<div id="result">
+ PASS: page did not scroll.
+</div>
+
+<iframe id="frame" srcdoc="<style>input { margin: 400px 20px; }</style>
+<input id='input' type='text'>
+"></iframe>
+
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (202242 => 202243)
--- trunk/Source/WebCore/ChangeLog 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/ChangeLog 2016-06-20 21:22:54 UTC (rev 202243)
@@ -1,3 +1,57 @@
+2016-06-20 Simon Fraser <[email protected]>
+
+ Focus event dispatched in iframe causes parent document to scroll incorrectly
+ https://bugs.webkit.org/show_bug.cgi?id=158629
+ rdar://problem/26521616
+
+ Reviewed by Tim Horton.
+
+ When focussing elements in iframes, the page could scroll to an incorrect location.
+ This happened because code in Element::focus() tried to disable scrolling on focus,
+ but did so only for the current frame, so ancestor frames got programmatically scrolled.
+ On iOS we handle the scrolling in the UI process, so never want the web process to
+ do programmatic scrolling.
+
+ Fix by changing the focus and cache restore code to use SelectionRevealMode::DoNotReveal,
+ rather than manually prohibiting frame scrolling. Pass SelectionRevealMode through various callers,
+ and use RevealUpToMainFrame for iOS, allowing the UI process to do the zoomToRect: for the main frame.
+
+ Tests: fast/forms/ios/focus-input-in-iframe.html
+ fast/forms/ios/programmatic-focus-input-in-iframe.html
+
+ * dom/Document.h:
+ * dom/Element.cpp:
+ (WebCore::Element::scrollIntoView):
+ (WebCore::Element::scrollIntoViewIfNeeded):
+ (WebCore::Element::scrollIntoViewIfNotVisible):
+ (WebCore::Element::focus):
+ (WebCore::Element::updateFocusAppearance):
+ * dom/Element.h:
+ * editing/Editor.cpp:
+ (WebCore::Editor::insertTextWithoutSendingTextEvent):
+ (WebCore::Editor::revealSelectionAfterEditingOperation):
+ (WebCore::Editor::findStringAndScrollToVisible):
+ * editing/FrameSelection.cpp:
+ (WebCore::FrameSelection::updateAndRevealSelection):
+ (WebCore::FrameSelection::revealSelection):
+ (WebCore::FrameSelection::FrameSelection): Deleted.
+ * editing/FrameSelection.h:
+ * html/HTMLInputElement.cpp:
+ (WebCore::HTMLInputElement::updateFocusAppearance):
+ * html/HTMLTextAreaElement.cpp:
+ (WebCore::HTMLTextAreaElement::updateFocusAppearance):
+ * page/ContextMenuController.cpp:
+ (WebCore::ContextMenuController::contextMenuItemSelected):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::scrollToAnchor):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::scrollRectToVisible):
+ (WebCore::RenderLayer::autoscroll):
+ * rendering/RenderLayer.h:
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::scrollRectToVisible):
+ * rendering/RenderObject.h:
+
2016-06-20 Keith Rollin <[email protected]>
Remove RefPtr::release() and change calls sites to use WTFMove()
Modified: trunk/Source/WebCore/dom/Document.h (202242 => 202243)
--- trunk/Source/WebCore/dom/Document.h 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/dom/Document.h 2016-06-20 21:22:54 UTC (rev 202243)
@@ -282,11 +282,6 @@
SetDefault,
};
-enum class SelectionRevealMode {
- Reveal,
- DoNotReveal
-};
-
enum class HttpEquivPolicy {
Enabled,
DisabledBySettings,
Modified: trunk/Source/WebCore/dom/Element.cpp (202242 => 202243)
--- trunk/Source/WebCore/dom/Element.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/dom/Element.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -639,9 +639,9 @@
LayoutRect bounds = renderer()->anchorRect();
// Align to the top / bottom and to the closest edge.
if (alignToTop)
- renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
+ renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
else
- renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
+ renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignBottomAlways);
}
void Element::scrollIntoViewIfNeeded(bool centerIfNeeded)
@@ -653,9 +653,9 @@
LayoutRect bounds = renderer()->anchorRect();
if (centerIfNeeded)
- renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
+ renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, bounds, ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
else
- renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
+ renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, bounds, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
}
void Element::scrollIntoViewIfNotVisible(bool centerIfNotVisible)
@@ -667,9 +667,9 @@
LayoutRect bounds = renderer()->anchorRect();
if (centerIfNotVisible)
- renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignCenterIfNotVisible, ScrollAlignment::alignCenterIfNotVisible);
+ renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, bounds, ScrollAlignment::alignCenterIfNotVisible, ScrollAlignment::alignCenterIfNotVisible);
else
- renderer()->scrollRectToVisible(bounds, ScrollAlignment::alignToEdgeIfNotVisible, ScrollAlignment::alignToEdgeIfNotVisible);
+ renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, bounds, ScrollAlignment::alignToEdgeIfNotVisible, ScrollAlignment::alignToEdgeIfNotVisible);
}
void Element::scrollByUnits(int units, ScrollGranularity granularity)
@@ -2245,20 +2245,18 @@
}
cancelFocusAppearanceUpdate();
+
+ SelectionRevealMode revealMode = SelectionRevealMode::Reveal;
#if PLATFORM(IOS)
// Focusing a form element triggers animation in UIKit to scroll to the right position.
// Calling updateFocusAppearance() would generate an unnecessary call to ScrollView::setScrollPosition(),
// which would jump us around during this animation. See <rdar://problem/6699741>.
- FrameView* view = document().view();
- bool isFormControl = view && is<HTMLFormControlElement>(*this);
+ bool isFormControl = is<HTMLFormControlElement>(*this);
if (isFormControl)
- view->setProhibitsScrolling(true);
+ revealMode = SelectionRevealMode::RevealUpToMainFrame;
#endif
- updateFocusAppearance(restorePreviousSelection ? SelectionRestorationMode::Restore : SelectionRestorationMode::SetDefault);
-#if PLATFORM(IOS)
- if (isFormControl)
- view->setProhibitsScrolling(false);
-#endif
+
+ updateFocusAppearance(restorePreviousSelection ? SelectionRestorationMode::Restore : SelectionRestorationMode::SetDefault, revealMode);
}
void Element::updateFocusAppearanceAfterAttachIfNeeded()
@@ -2290,11 +2288,10 @@
if (frame->selection().shouldChangeSelection(newSelection)) {
frame->selection().setSelection(newSelection, FrameSelection::defaultSetSelectionOptions(), Element::defaultFocusTextStateChangeIntent());
- if (revealMode == SelectionRevealMode::Reveal)
- frame->selection().revealSelection();
+ frame->selection().revealSelection(revealMode);
}
- } else if (renderer() && !renderer()->isWidget() && revealMode == SelectionRevealMode::Reveal)
- renderer()->scrollRectToVisible(renderer()->anchorRect());
+ } else if (renderer() && !renderer()->isWidget())
+ renderer()->scrollRectToVisible(revealMode, renderer()->anchorRect());
}
void Element::blur()
Modified: trunk/Source/WebCore/dom/Element.h (202242 => 202243)
--- trunk/Source/WebCore/dom/Element.h 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/dom/Element.h 2016-06-20 21:22:54 UTC (rev 202243)
@@ -60,6 +60,12 @@
SpellcheckAttributeDefault
};
+enum class SelectionRevealMode {
+ Reveal,
+ RevealUpToMainFrame, // Scroll overflow and iframes, but not the main frame.
+ DoNotReveal
+};
+
class Element : public ContainerNode {
public:
static Ref<Element> create(const QualifiedName&, Document&);
Modified: trunk/Source/WebCore/editing/Editor.cpp (202242 => 202243)
--- trunk/Source/WebCore/editing/Editor.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/editing/Editor.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -1204,7 +1204,7 @@
// Reveal the current selection
if (Frame* editedFrame = document->frame())
if (Page* page = editedFrame->page())
- page->focusController().focusedOrMainFrame().selection().revealSelection(ScrollAlignment::alignCenterIfNeeded);
+ page->focusController().focusedOrMainFrame().selection().revealSelection(SelectionRevealMode::Reveal, ScrollAlignment::alignCenterIfNeeded);
}
}
@@ -2799,7 +2799,7 @@
if (m_ignoreCompositionSelectionChange)
return;
- m_frame.selection().revealSelection(alignment, revealExtentOption);
+ m_frame.selection().revealSelection(SelectionRevealMode::Reveal, alignment, revealExtentOption);
}
void Editor::setIgnoreCompositionSelectionChange(bool ignore, RevealSelection shouldRevealExistingSelection)
@@ -3147,7 +3147,7 @@
if (!nextMatch)
return nullptr;
- nextMatch->firstNode()->renderer()->scrollRectToVisible(nextMatch->absoluteBoundingBox(),
+ nextMatch->firstNode()->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, nextMatch->absoluteBoundingBox(),
ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
return nextMatch;
Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (202242 => 202243)
--- trunk/Source/WebCore/editing/FrameSelection.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -127,7 +127,6 @@
#if PLATFORM(IOS)
, m_updateAppearanceEnabled(false)
, m_caretBlinks(true)
- , m_scrollingSuppressCount(0)
#endif
{
if (shouldAlwaysUseDirectionalSelection(m_frame))
@@ -388,7 +387,7 @@
else
alignment = m_alwaysAlignCursorOnScrollWhenRevealingSelection ? ScrollAlignment::alignTopAlways : ScrollAlignment::alignToEdgeIfNeeded;
- revealSelection(alignment, RevealExtent);
+ revealSelection(SelectionRevealMode::Reveal, alignment, RevealExtent);
}
notifyAccessibilityForSelectionChange(intent);
@@ -2290,8 +2289,11 @@
return scanForForm(start);
}
-void FrameSelection::revealSelection(const ScrollAlignment& alignment, RevealExtentOption revealExtentOption)
+void FrameSelection::revealSelection(SelectionRevealMode revealMode, const ScrollAlignment& alignment, RevealExtentOption revealExtentOption)
{
+ if (revealMode == SelectionRevealMode::DoNotReveal)
+ return;
+
LayoutRect rect;
switch (m_selection.selectionType()) {
@@ -2312,7 +2314,7 @@
if (RenderLayer* layer = start.deprecatedNode()->renderer()->enclosingLayer()) {
if (!m_scrollingSuppressCount) {
layer->setAdjustForIOSCaretWhenScrolling(true);
- layer->scrollRectToVisible(rect, alignment, alignment);
+ layer->scrollRectToVisible(revealMode, rect, alignment, alignment);
layer->setAdjustForIOSCaretWhenScrolling(false);
updateAppearance();
if (m_frame->page())
@@ -2323,7 +2325,7 @@
// FIXME: This code only handles scrolling the startContainer's layer, but
// the selection rect could intersect more than just that.
// See <rdar://problem/4799899>.
- if (start.deprecatedNode()->renderer()->scrollRectToVisible(rect, alignment, alignment))
+ if (start.deprecatedNode()->renderer()->scrollRectToVisible(revealMode, rect, alignment, alignment))
updateAppearance();
#endif
}
Modified: trunk/Source/WebCore/editing/FrameSelection.h (202242 => 202243)
--- trunk/Source/WebCore/editing/FrameSelection.h 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/editing/FrameSelection.h 2016-06-20 21:22:54 UTC (rev 202243)
@@ -28,6 +28,7 @@
#include "AXTextStateChangeIntent.h"
#include "EditingStyle.h"
+#include "Element.h"
#include "IntRect.h"
#include "LayoutRect.h"
#include "Range.h"
@@ -266,7 +267,7 @@
WEBCORE_EXPORT HTMLFormElement* currentForm() const;
- WEBCORE_EXPORT void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, RevealExtentOption = DoNotRevealExtent);
+ WEBCORE_EXPORT void revealSelection(SelectionRevealMode = SelectionRevealMode::Reveal, const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, RevealExtentOption = DoNotRevealExtent);
WEBCORE_EXPORT void setSelectionFromNone();
bool shouldShowBlockCursor() const { return m_shouldShowBlockCursor; }
@@ -350,7 +351,7 @@
bool m_updateAppearanceEnabled : 1;
bool m_caretBlinks : 1;
Color m_caretColor;
- int m_scrollingSuppressCount;
+ int m_scrollingSuppressCount { 0 };
#endif
};
Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (202242 => 202243)
--- trunk/Source/WebCore/html/HTMLInputElement.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -404,8 +404,8 @@
select(Element::defaultFocusTextStateChangeIntent());
else
restoreCachedSelection();
- if (document().frame() && revealMode == SelectionRevealMode::Reveal)
- document().frame()->selection().revealSelection();
+ if (document().frame())
+ document().frame()->selection().revealSelection(revealMode);
} else
HTMLTextFormControlElement::updateFocusAppearance(restorationMode, revealMode);
}
Modified: trunk/Source/WebCore/html/HTMLTextAreaElement.cpp (202242 => 202243)
--- trunk/Source/WebCore/html/HTMLTextAreaElement.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/html/HTMLTextAreaElement.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -260,8 +260,8 @@
} else
restoreCachedSelection(Element::defaultFocusTextStateChangeIntent());
- if (document().frame() && revealMode == SelectionRevealMode::Reveal)
- document().frame()->selection().revealSelection();
+ if (document().frame())
+ document().frame()->selection().revealSelection(revealMode);
}
void HTMLTextAreaElement::defaultEventHandler(Event* event)
Modified: trunk/Source/WebCore/page/ContextMenuController.cpp (202242 => 202243)
--- trunk/Source/WebCore/page/ContextMenuController.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/page/ContextMenuController.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -372,7 +372,7 @@
ASSERT(document);
RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(*document, createFragmentFromMarkup(*document, title, ""), replaceOptions);
applyCommand(command);
- frame->selection().revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
+ frame->selection().revealSelection(SelectionRevealMode::Reveal, ScrollAlignment::alignToEdgeIfNeeded);
}
break;
}
Modified: trunk/Source/WebCore/page/FrameView.cpp (202242 => 202243)
--- trunk/Source/WebCore/page/FrameView.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/page/FrameView.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -3050,11 +3050,11 @@
// Scroll nested layers and frames to reveal the anchor.
// Align to the top and to the closest side (this matches other browsers).
if (anchorNode->renderer()->style().isHorizontalWritingMode())
- anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
+ anchorNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, rect, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignTopAlways);
else if (anchorNode->renderer()->style().isFlippedBlocksWritingMode())
- anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignRightAlways, ScrollAlignment::alignToEdgeIfNeeded);
+ anchorNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, rect, ScrollAlignment::alignRightAlways, ScrollAlignment::alignToEdgeIfNeeded);
else
- anchorNode->renderer()->scrollRectToVisible(rect, ScrollAlignment::alignLeftAlways, ScrollAlignment::alignToEdgeIfNeeded);
+ anchorNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, rect, ScrollAlignment::alignLeftAlways, ScrollAlignment::alignToEdgeIfNeeded);
if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
cache->handleScrolledToAnchor(anchorNode.get());
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (202242 => 202243)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -80,6 +80,7 @@
#include "HitTestRequest.h"
#include "HitTestResult.h"
#include "Logging.h"
+#include "MainFrame.h"
#include "NoEventDispatchAssertion.h"
#include "OverflowEvent.h"
#include "OverlapTestRequestClient.h"
@@ -2490,7 +2491,7 @@
return box->hasHorizontalOverflow() || box->hasVerticalOverflow();
}
-void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
+void RenderLayer::scrollRectToVisible(SelectionRevealMode revealMode, const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
{
LOG_WITH_STREAM(Scrolling, stream << "Layer " << this << " scrollRectToVisible " << rect);
@@ -2550,6 +2551,9 @@
parentLayer = nullptr;
}
} else {
+ if (revealMode == SelectionRevealMode::RevealUpToMainFrame && frameView.frame().isMainFrame())
+ return;
+
#if !PLATFORM(IOS)
LayoutRect viewRect = frameView.visibleContentRect();
LayoutRect visibleRectRelativeToDocument = viewRect;
@@ -2574,7 +2578,7 @@
}
if (parentLayer)
- parentLayer->scrollRectToVisible(newRect, alignX, alignY);
+ parentLayer->scrollRectToVisible(revealMode, newRect, alignX, alignY);
}
void RenderLayer::updateCompositingLayersAfterScroll()
@@ -2667,7 +2671,7 @@
void RenderLayer::autoscroll(const IntPoint& position)
{
IntPoint currentDocumentPosition = renderer().view().frameView().windowToContents(position);
- scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
+ scrollRectToVisible(SelectionRevealMode::Reveal, LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
}
bool RenderLayer::canResize() const
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (202242 => 202243)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2016-06-20 21:22:54 UTC (rev 202243)
@@ -205,7 +205,7 @@
void availableContentSizeChanged(AvailableSizeChangeReason) override;
- void scrollRectToVisible(const LayoutRect&, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
+ void scrollRectToVisible(SelectionRevealMode, const LayoutRect&, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
LayoutRect getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& visibleRectRelativeToDocument, const LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (202242 => 202243)
--- trunk/Source/WebCore/rendering/RenderObject.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -358,13 +358,16 @@
return nullptr;
}
-bool RenderObject::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
+bool RenderObject::scrollRectToVisible(SelectionRevealMode revealMode, const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
{
+ if (revealMode == SelectionRevealMode::DoNotReveal)
+ return false;
+
RenderLayer* enclosingLayer = this->enclosingLayer();
if (!enclosingLayer)
return false;
- enclosingLayer->scrollRectToVisible(rect, alignX, alignY);
+ enclosingLayer->scrollRectToVisible(revealMode, rect, alignX, alignY);
return true;
}
Modified: trunk/Source/WebCore/rendering/RenderObject.h (202242 => 202243)
--- trunk/Source/WebCore/rendering/RenderObject.h 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebCore/rendering/RenderObject.h 2016-06-20 21:22:54 UTC (rev 202243)
@@ -155,7 +155,7 @@
WEBCORE_EXPORT RenderLayer* enclosingLayer() const;
// Scrolling is a RenderBox concept, however some code just cares about recursively scrolling our enclosing ScrollableArea(s).
- WEBCORE_EXPORT bool scrollRectToVisible(const LayoutRect&, const ScrollAlignment& alignX = ScrollAlignment::alignCenterIfNeeded, const ScrollAlignment& alignY = ScrollAlignment::alignCenterIfNeeded);
+ WEBCORE_EXPORT bool scrollRectToVisible(SelectionRevealMode, const LayoutRect&, const ScrollAlignment& alignX = ScrollAlignment::alignCenterIfNeeded, const ScrollAlignment& alignY = ScrollAlignment::alignCenterIfNeeded);
// Convenience function for getting to the nearest enclosing box of a RenderObject.
RenderBox& enclosingBox() const;
Modified: trunk/Source/WebKit/mac/ChangeLog (202242 => 202243)
--- trunk/Source/WebKit/mac/ChangeLog 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebKit/mac/ChangeLog 2016-06-20 21:22:54 UTC (rev 202243)
@@ -1,3 +1,21 @@
+2016-06-20 Simon Fraser <[email protected]>
+
+ Focus event dispatched in iframe causes parent document to scroll incorrectly
+ https://bugs.webkit.org/show_bug.cgi?id=158629
+ rdar://problem/26521616
+
+ Reviewed by Tim Horton.
+
+ Pass SelectionRevealMode::Reveal in existing code.
+
+ * WebView/WebFrame.mm:
+ (-[WebFrame _scrollDOMRangeToVisible:]):
+ (-[WebFrame _scrollDOMRangeToVisible:withInset:]):
+ (-[WebFrame revealSelectionAtExtent:]):
+ * WebView/WebHTMLView.mm:
+ (-[WebHTMLView jumpToSelection:]):
+ (-[WebHTMLView centerSelectionInVisibleArea:]):
+
2016-06-20 Keith Rollin <[email protected]>
Remove RefPtr::release() and change calls sites to use WTFMove()
Modified: trunk/Source/WebKit/mac/WebView/WebFrame.mm (202242 => 202243)
--- trunk/Source/WebKit/mac/WebView/WebFrame.mm 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebKit/mac/WebView/WebFrame.mm 2016-06-20 21:22:54 UTC (rev 202243)
@@ -717,12 +717,12 @@
if (startNode && startNode->renderer()) {
#if !PLATFORM(IOS)
- startNode->renderer()->scrollRectToVisible(enclosingIntRect(rangeRect), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
+ startNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, enclosingIntRect(rangeRect), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
#else
RenderLayer* layer = startNode->renderer()->enclosingLayer();
if (layer) {
layer->setAdjustForIOSCaretWhenScrolling(true);
- startNode->renderer()->scrollRectToVisible(enclosingIntRect(rangeRect), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
+ startNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, enclosingIntRect(rangeRect), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
layer->setAdjustForIOSCaretWhenScrolling(false);
_private->coreFrame->selection().setCaretRectNeedsUpdate();
_private->coreFrame->selection().updateAppearance();
@@ -741,7 +741,7 @@
RenderLayer* layer = startNode->renderer()->enclosingLayer();
if (layer) {
layer->setAdjustForIOSCaretWhenScrolling(true);
- startNode->renderer()->scrollRectToVisible(enclosingIntRect(rangeRect), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
+ startNode->renderer()->scrollRectToVisible(SelectionRevealMode::Reveal, enclosingIntRect(rangeRect), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
layer->setAdjustForIOSCaretWhenScrolling(false);
Frame *coreFrame = core(self);
@@ -1375,7 +1375,7 @@
{
WebCore::Frame *frame = core(self);
RevealExtentOption revealExtentOption = revealExtent ? RevealExtent : DoNotRevealExtent;
- frame->selection().revealSelection(ScrollAlignment::alignToEdgeIfNeeded, revealExtentOption);
+ frame->selection().revealSelection(SelectionRevealMode::Reveal, ScrollAlignment::alignToEdgeIfNeeded, revealExtentOption);
}
- (void)resetSelection
Modified: trunk/Source/WebKit/mac/WebView/WebHTMLView.mm (202242 => 202243)
--- trunk/Source/WebKit/mac/WebView/WebHTMLView.mm 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebKit/mac/WebView/WebHTMLView.mm 2016-06-20 21:22:54 UTC (rev 202243)
@@ -3146,7 +3146,7 @@
COMMAND_PROLOGUE
if (Frame* coreFrame = core([self _frame]))
- coreFrame->selection().revealSelection(ScrollAlignment::alignCenterAlways);
+ coreFrame->selection().revealSelection(SelectionRevealMode::Reveal, ScrollAlignment::alignCenterAlways);
}
#if !PLATFORM(IOS)
@@ -5345,7 +5345,7 @@
COMMAND_PROLOGUE
if (Frame* coreFrame = core([self _frame]))
- coreFrame->selection().revealSelection(ScrollAlignment::alignCenterAlways);
+ coreFrame->selection().revealSelection(SelectionRevealMode::Reveal, ScrollAlignment::alignCenterAlways);
}
#if !PLATFORM(IOS)
Modified: trunk/Source/WebKit2/ChangeLog (202242 => 202243)
--- trunk/Source/WebKit2/ChangeLog 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebKit2/ChangeLog 2016-06-20 21:22:54 UTC (rev 202243)
@@ -1,3 +1,16 @@
+2016-06-20 Simon Fraser <[email protected]>
+
+ Focus event dispatched in iframe causes parent document to scroll incorrectly
+ https://bugs.webkit.org/show_bug.cgi?id=158629
+ rdar://problem/26521616
+
+ Reviewed by Tim Horton.
+
+ Pass SelectionRevealMode::Reveal in existing code.
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::centerSelectionInVisibleArea):
+
2016-06-20 Keith Rollin <[email protected]>
Remove RefPtr::release() and change calls sites to use WTFMove()
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (202242 => 202243)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2016-06-20 20:52:45 UTC (rev 202242)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp 2016-06-20 21:22:54 UTC (rev 202243)
@@ -2396,7 +2396,7 @@
void WebPage::centerSelectionInVisibleArea()
{
Frame& frame = m_page->focusController().focusedOrMainFrame();
- frame.selection().revealSelection(ScrollAlignment::alignCenterAlways);
+ frame.selection().revealSelection(SelectionRevealMode::Reveal, ScrollAlignment::alignCenterAlways);
m_findController.showFindIndicatorInSelection();
}