*/
#include "config.h"
-#include "WebViewImpl.h"
-
-#include "CSSValueKeywords.h"
-#include "CompositionUnderlineVectorBuilder.h"
-#include "ContextFeaturesClientImpl.h"
-#include "DatabaseClientImpl.h"
-#include "FullscreenController.h"
-#include "GeolocationClientProxy.h"
-#include "GraphicsLayerFactoryChromium.h"
-#include "HTMLNames.h"
-#include "LinkHighlight.h"
-#include "LocalFileSystemClient.h"
-#include "MIDIClientProxy.h"
-#include "PopupContainer.h"
-#include "PrerendererClientImpl.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SpeechInputClientImpl.h"
-#include "SpeechRecognitionClientProxy.h"
-#include "StorageQuotaClientImpl.h"
-#include "ValidationMessageClientImpl.h"
-#include "ViewportAnchor.h"
-#include "WebAXObject.h"
-#include "WebActiveWheelFlingParameters.h"
-#include "WebAutofillClient.h"
-#include "WebDevToolsAgentImpl.h"
-#include "WebDevToolsAgentPrivate.h"
-#include "WebFrameImpl.h"
-#include "WebHitTestResult.h"
-#include "WebInputElement.h"
-#include "WebInputEventConversion.h"
-#include "WebMediaPlayerAction.h"
-#include "WebNode.h"
-#include "WebPagePopupImpl.h"
-#include "WebPlugin.h"
-#include "WebPluginAction.h"
-#include "WebPluginContainerImpl.h"
-#include "WebPopupMenuImpl.h"
-#include "WebRange.h"
-#include "WebSettingsImpl.h"
-#include "WebTextInputInfo.h"
-#include "WebViewClient.h"
-#include "WebWindowFeatures.h"
-#include "WorkerGlobalScopeProxyProviderImpl.h"
+#include "web/WebViewImpl.h"
+
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/clipboard/DataObject.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentMarkerController.h"
#include "core/dom/Text.h"
-#include "core/dom/WheelController.h"
#include "core/editing/Editor.h"
#include "core/editing/FrameSelection.h"
+#include "core/editing/HTMLInterchange.h"
#include "core/editing/InputMethodController.h"
#include "core/editing/TextIterator.h"
+#include "core/editing/markup.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/WheelEvent.h"
+#include "core/frame/EventHandlerRegistry.h"
#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/page/PointerLockController.h"
#include "core/page/ScopedPageLoadDeferrer.h"
#include "core/page/TouchDisambiguation.h"
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/RenderWidget.h"
#include "core/rendering/TextAutosizer.h"
#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "modules/device_orientation/DeviceOrientationInspectorAgent.h"
#include "modules/encryptedmedia/MediaKeysController.h"
-#include "modules/geolocation/GeolocationController.h"
+#include "modules/filesystem/InspectorFileSystemAgent.h"
#include "modules/indexeddb/InspectorIndexedDBAgent.h"
-#include "modules/notifications/NotificationController.h"
-#include "painting/ContinuousPainter.h"
+#include "modules/push_messaging/PushController.h"
#include "platform/ContextMenu.h"
#include "platform/ContextMenuItem.h"
#include "platform/Cursor.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/PlatformWheelEvent.h"
#include "platform/PopupMenuClient.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "platform/UserGestureIndicator.h"
#include "platform/exported/WebActiveGestureAnimation.h"
#include "public/platform/WebImage.h"
#include "public/platform/WebLayerTreeView.h"
#include "public/platform/WebVector.h"
+#include "public/web/WebAXObject.h"
+#include "public/web/WebActiveWheelFlingParameters.h"
+#include "public/web/WebAutofillClient.h"
+#include "public/web/WebFrameClient.h"
+#include "public/web/WebHitTestResult.h"
+#include "public/web/WebInputElement.h"
+#include "public/web/WebMediaPlayerAction.h"
+#include "public/web/WebNode.h"
+#include "public/web/WebPlugin.h"
+#include "public/web/WebPluginAction.h"
+#include "public/web/WebRange.h"
+#include "public/web/WebTextInputInfo.h"
+#include "public/web/WebViewClient.h"
+#include "public/web/WebWindowFeatures.h"
+#include "web/CompositionUnderlineVectorBuilder.h"
+#include "web/ContextFeaturesClientImpl.h"
+#include "web/DatabaseClientImpl.h"
+#include "web/FullscreenController.h"
+#include "web/GraphicsLayerFactoryChromium.h"
+#include "web/LinkHighlight.h"
+#include "web/NavigatorContentUtilsClientImpl.h"
+#include "web/PopupContainer.h"
+#include "web/PrerendererClientImpl.h"
+#include "web/SpeechRecognitionClientProxy.h"
+#include "web/StorageQuotaClientImpl.h"
+#include "web/ValidationMessageClientImpl.h"
+#include "web/ViewportAnchor.h"
+#include "web/WebDevToolsAgentImpl.h"
+#include "web/WebDevToolsAgentPrivate.h"
+#include "web/WebInputEventConversion.h"
+#include "web/WebLocalFrameImpl.h"
+#include "web/WebPagePopupImpl.h"
+#include "web/WebPluginContainerImpl.h"
+#include "web/WebPopupMenuImpl.h"
+#include "web/WebRemoteFrameImpl.h"
+#include "web/WebSettingsImpl.h"
+#include "web/WorkerGlobalScopeProxyProviderImpl.h"
+#include "web/painting/ContinuousPainter.h"
#include "wtf/CurrentTime.h"
#include "wtf/RefPtr.h"
#include "wtf/TemporaryChange.h"
#include <cmath> // for std::pow
using namespace WebCore;
-using namespace std;
// The following constants control parameters for automated scaling of webpages
// (such as due to a double tap gesture or find in page etc.). These are
return platformEventKeyState;
}
+namespace {
+
+class UserGestureNotifier {
+public:
+ // If a UserGestureIndicator is created for a user gesture during the
+ // lifetime of a UserGestureNotifier and *userGestureObserved is false,
+ // the object will notify the client and set *userGestureObserved to true.
+ UserGestureNotifier(WebAutofillClient*, bool* userGestureObserved);
+ ~UserGestureNotifier();
+
+private:
+ WebAutofillClient* const m_client;
+ bool* const m_userGestureObserved;
+};
+
+UserGestureNotifier::UserGestureNotifier(WebAutofillClient* client, bool* userGestureObserved)
+ : m_client(client)
+ , m_userGestureObserved(userGestureObserved)
+{
+ ASSERT(m_userGestureObserved);
+ if (m_client)
+ UserGestureIndicator::clearProcessedUserGestureInPast();
+}
+
+UserGestureNotifier::~UserGestureNotifier()
+{
+ if (!*m_userGestureObserved && UserGestureIndicator::processedUserGestureInPast()) {
+ *m_userGestureObserved = true;
+ if (m_client)
+ m_client->firstUserGestureObserved();
+ }
+}
+
+} // namespace
+
// WebView ----------------------------------------------------------------
WebView* WebView::create(WebViewClient* client)
void WebViewImpl::setMainFrame(WebFrame* frame)
{
- toWebFrameImpl(frame)->initializeAsMainFrame(page());
+ if (frame->isWebLocalFrame())
+ toWebLocalFrameImpl(frame)->initializeAsMainFrame(page());
+ else
+ toWebRemoteFrameImpl(frame)->initializeAsMainFrame(page());
}
void WebViewImpl::setAutofillClient(WebAutofillClient* autofillClient)
m_spellCheckClient = spellCheckClient;
}
-void WebViewImpl::setPasswordGeneratorClient(WebPasswordGeneratorClient* client)
-{
- m_passwordGeneratorClient = client;
-}
-
WebViewImpl::WebViewImpl(WebViewClient* client)
: m_client(client)
, m_autofillClient(0)
, m_spellCheckClient(0)
- , m_passwordGeneratorClient(0)
, m_chromeClientImpl(this)
, m_contextMenuClientImpl(this)
, m_dragClientImpl(this)
, m_zoomLevel(0)
, m_minimumZoomLevel(zoomFactorToZoomLevel(minTextSizeMultiplier))
, m_maximumZoomLevel(zoomFactorToZoomLevel(maxTextSizeMultiplier))
- , m_savedPageScaleFactor(0)
, m_doubleTapZoomPageScaleFactor(0)
, m_doubleTapZoomPending(false)
, m_enableFakePageScaleAnimationForTesting(false)
, m_imeAcceptEvents(true)
, m_operationsAllowed(WebDragOperationNone)
, m_dragOperation(WebDragOperationNone)
- , m_featureSwitchClient(adoptPtr(new ContextFeaturesClientImpl()))
, m_isTransparent(false)
, m_tabsToLinks(false)
, m_layerTreeView(0)
, m_graphicsLayerFactory(adoptPtr(new GraphicsLayerFactoryChromium(this)))
, m_isAcceleratedCompositingActive(false)
, m_layerTreeViewCommitsDeferred(false)
- , m_compositorCreationFailed(false)
+ , m_matchesHeuristicsForGpuRasterization(false)
, m_recreatingGraphicsContext(false)
-#if ENABLE(INPUT_SPEECH)
- , m_speechInputClient(SpeechInputClientImpl::create(client))
-#endif
- , m_speechRecognitionClient(SpeechRecognitionClientProxy::create(client ? client->speechRecognizer() : 0))
- , m_geolocationClientProxy(adoptPtr(new GeolocationClientProxy(client ? client->geolocationClient() : 0)))
- , m_userMediaClientImpl(this)
- , m_midiClientProxy(adoptPtr(new MIDIClientProxy(client ? client->webMIDIClient() : 0)))
- , m_navigatorContentUtilsClient(NavigatorContentUtilsClientImpl::create(this))
, m_flingModifier(0)
, m_flingSourceDevice(false)
, m_fullscreenController(FullscreenController::create(this))
, m_baseBackgroundColor(Color::white)
, m_backgroundColorOverride(Color::transparent)
, m_zoomFactorOverride(0)
+ , m_userGestureObserved(false)
{
Page::PageClients pageClients;
pageClients.chromeClient = &m_chromeClientImpl;
pageClients.spellCheckerClient = &m_spellCheckerClientImpl;
pageClients.storageClient = &m_storageClientImpl;
- m_page = adoptPtr(new Page(pageClients));
- provideUserMediaTo(*m_page, &m_userMediaClientImpl);
+ m_page = adoptPtrWillBeNoop(new Page(pageClients));
MediaKeysController::provideMediaKeysTo(*m_page, &m_mediaKeysClientImpl);
- provideMIDITo(*m_page, m_midiClientProxy.get());
-#if ENABLE(INPUT_SPEECH)
- provideSpeechInputTo(*m_page, m_speechInputClient.get());
-#endif
- provideSpeechRecognitionTo(*m_page, m_speechRecognitionClient.get());
- provideNotification(*m_page, notificationPresenterImpl());
- provideNavigatorContentUtilsTo(*m_page, m_navigatorContentUtilsClient.get());
+ provideSpeechRecognitionTo(*m_page, SpeechRecognitionClientProxy::create(client ? client->speechRecognizer() : 0));
+ provideNavigatorContentUtilsTo(*m_page, NavigatorContentUtilsClientImpl::create(this));
- provideContextFeaturesTo(*m_page, m_featureSwitchClient.get());
- if (RuntimeEnabledFeatures::deviceOrientationEnabled())
- DeviceOrientationInspectorAgent::provideTo(*m_page);
- provideGeolocationTo(*m_page, m_geolocationClientProxy.get());
- m_geolocationClientProxy->setController(GeolocationController::from(m_page.get()));
+ provideContextFeaturesTo(*m_page, ContextFeaturesClientImpl::create());
+ DeviceOrientationInspectorAgent::provideTo(*m_page);
- provideLocalFileSystemTo(*m_page, LocalFileSystemClient::create());
+ m_page->inspectorController().registerModuleAgent(InspectorFileSystemAgent::create(m_page.get()));
provideDatabaseClientTo(*m_page, DatabaseClientImpl::create());
InspectorIndexedDBAgent::provideTo(m_page.get());
provideStorageQuotaClientTo(*m_page, StorageQuotaClientImpl::create());
- m_validationMessage = ValidationMessageClientImpl::create(*this);
- m_page->setValidationMessageClient(m_validationMessage.get());
+ m_page->setValidationMessageClient(ValidationMessageClientImpl::create(*this));
provideWorkerGlobalScopeProxyProviderTo(*m_page, WorkerGlobalScopeProxyProviderImpl::create());
m_page->makeOrdinary();
if (m_client) {
+ providePushControllerTo(*m_page, m_client->webPushClient());
setDeviceScaleFactor(m_client->screenInfo().deviceScaleFactor);
setVisibilityState(m_client->visibilityState(), true);
}
ASSERT(!m_page);
}
-WebFrameImpl* WebViewImpl::mainFrameImpl()
+WebLocalFrameImpl* WebViewImpl::mainFrameImpl()
{
- return m_page ? WebFrameImpl::fromFrame(m_page->mainFrame()) : 0;
+ return m_page && m_page->mainFrame() && m_page->mainFrame()->isLocalFrame() ? WebLocalFrameImpl::fromFrame(m_page->deprecatedLocalMainFrame()) : 0;
}
bool WebViewImpl::tabKeyCyclesThroughElements() const
m_lastMouseDownPoint = WebPoint(event.x, event.y);
- if (event.button == WebMouseEvent::ButtonLeft) {
- IntPoint point(event.x, event.y);
- point = m_page->mainFrame()->view()->windowToContents(point);
- HitTestResult result(m_page->mainFrame()->eventHandler().hitTestResultAtPoint(point));
+ // Take capture on a mouse down on a plugin so we can send it mouse events.
+ // If the hit node is a plugin but a scrollbar is over it don't start mouse
+ // capture because it will interfere with the scrollbar receiving events.
+ IntPoint point(event.x, event.y);
+ if (event.button == WebMouseEvent::ButtonLeft && m_page->mainFrame()->isLocalFrame() && !m_page->deprecatedLocalMainFrame()->view()->scrollbarAtPoint(point)) {
+ point = m_page->deprecatedLocalMainFrame()->view()->windowToContents(point);
+ HitTestResult result(m_page->deprecatedLocalMainFrame()->eventHandler().hitTestResultAtPoint(point));
Node* hitNode = result.innerNonSharedNode();
- // Take capture on a mouse down on a plugin so we can send it mouse events.
- if (hitNode && hitNode->renderer() && hitNode->renderer()->isEmbeddedObject()) {
+ if (!result.scrollbar() && hitNode && hitNode->renderer() && hitNode->renderer()->isEmbeddedObject()) {
m_mouseCaptureNode = hitNode;
TRACE_EVENT_ASYNC_BEGIN0("input", "capturing mouse", this);
}
// Find the right target frame. See issue 1186900.
HitTestResult result = hitTestResultForWindowPos(pme.position());
- LocalFrame* targetFrame;
+ Frame* targetFrame;
if (result.innerNonSharedNode())
targetFrame = result.innerNonSharedNode()->document().frame();
else
targetFrame = m_page->focusController().focusedOrMainFrame();
+ if (!targetFrame->isLocalFrame())
+ return;
+
+ LocalFrame* targetLocalFrame = toLocalFrame(targetFrame);
+
#if OS(WIN)
- targetFrame->view()->setCursor(pointerCursor());
+ targetLocalFrame->view()->setCursor(pointerCursor());
#endif
m_contextMenuAllowed = true;
- targetFrame->eventHandler().sendContextMenuEvent(pme);
+ targetLocalFrame->eventHandler().sendContextMenuEvent(pme);
m_contextMenuAllowed = false;
// Actually showing the context menu is handled by the ContextMenuClient
// implementation...
return PageWidgetEventHandler::handleMouseWheel(mainFrame, event);
}
-void WebViewImpl::scrollBy(const WebFloatSize& delta)
+bool WebViewImpl::scrollBy(const WebFloatSize& delta, const WebFloatSize& velocity)
{
- if (m_flingSourceDevice == WebGestureEvent::Touchpad) {
+ if (m_flingSourceDevice == WebGestureDeviceTouchpad) {
WebMouseWheelEvent syntheticWheel;
const float tickDivisor = WebCore::WheelEvent::TickMultiplier;
syntheticWheel.globalY = m_globalPositionOnFlingStart.y;
syntheticWheel.modifiers = m_flingModifier;
- if (m_page && m_page->mainFrame() && m_page->mainFrame()->view())
- handleMouseWheel(*m_page->mainFrame(), syntheticWheel);
+ if (m_page && m_page->mainFrame() && m_page->mainFrame()->isLocalFrame() && m_page->deprecatedLocalMainFrame()->view())
+ return handleMouseWheel(*m_page->deprecatedLocalMainFrame(), syntheticWheel);
} else {
WebGestureEvent syntheticGestureEvent;
syntheticGestureEvent.globalX = m_globalPositionOnFlingStart.x;
syntheticGestureEvent.globalY = m_globalPositionOnFlingStart.y;
syntheticGestureEvent.modifiers = m_flingModifier;
- syntheticGestureEvent.sourceDevice = WebGestureEvent::Touchscreen;
+ syntheticGestureEvent.sourceDevice = WebGestureDeviceTouchscreen;
- if (m_page && m_page->mainFrame() && m_page->mainFrame()->view())
- handleGestureEvent(syntheticGestureEvent);
+ if (m_page && m_page->mainFrame() && m_page->mainFrame()->isLocalFrame() && m_page->deprecatedLocalMainFrame()->view())
+ return handleGestureEvent(syntheticGestureEvent);
}
+ return false;
}
bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event)
m_flingModifier = event.modifiers;
m_flingSourceDevice = event.sourceDevice;
OwnPtr<WebGestureCurve> flingCurve = adoptPtr(Platform::current()->createFlingAnimationCurve(event.sourceDevice, WebFloatPoint(event.data.flingStart.velocityX, event.data.flingStart.velocityY), WebSize()));
+ ASSERT(flingCurve);
m_gestureAnimation = WebActiveGestureAnimation::createAtAnimationStart(flingCurve.release(), this);
scheduleAnimation();
eventSwallowed = true;
scaledEvent.data.tap.height = event.data.tap.height / pageScaleFactor();
IntRect boundingBox(scaledEvent.x - scaledEvent.data.tap.width / 2, scaledEvent.y - scaledEvent.data.tap.height / 2, scaledEvent.data.tap.width, scaledEvent.data.tap.height);
Vector<IntRect> goodTargets;
- Vector<Node*> highlightNodes;
+ WillBeHeapVector<RawPtrWillBeMember<Node> > highlightNodes;
findGoodTouchTargets(boundingBox, mainFrameImpl()->frame(), goodTargets, highlightNodes);
// FIXME: replace touch adjustment code when numberOfGoodTargets == 1?
// Single candidate case is currently handled by: https://bugs.webkit.org/show_bug.cgi?id=85101
m_globalPositionOnFlingStart = parameters.globalPoint;
m_flingModifier = parameters.modifiers;
OwnPtr<WebGestureCurve> curve = adoptPtr(Platform::current()->createFlingAnimationCurve(parameters.sourceDevice, WebFloatPoint(parameters.delta), parameters.cumulativeScroll));
+ ASSERT(curve);
m_gestureAnimation = WebActiveGestureAnimation::createWithTimeOffset(curve.release(), this, parameters.startTime);
scheduleAnimation();
}
void WebViewImpl::getSelectionRootBounds(WebRect& bounds) const
{
- const LocalFrame* frame = focusedWebCoreFrame();
- if (!frame)
+ const Frame* frame = focusedWebCoreFrame();
+ if (!frame || !frame->isLocalFrame())
return;
- Element* root = frame->selection().rootEditableElementOrDocumentElement();
+ Element* root = toLocalFrame(frame)->selection().rootEditableElementOrDocumentElement();
if (!root)
return;
bounds = boundingBox;
}
+void WebViewImpl::acceptLanguagesChanged()
+{
+ if (!page())
+ return;
+
+ page()->acceptLanguagesChanged();
+}
+
bool WebViewImpl::handleKeyEvent(const WebKeyboardEvent& event)
{
ASSERT((event.type == WebInputEvent::RawKeyDown)
return true;
}
- RefPtr<LocalFrame> frame = focusedWebCoreFrame();
- if (!frame)
+ RefPtr<Frame> focusedFrame = focusedWebCoreFrame();
+ if (focusedFrame && focusedFrame->isRemoteFrameTemporary()) {
+ WebLocalFrameImpl* webFrame = WebLocalFrameImpl::fromFrame(toLocalFrameTemporary(focusedFrame.get()));
+ webFrame->client()->forwardInputEvent(&event);
+ return true;
+ }
+
+ if (!focusedFrame || !focusedFrame->isLocalFrame())
return false;
+ RefPtr<LocalFrame> frame = toLocalFrame(focusedFrame.get());
+
+ PlatformKeyboardEventBuilder evt(event);
+
+ if (frame->eventHandler().keyEvent(evt)) {
+ if (WebInputEvent::RawKeyDown == event.type) {
+ // Suppress the next keypress event unless the focused node is a plug-in node.
+ // (Flash needs these keypress events to handle non-US keyboards.)
+ Element* element = focusedElement();
+ if (!element || !element->renderer() || !element->renderer()->isEmbeddedObject())
+ m_suppressNextKeypressEvent = true;
+ }
+ return true;
+ }
+
#if !OS(MACOSX)
const WebInputEvent::Type contextMenuTriggeringEventType =
#if OS(WIN)
}
#endif // !OS(MACOSX)
- PlatformKeyboardEventBuilder evt(event);
-
- if (frame->eventHandler().keyEvent(evt)) {
- if (WebInputEvent::RawKeyDown == event.type) {
- // Suppress the next keypress event unless the focused node is a plug-in node.
- // (Flash needs these keypress events to handle non-US keyboards.)
- Element* element = focusedElement();
- if (!element || !element->renderer() || !element->renderer()->isEmbeddedObject())
- m_suppressNextKeypressEvent = true;
- }
- return true;
- }
-
return keyEventDefault(event);
}
if (m_pagePopup)
return m_pagePopup->handleKeyEvent(PlatformKeyboardEventBuilder(event));
- LocalFrame* frame = focusedWebCoreFrame();
+ LocalFrame* frame = toLocalFrame(focusedWebCoreFrame());
if (!frame)
return suppress;
const int absoluteSourceX = source.x + scrollOffset.width();
if (leftMargin > absoluteSourceX) {
leftMargin = absoluteSourceX;
- rightMargin = max(leftMargin, minimumMargin);
+ rightMargin = std::max(leftMargin, minimumMargin);
}
const int maximumRightMargin = maxSize.width - (source.width + absoluteSourceX);
if (rightMargin > maximumRightMargin) {
rightMargin = maximumRightMargin;
- leftMargin = min(leftMargin, max(rightMargin, minimumMargin));
+ leftMargin = std::min(leftMargin, std::max(rightMargin, minimumMargin));
}
const int newWidth = source.width + leftMargin + rightMargin;
static_cast<int>(minimumMargin * rect.width / m_size.width));
// Fit block to screen, respecting limits.
scale = static_cast<float>(m_size.width) / rect.width;
- scale = min(scale, legibleScale());
+ scale = std::min(scale, legibleScale());
if (pageScaleFactor() < defaultScaleWhenAlreadyLegible)
- scale = max(scale, defaultScaleWhenAlreadyLegible);
+ scale = std::max(scale, defaultScaleWhenAlreadyLegible);
scale = clampPageScaleFactorToLimits(scale);
}
} else {
// Ensure position we're zooming to (+ padding) isn't off the bottom of
// the screen.
- rect.y = max<float>(rect.y, hitPoint.y + padding - screenHeight);
+ rect.y = std::max<float>(rect.y, hitPoint.y + padding - screenHeight);
} // Otherwise top align the block.
// Do the same thing for horizontal alignment.
if (rect.width < screenWidth)
rect.x -= 0.5 * (screenWidth - rect.width);
else
- rect.x = max<float>(rect.x, hitPoint.x + padding - screenWidth);
+ rect.x = std::max<float>(rect.x, hitPoint.x + padding - screenWidth);
scroll.x = rect.x;
scroll.y = rect.y;
scroll = clampOffsetAtScale(scroll, scale);
}
-static bool invokesHandCursor(Node* node, bool shiftKey, LocalFrame* frame)
+static bool invokesHandCursor(Node* node, LocalFrame* frame)
{
if (!node || !node->renderer())
return false;
ECursor cursor = node->renderer()->style()->cursor();
return cursor == CURSOR_POINTER
- || (cursor == CURSOR_AUTO && frame->eventHandler().useHandCursor(node, node->isLink(), shiftKey));
+ || (cursor == CURSOR_AUTO && frame->eventHandler().useHandCursor(node, node->isLink()));
}
Node* WebViewImpl::bestTapNode(const PlatformGestureEvent& tapEvent)
{
- if (!m_page || !m_page->mainFrame())
+ if (!m_page || !m_page->mainFrame() || !m_page->mainFrame()->isLocalFrame())
return 0;
Node* bestTouchNode = 0;
IntPoint touchEventLocation(tapEvent.position());
- m_page->mainFrame()->eventHandler().adjustGesturePosition(tapEvent, touchEventLocation);
+ m_page->deprecatedLocalMainFrame()->eventHandler().adjustGesturePosition(tapEvent, touchEventLocation);
- IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(touchEventLocation);
- HitTestResult result = m_page->mainFrame()->eventHandler().hitTestResultAtPoint(hitTestPoint, HitTestRequest::TouchEvent | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
+ IntPoint hitTestPoint = m_page->deprecatedLocalMainFrame()->view()->windowToContents(touchEventLocation);
+ HitTestResult result = m_page->deprecatedLocalMainFrame()->eventHandler().hitTestResultAtPoint(hitTestPoint, HitTestRequest::TouchEvent | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
bestTouchNode = result.targetNode();
// We might hit something like an image map that has no renderer on it
// Check if we're in the subtree of a node with a hand cursor
// this is the heuristic we use to determine if we show a highlight on tap
- while (bestTouchNode && !invokesHandCursor(bestTouchNode, false, m_page->mainFrame()))
+ while (bestTouchNode && !invokesHandCursor(bestTouchNode, m_page->deprecatedLocalMainFrame()))
bestTouchNode = bestTouchNode->parentNode();
if (!bestTouchNode)
return 0;
// We should pick the largest enclosing node with hand cursor set.
- while (bestTouchNode->parentNode() && invokesHandCursor(bestTouchNode->parentNode(), false, m_page->mainFrame()))
+ while (bestTouchNode->parentNode() && invokesHandCursor(bestTouchNode->parentNode(), toLocalFrame(m_page->mainFrame())))
bestTouchNode = bestTouchNode->parentNode();
return bestTouchNode;
{
Node* touchNode = bestTapNode(tapEvent);
- Vector<Node*> highlightNodes;
+ WillBeHeapVector<RawPtrWillBeMember<Node> > highlightNodes;
highlightNodes.append(touchNode);
enableTapHighlights(highlightNodes);
}
-void WebViewImpl::enableTapHighlights(Vector<Node*>& highlightNodes)
+void WebViewImpl::enableTapHighlights(WillBeHeapVector<RawPtrWillBeMember<Node> >& highlightNodes)
{
if (highlightNodes.isEmpty())
return;
return true;
}
-void WebViewImpl::numberOfWheelEventHandlersChanged(unsigned numberOfWheelHandlers)
-{
- if (m_client)
- m_client->numberOfWheelEventHandlersChanged(numberOfWheelHandlers);
-}
-
void WebViewImpl::hasTouchEventHandlers(bool hasTouchHandlers)
{
if (m_client)
page()->contextMenuController().clearContextMenu();
m_contextMenuAllowed = true;
- LocalFrame* focusedFrame = page()->focusController().focusedOrMainFrame();
- bool handled = focusedFrame->eventHandler().sendContextMenuEventForKey();
+ Frame* focusedFrame = page()->focusController().focusedOrMainFrame();
+ if (!focusedFrame->isLocalFrame())
+ return false;
+ bool handled = toLocalFrame(focusedFrame)->eventHandler().sendContextMenuEventForKey();
m_contextMenuAllowed = false;
return handled;
}
bool WebViewImpl::keyEventDefault(const WebKeyboardEvent& event)
{
- LocalFrame* frame = focusedWebCoreFrame();
+ LocalFrame* frame = toLocalFrame(focusedWebCoreFrame());
if (!frame)
return false;
bool WebViewImpl::bubblingScroll(ScrollDirection scrollDirection, ScrollGranularity scrollGranularity)
{
- LocalFrame* frame = focusedWebCoreFrame();
+ LocalFrame* frame = toLocalFrame(focusedWebCoreFrame());
if (!frame)
return false;
m_selectPopup = popupContainer;
ASSERT(mainFrameImpl()->frame()->document());
Document& document = *mainFrameImpl()->frame()->document();
- WheelController::from(document)->didAddWheelEventHandler(document);
+ page()->frameHost().eventHandlerRegistry().didAddEventHandler(document, EventHandlerRegistry::WheelEvent);
}
void WebViewImpl::popupClosed(PopupContainer* popupContainer)
m_selectPopup = nullptr;
ASSERT(mainFrameImpl()->frame()->document());
Document& document = *mainFrameImpl()->frame()->document();
- WheelController::from(document)->didRemoveWheelEventHandler(document);
+ // Remove the handler we added in |popupOpened| conditionally, because the
+ // Document may have already removed it, for instance, due to a navigation.
+ EventHandlerRegistry* registry = &document.frameHost()->eventHandlerRegistry();
+ if (registry->eventHandlerTargets(EventHandlerRegistry::WheelEvent)->contains(&document))
+ registry->didRemoveEventHandler(document, EventHandlerRegistry::WheelEvent);
}
PagePopup* WebViewImpl::openPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView)
m_pagePopup = nullptr;
}
-LocalFrame* WebViewImpl::focusedWebCoreFrame() const
+Frame* WebViewImpl::focusedWebCoreFrame() const
{
return m_page ? m_page->focusController().focusedOrMainFrame() : 0;
}
if (m_page) {
// Initiate shutdown for the entire frameset. This will cause a lot of
// notifications to be sent.
- if (m_page->mainFrame())
- m_page->mainFrame()->loader().frameDetached();
-
+ m_page->willBeDestroyed();
m_page.clear();
}
mainFrameImpl()->frameView()->willStartLiveResize();
LocalFrame* frame = mainFrameImpl()->frame();
- WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(frame);
+ WebPluginContainerImpl* pluginContainer = WebLocalFrameImpl::pluginContainerFromFrame(frame);
if (pluginContainer)
pluginContainer->willStartLiveResize();
}
return m_size;
}
+void WebViewImpl::resizePinchViewport(const WebSize& newSize)
+{
+ if (!pinchVirtualViewportEnabled())
+ return;
+
+ page()->frameHost().pinchViewport().setSize(newSize);
+}
+
void WebViewImpl::resize(const WebSize& newSize)
{
if (m_shouldAutoResize || m_size == newSize)
m_size = newSize;
bool shouldAnchorAndRescaleViewport = settings()->mainFrameResizesAreOrientationChanges()
- && oldSize.width && oldContentsWidth && newSize.width != oldSize.width;
+ && oldSize.width && oldContentsWidth && newSize.width != oldSize.width && !m_fullscreenController->isFullscreen();
ViewportAnchor viewportAnchor(&mainFrameImpl()->frame()->eventHandler());
if (shouldAnchorAndRescaleViewport) {
FloatSize(viewportAnchorXCoord, viewportAnchorYCoord));
}
- updatePageDefinedViewportConstraints(mainFrameImpl()->frame()->document()->viewportDescription());
- updateMainFrameLayoutSize();
+ {
+ // Avoids unnecessary invalidations while various bits of state in FastTextAutosizer are updated.
+ FastTextAutosizer::DeferUpdatePageInfo deferUpdatePageInfo(page());
+
+ m_pageScaleConstraintsSet.didChangeViewSize(m_size);
- WebDevToolsAgentPrivate* agentPrivate = devToolsAgentPrivate();
- if (agentPrivate)
- agentPrivate->webViewResized(newSize);
- WebFrameImpl* webFrame = mainFrameImpl();
- if (webFrame->frameView()) {
- webFrame->frameView()->resize(m_size);
- if (page()->settings().pinchVirtualViewportEnabled())
+ updatePageDefinedViewportConstraints(mainFrameImpl()->frame()->document()->viewportDescription());
+ updateMainFrameLayoutSize();
+
+ // If the virtual viewport pinch mode is enabled, the main frame will be resized
+ // after layout so it can be sized to the contentsSize.
+ if (!pinchVirtualViewportEnabled() && mainFrameImpl()->frameView())
+ mainFrameImpl()->frameView()->resize(m_size);
+
+ if (pinchVirtualViewportEnabled())
page()->frameHost().pinchViewport().setSize(m_size);
+
+ // When device emulation is enabled, device size values may change - they are
+ // usually set equal to the view size. These values are not considered viewport-dependent
+ // (see MediaQueryExp::isViewportDependent), since they are only viewport-dependent in emulation mode,
+ // and thus will not be invalidated in |FrameView::performPreLayoutTasks|.
+ // Therefore we should force explicit media queries invalidation here.
+ if (page()->inspectorController().deviceEmulationEnabled()) {
+ if (Document* document = mainFrameImpl()->frame()->document())
+ document->mediaQueryAffectingValueChanged();
+ }
}
if (settings()->viewportEnabled() && !m_fixedLayoutSizeLock) {
mainFrameImpl()->frameView()->willEndLiveResize();
LocalFrame* frame = mainFrameImpl()->frame();
- WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(frame);
+ WebPluginContainerImpl* pluginContainer = WebLocalFrameImpl::pluginContainerFromFrame(frame);
if (pluginContainer)
pluginContainer->willEndLiveResize();
}
m_linkHighlights[i]->updateGeometry();
}
-void WebViewImpl::enterForceCompositingMode(bool enter)
+void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect)
{
- if (page()->settings().forceCompositingMode() == enter)
- return;
+ // This should only be used when compositing is not being used for this
+ // WebView, and it is painting into the recording of its parent.
+ ASSERT(!isAcceleratedCompositingActive());
- TRACE_EVENT1("webkit", "WebViewImpl::enterForceCompositingMode", "enter", enter);
- settingsImpl()->setForceCompositingMode(enter);
- if (enter) {
- if (!m_page)
- return;
- LocalFrame* mainFrame = m_page->mainFrame();
- if (!mainFrame)
- return;
- mainFrame->view()->updateCompositingLayersAfterStyleChange();
- }
+ double paintStart = currentTime();
+ PageWidgetDelegate::paint(m_page.get(), pageOverlays(), canvas, rect, isTransparent() ? PageWidgetDelegate::Translucent : PageWidgetDelegate::Opaque);
+ double paintEnd = currentTime();
+ double pixelsPerSec = (rect.width * rect.height) / (paintEnd - paintStart);
+ blink::Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintDurationMS", (paintEnd - paintStart) * 1000, 0, 120, 30);
+ blink::Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintMegapixPerSecond", pixelsPerSec / 1000000, 10, 210, 30);
}
-void WebViewImpl::doPixelReadbackToCanvas(WebCanvas* canvas, const IntRect& rect)
+#if OS(ANDROID)
+void WebViewImpl::paintCompositedDeprecated(WebCanvas* canvas, const WebRect& rect)
{
- ASSERT(m_layerTreeView);
-
- SkBitmap target;
- target.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height(), rect.width() * 4);
- target.allocPixels();
- m_layerTreeView->compositeAndReadback(target.getPixels(), rect);
-#if (!SK_R32_SHIFT && SK_B32_SHIFT == 16)
- // The compositor readback always gives back pixels in BGRA order, but for
- // example Android's Skia uses RGBA ordering so the red and blue channels
- // need to be swapped.
- uint8_t* pixels = reinterpret_cast<uint8_t*>(target.getPixels());
- for (size_t i = 0; i < target.getSize(); i += 4)
- std::swap(pixels[i], pixels[i + 2]);
-#endif
- canvas->writePixels(target, rect.x(), rect.y());
-}
+ // Note: This method exists on OS(ANDROID) and will hopefully be
+ // removed once the link disambiguation feature renders using
+ // the compositor.
+ ASSERT(isAcceleratedCompositingActive());
-void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect, PaintOptions option)
-{
-#if !OS(ANDROID)
- // ReadbackFromCompositorIfAvailable is the only option available on non-Android.
- // Ideally, Android would always use ReadbackFromCompositorIfAvailable as well.
- ASSERT(option == ReadbackFromCompositorIfAvailable);
-#endif
+ FrameView* view = page()->deprecatedLocalMainFrame()->view();
+ PaintBehavior oldPaintBehavior = view->paintBehavior();
+ view->setPaintBehavior(oldPaintBehavior | PaintBehaviorFlattenCompositingLayers);
- if (option == ReadbackFromCompositorIfAvailable && isAcceleratedCompositingActive()) {
- // If a canvas was passed in, we use it to grab a copy of the
- // freshly-rendered pixels.
- if (canvas) {
- // Clip rect to the confines of the rootLayerTexture.
- IntRect resizeRect(rect);
- resizeRect.intersect(IntRect(IntPoint(0, 0), m_layerTreeView->deviceViewportSize()));
- doPixelReadbackToCanvas(canvas, resizeRect);
- }
- } else {
- FrameView* view = page()->mainFrame()->view();
- PaintBehavior oldPaintBehavior = view->paintBehavior();
- if (isAcceleratedCompositingActive()) {
- ASSERT(option == ForceSoftwareRenderingAndIgnoreGPUResidentContent);
- view->setPaintBehavior(oldPaintBehavior | PaintBehaviorFlattenCompositingLayers);
- }
+ PageWidgetDelegate::paint(m_page.get(), pageOverlays(), canvas, rect, isTransparent() ? PageWidgetDelegate::Translucent : PageWidgetDelegate::Opaque);
- double paintStart = currentTime();
- PageWidgetDelegate::paint(m_page.get(), pageOverlays(), canvas, rect, isTransparent() ? PageWidgetDelegate::Translucent : PageWidgetDelegate::Opaque);
- double paintEnd = currentTime();
- double pixelsPerSec = (rect.width * rect.height) / (paintEnd - paintStart);
- blink::Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintDurationMS", (paintEnd - paintStart) * 1000, 0, 120, 30);
- blink::Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintMegapixPerSecond", pixelsPerSec / 1000000, 10, 210, 30);
+ view->setPaintBehavior(oldPaintBehavior);
+}
+#endif
- if (isAcceleratedCompositingActive()) {
- ASSERT(option == ForceSoftwareRenderingAndIgnoreGPUResidentContent);
- view->setPaintBehavior(oldPaintBehavior);
- }
- }
+void WebViewImpl::compositeAndReadbackAsync(WebCompositeAndReadbackAsyncCallback* callback)
+{
+ ASSERT(isAcceleratedCompositingActive());
+ m_layerTreeView->compositeAndReadbackAsync(callback);
}
bool WebViewImpl::isTrackingRepaints() const
{
if (!page())
return false;
- FrameView* view = page()->mainFrame()->view();
- return view->isTrackingRepaints();
+ if (!page()->mainFrame()->isLocalFrame())
+ return false;
+ FrameView* view = page()->deprecatedLocalMainFrame()->view();
+ return view->isTrackingPaintInvalidations();
}
void WebViewImpl::themeChanged()
{
if (!page())
return;
- FrameView* view = page()->mainFrame()->view();
+ if (!page()->mainFrame()->isLocalFrame())
+ return;
+ FrameView* view = page()->deprecatedLocalMainFrame()->view();
WebRect damagedRect(0, 0, m_size.width, m_size.height);
view->invalidateRect(damagedRect);
const WebInputEvent* WebViewImpl::m_currentInputEvent = 0;
+// FIXME: autogenerate this kind of code, and use it throughout Blink rather than
+// the one-offs for subsets of these values.
+static const AtomicString* inputTypeToName(WebInputEvent::Type type)
+{
+ switch (type) {
+ case WebInputEvent::MouseDown:
+ return &EventTypeNames::mousedown;
+ case WebInputEvent::MouseUp:
+ return &EventTypeNames::mouseup;
+ case WebInputEvent::MouseMove:
+ return &EventTypeNames::mousemove;
+ case WebInputEvent::MouseEnter:
+ return &EventTypeNames::mouseenter;
+ case WebInputEvent::MouseLeave:
+ return &EventTypeNames::mouseleave;
+ case WebInputEvent::ContextMenu:
+ return &EventTypeNames::contextmenu;
+ case WebInputEvent::MouseWheel:
+ return &EventTypeNames::mousewheel;
+ case WebInputEvent::KeyDown:
+ return &EventTypeNames::keydown;
+ case WebInputEvent::KeyUp:
+ return &EventTypeNames::keyup;
+ case WebInputEvent::GestureScrollBegin:
+ return &EventTypeNames::gesturescrollstart;
+ case WebInputEvent::GestureScrollEnd:
+ return &EventTypeNames::gesturescrollend;
+ case WebInputEvent::GestureScrollUpdate:
+ return &EventTypeNames::gesturescrollupdate;
+ case WebInputEvent::TouchStart:
+ return &EventTypeNames::touchstart;
+ case WebInputEvent::TouchMove:
+ return &EventTypeNames::touchmove;
+ case WebInputEvent::TouchEnd:
+ return &EventTypeNames::touchend;
+ case WebInputEvent::TouchCancel:
+ return &EventTypeNames::touchcancel;
+ default:
+ return 0;
+ }
+}
+
bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent)
{
- TRACE_EVENT0("input", "WebViewImpl::handleInputEvent");
+ UserGestureNotifier notifier(m_autofillClient, &m_userGestureObserved);
+ // On the first input event since page load, |notifier| instructs the
+ // autofill client to unblock values of password input fields of any forms
+ // on the page. There is a single input event, GestureTap, which can both
+ // be the first event after page load, and cause a form submission. In that
+ // case, the form submission happens before the autofill client is told
+ // to unblock the password values, and so the password values are not
+ // submitted. To avoid that, GestureTap is handled explicitly:
+ if (inputEvent.type == WebInputEvent::GestureTap && m_autofillClient) {
+ m_userGestureObserved = true;
+ m_autofillClient->firstUserGestureObserved();
+ }
+
+ const AtomicString* inputEventName = inputTypeToName(inputEvent.type);
+ TRACE_EVENT1("input", "WebViewImpl::handleInputEvent", "type", inputEventName ? inputEventName->ascii() : "unknown");
// If we've started a drag and drop operation, ignore input events until
// we're done.
if (m_doingDragAndDrop)
if (m_mouseCaptureNode && WebInputEvent::isMouseEventType(inputEvent.type)) {
TRACE_EVENT1("input", "captured mouse event", "type", inputEvent.type);
// Save m_mouseCaptureNode since mouseCaptureLost() will clear it.
- RefPtr<Node> node = m_mouseCaptureNode;
+ RefPtrWillBeRawPtr<Node> node = m_mouseCaptureNode;
// Not all platforms call mouseCaptureLost() directly.
if (inputEvent.type == WebInputEvent::MouseUp)
m_page->focusController().setFocused(enable);
if (enable) {
m_page->focusController().setActive(true);
- RefPtr<LocalFrame> focusedFrame = m_page->focusController().focusedFrame();
- if (focusedFrame) {
- Element* element = focusedFrame->document()->focusedElement();
- if (element && focusedFrame->selection().selection().isNone()) {
+ RefPtr<Frame> focusedFrame = m_page->focusController().focusedFrame();
+ if (focusedFrame && focusedFrame->isLocalFrame()) {
+ LocalFrame* localFrame = toLocalFrame(focusedFrame.get());
+ Element* element = localFrame->document()->focusedElement();
+ if (element && localFrame->selection().selection().isNone()) {
// If the selection was cleared while the WebView was not
// focused, then the focus element shows with a focus ring but
// no caret and does respond to keyboard inputs.
// instead. Note that this has the side effect of moving the
// caret back to the beginning of the text.
Position position(element, 0, Position::PositionIsOffsetInAnchor);
- focusedFrame->selection().setSelection(VisibleSelection(position, SEL_DEFAULT_AFFINITY));
+ localFrame->selection().setSelection(VisibleSelection(position, SEL_DEFAULT_AFFINITY));
}
}
}
if (!m_page)
return;
- LocalFrame* frame = m_page->mainFrame();
+ LocalFrame* frame = m_page->mainFrame() && m_page->mainFrame()->isLocalFrame()
+ ? m_page->deprecatedLocalMainFrame() : 0;
if (!frame)
return;
- RefPtr<LocalFrame> focusedFrame = m_page->focusController().focusedFrame();
- if (focusedFrame) {
+ RefPtr<Frame> focusedFrame = m_page->focusController().focusedFrame();
+ if (focusedFrame && focusedFrame->isLocalFrame()) {
// Finish an ongoing composition to delete the composition node.
- if (focusedFrame->inputMethodController().hasComposition()) {
+ if (toLocalFrame(focusedFrame.get())->inputMethodController().hasComposition()) {
if (m_autofillClient)
m_autofillClient->setIgnoreTextChanges(true);
- focusedFrame->inputMethodController().confirmComposition();
+ toLocalFrame(focusedFrame.get())->inputMethodController().confirmComposition();
if (m_autofillClient)
m_autofillClient->setIgnoreTextChanges(false);
int selectionStart,
int selectionEnd)
{
- LocalFrame* focused = focusedWebCoreFrame();
+ LocalFrame* focused = toLocalFrame(focusedWebCoreFrame());
if (!focused || !m_imeAcceptEvents)
return false;
// editable because JavaScript may delete a parent node of the composition
// node. In this case, WebKit crashes while deleting texts from the parent
// node, which doesn't exist any longer.
- RefPtr<Range> range = inputMethodController.compositionRange();
+ RefPtrWillBeRawPtr<Range> range = inputMethodController.compositionRange();
if (range) {
Node* node = range->startContainer();
if (!node || !node->isContentEditable())
bool WebViewImpl::confirmComposition(const WebString& text, ConfirmCompositionBehavior selectionBehavior)
{
- LocalFrame* focused = focusedWebCoreFrame();
+ LocalFrame* focused = toLocalFrame(focusedWebCoreFrame());
if (!focused || !m_imeAcceptEvents)
return false;
bool WebViewImpl::compositionRange(size_t* location, size_t* length)
{
- LocalFrame* focused = focusedWebCoreFrame();
+ LocalFrame* focused = toLocalFrame(focusedWebCoreFrame());
if (!focused || !m_imeAcceptEvents)
return false;
- RefPtr<Range> range = focused->inputMethodController().compositionRange();
+ RefPtrWillBeRawPtr<Range> range = focused->inputMethodController().compositionRange();
if (!range)
return false;
{
WebTextInputInfo info;
- LocalFrame* focused = focusedWebCoreFrame();
+ LocalFrame* focused = toLocalFrame(focusedWebCoreFrame());
if (!focused)
return info;
if (!focused->editor().canEdit())
return info;
- info.value = plainText(rangeOfContents(node).get());
+ // Emits an object replacement character for each replaced element so that
+ // it is exposed to IME and thus could be deleted by IME on android.
+ info.value = plainText(rangeOfContents(node).get(), TextIteratorEmitsObjectReplacementCharacter);
if (info.value.isEmpty())
return info;
- if (RefPtr<Range> range = selection.selection().firstRange()) {
+ if (RefPtrWillBeRawPtr<Range> range = selection.selection().firstRange()) {
PlainTextRange plainTextRange(PlainTextRange::create(*node, *range.get()));
if (plainTextRange.isNotNull()) {
info.selectionStart = plainTextRange.start();
}
}
- if (RefPtr<Range> range = focused->inputMethodController().compositionRange()) {
+ if (RefPtrWillBeRawPtr<Range> range = focused->inputMethodController().compositionRange()) {
PlainTextRange plainTextRange(PlainTextRange::create(*node, *range.get()));
if (plainTextRange.isNotNull()) {
info.compositionStart = plainTextRange.start();
bool WebViewImpl::selectionBounds(WebRect& anchor, WebRect& focus) const
{
- const LocalFrame* frame = focusedWebCoreFrame();
+ const LocalFrame* frame = toLocalFrame(focusedWebCoreFrame());
if (!frame)
return false;
FrameSelection& selection = frame->selection();
if (selection.isCaret()) {
anchor = focus = selection.absoluteCaretBounds();
} else {
- RefPtr<Range> selectedRange = selection.toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> selectedRange = selection.toNormalizedRange();
if (!selectedRange)
return false;
- RefPtr<Range> range(Range::create(selectedRange->startContainer()->document(),
+ RefPtrWillBeRawPtr<Range> range(Range::create(selectedRange->startContainer()->document(),
selectedRange->startContainer(),
selectedRange->startOffset(),
selectedRange->startContainer(),
IntRect scaledAnchor(frame->view()->contentsToWindow(anchor));
IntRect scaledFocus(frame->view()->contentsToWindow(focus));
+
+ if (pinchVirtualViewportEnabled()) {
+ // FIXME(http://crbug.com/371902) - We shouldn't have to do this
+ // manually, the contentsToWindow methods above should be fixed to do
+ // this.
+ IntPoint pinchViewportOffset =
+ roundedIntPoint(page()->frameHost().pinchViewport().visibleRect().location());
+ scaledAnchor.moveBy(-pinchViewportOffset);
+ scaledFocus.moveBy(-pinchViewportOffset);
+ }
+
scaledAnchor.scale(pageScaleFactor());
scaledFocus.scale(pageScaleFactor());
anchor = scaledAnchor;
if (!m_imeAcceptEvents)
return 0;
- LocalFrame* focusedFrame = focusedWebCoreFrame();
+ LocalFrame* focusedFrame = toLocalFrame(focusedWebCoreFrame());
if (!focusedFrame)
return 0;
WebPlugin* WebViewImpl::focusedPluginIfInputMethodSupported(LocalFrame* frame)
{
- WebPluginContainerImpl* container = WebFrameImpl::pluginContainerFromNode(frame, WebNode(focusedElement()));
+ WebPluginContainerImpl* container = WebLocalFrameImpl::pluginContainerFromNode(frame, WebNode(focusedElement()));
if (container && container->supportsInputMethod())
return container->plugin();
return 0;
bool WebViewImpl::selectionTextDirection(WebTextDirection& start, WebTextDirection& end) const
{
- const LocalFrame* frame = focusedWebCoreFrame();
+ const LocalFrame* frame = toLocalFrame(focusedWebCoreFrame());
if (!frame)
return false;
FrameSelection& selection = frame->selection();
bool WebViewImpl::isSelectionAnchorFirst() const
{
- if (const LocalFrame* frame = focusedWebCoreFrame())
+ if (const LocalFrame* frame = toLocalFrame(focusedWebCoreFrame()))
return frame->selection().selection().isBaseFirst();
return false;
}
WebVector<WebCompositionUnderline> WebViewImpl::compositionUnderlines() const
{
- const LocalFrame* focused = focusedWebCoreFrame();
+ const LocalFrame* focused = toLocalFrame(focusedWebCoreFrame());
if (!focused)
return WebVector<WebCompositionUnderline>();
const Vector<CompositionUnderline>& underlines = focused->inputMethodController().customCompositionUnderlines();
WebVector<WebCompositionUnderline> results(underlines.size());
for (size_t index = 0; index < underlines.size(); ++index) {
CompositionUnderline underline = underlines[index];
- results[index] = WebCompositionUnderline(underline.startOffset, underline.endOffset, static_cast<WebColor>(underline.color.rgb()), underline.thick);
+ results[index] = WebCompositionUnderline(underline.startOffset, underline.endOffset, static_cast<WebColor>(underline.color.rgb()), underline.thick, static_cast<WebColor>(underline.backgroundColor.rgb()));
}
return results;
}
return m_baseBackgroundColor;
if (!m_page->mainFrame())
return m_baseBackgroundColor;
- FrameView* view = m_page->mainFrame()->view();
+ if (!m_page->mainFrame()->isLocalFrame())
+ return m_baseBackgroundColor;
+ FrameView* view = m_page->deprecatedLocalMainFrame()->view();
return view->documentBackgroundColor().rgb();
}
bool WebViewImpl::caretOrSelectionRange(size_t* location, size_t* length)
{
- const LocalFrame* focused = focusedWebCoreFrame();
+ const LocalFrame* focused = toLocalFrame(focusedWebCoreFrame());
if (!focused)
return false;
// the text direction of the selected node and updates its DOM "dir"
// attribute and its CSS "direction" property.
// So, we just call the function as Safari does.
- const LocalFrame* focused = focusedWebCoreFrame();
+ const LocalFrame* focused = toLocalFrame(focusedWebCoreFrame());
if (!focused)
return;
if (!m_page)
return WebString();
+ if (!m_page->mainFrame()->isLocalFrame())
+ return WebString();
+
// FIXME: Is this check needed?
- if (!m_page->mainFrame()->document()->loader())
+ if (!m_page->deprecatedLocalMainFrame()->document()->loader())
return WebString();
- return m_page->mainFrame()->document()->encodingName();
+ return m_page->deprecatedLocalMainFrame()->document()->encodingName();
}
void WebViewImpl::setPageEncoding(const WebString& encodingName)
if (!m_page)
return;
+ if (!m_page->mainFrame()->isLocalFrame())
+ return;
+
// Only change override encoding, don't change default encoding.
// Note that the new encoding must be 0 if it isn't supposed to be set.
AtomicString newEncodingName;
if (!encodingName.isEmpty())
newEncodingName = encodingName;
- m_page->mainFrame()->loader().reload(NormalReload, KURL(), newEncodingName);
-}
-
-bool WebViewImpl::dispatchBeforeUnloadEvent()
-{
- // FIXME: This should really cause a recursive depth-first walk of all
- // frames in the tree, calling each frame's onbeforeunload. At the moment,
- // we're consistent with Safari 3.1, not IE/FF.
- LocalFrame* frame = m_page->mainFrame();
- if (!frame)
- return true;
-
- return frame->loader().shouldClose();
-}
-
-void WebViewImpl::dispatchUnloadEvent()
-{
- // Run unload handlers.
- m_page->mainFrame()->loader().closeURL();
+ m_page->deprecatedLocalMainFrame()->loader().reload(NormalReload, KURL(), newEncodingName);
}
WebFrame* WebViewImpl::mainFrame()
{
- return mainFrameImpl();
+ return WebFrame::fromFrame(m_page ? m_page->mainFrame() : 0);
}
WebFrame* WebViewImpl::findFrameByName(
const WebString& name, WebFrame* relativeToFrame)
{
+ // FIXME: Either this should only deal with WebLocalFrames or it should move to WebFrame.
if (!relativeToFrame)
relativeToFrame = mainFrame();
- LocalFrame* frame = toWebFrameImpl(relativeToFrame)->frame();
+ Frame* frame = toWebLocalFrameImpl(relativeToFrame)->frame();
frame = frame->tree().find(name);
- return WebFrameImpl::fromFrame(frame);
+ if (!frame || !frame->isLocalFrame())
+ return 0;
+ return WebLocalFrameImpl::fromFrame(toLocalFrame(frame));
}
WebFrame* WebViewImpl::focusedFrame()
{
- return WebFrameImpl::fromFrame(focusedWebCoreFrame());
+ return WebLocalFrameImpl::fromFrame(toLocalFrame(focusedWebCoreFrame()));
}
void WebViewImpl::setFocusedFrame(WebFrame* frame)
{
if (!frame) {
// Clears the focused frame if any.
- if (LocalFrame* focusedFrame = focusedWebCoreFrame())
- focusedFrame->selection().setFocused(false);
+ Frame* focusedFrame = focusedWebCoreFrame();
+ if (focusedFrame && focusedFrame->isLocalFrame())
+ toLocalFrame(focusedFrame)->selection().setFocused(false);
return;
}
- LocalFrame* webcoreFrame = toWebFrameImpl(frame)->frame();
+ LocalFrame* webcoreFrame = toWebLocalFrameImpl(frame)->frame();
webcoreFrame->page()->focusController().setFocusedFrame(webcoreFrame);
}
{
if (!m_page)
return;
- LocalFrame* frame = page()->focusController().focusedOrMainFrame();
- if (Document* document = frame->document())
- document->setFocusedElement(nullptr);
+ Frame* frame = page()->focusController().focusedOrMainFrame();
+ if (frame->isLocalFrame()) {
+ if (Document* document = toLocalFrame(frame)->document())
+ document->setFocusedElement(nullptr);
+ }
page()->focusController().setInitialFocus(reverse ? FocusTypeBackward : FocusTypeForward);
}
void WebViewImpl::clearFocusedElement()
{
- RefPtr<LocalFrame> frame = focusedWebCoreFrame();
- if (!frame)
+ RefPtr<Frame> frame = focusedWebCoreFrame();
+ if (!frame || !frame->isLocalFrame())
return;
- RefPtr<Document> document = frame->document();
+ LocalFrame* localFrame = toLocalFrame(frame.get());
+
+ RefPtrWillBeRawPtr<Document> document = localFrame->document();
if (!document)
return;
- RefPtr<Element> oldFocusedElement = document->focusedElement();
+ RefPtrWillBeRawPtr<Element> oldFocusedElement = document->focusedElement();
// Clear the focused node.
document->setFocusedElement(nullptr);
// processing keyboard events even though focus has been moved to the page and
// keystrokes get eaten as a result.
if (oldFocusedElement->isContentEditable() || oldFocusedElement->isTextFormControl())
- frame->selection().clear();
-}
-
-void WebViewImpl::scrollFocusedNodeIntoView()
-{
- if (Element* element = focusedElement())
- element->scrollIntoViewIfNeeded(true);
+ localFrame->selection().clear();
}
void WebViewImpl::scrollFocusedNodeIntoRect(const WebRect& rect)
{
- LocalFrame* frame = page()->mainFrame();
+ LocalFrame* frame = page()->mainFrame() && page()->mainFrame()->isLocalFrame()
+ ? page()->deprecatedLocalMainFrame() : 0;
Element* element = focusedElement();
if (!frame || !frame->view() || !element)
return;
// onscreen.
int idealLeftPadding = viewWidth * leftBoxRatio;
int maxLeftPaddingKeepingBoxOnscreen = viewWidth - textboxRectInDocumentCoordinates.width();
- newScroll.setX(textboxRectInDocumentCoordinates.x() - min<int>(idealLeftPadding, maxLeftPaddingKeepingBoxOnscreen));
+ newScroll.setX(textboxRectInDocumentCoordinates.x() - std::min<int>(idealLeftPadding, maxLeftPaddingKeepingBoxOnscreen));
} else {
// Field is wider than screen. Try to left-align field, unless caret would
// be offscreen, in which case right-align the caret.
- newScroll.setX(max<int>(textboxRectInDocumentCoordinates.x(), caretInDocumentCoordinates.x() + caretInDocumentCoordinates.width() + caretPadding - viewWidth));
+ newScroll.setX(std::max<int>(textboxRectInDocumentCoordinates.x(), caretInDocumentCoordinates.x() + caretInDocumentCoordinates.width() + caretPadding - viewWidth));
}
if (textboxRectInDocumentCoordinates.height() <= viewHeight) {
// Field is shorter than screen. Vertically center it.
} else {
// Field is taller than screen. Try to top align field, unless caret would
// be offscreen, in which case bottom-align the caret.
- newScroll.setY(max<int>(textboxRectInDocumentCoordinates.y(), caretInDocumentCoordinates.y() + caretInDocumentCoordinates.height() + caretPadding - viewHeight));
+ newScroll.setY(std::max<int>(textboxRectInDocumentCoordinates.y(), caretInDocumentCoordinates.y() + caretInDocumentCoordinates.height() + caretPadding - viewHeight));
}
needAnimation = false;
m_zoomLevel = zoomLevel;
LocalFrame* frame = mainFrameImpl()->frame();
- WebPluginContainerImpl* pluginContainer = WebFrameImpl::pluginContainerFromFrame(frame);
+ WebPluginContainerImpl* pluginContainer = WebLocalFrameImpl::pluginContainerFromFrame(frame);
if (pluginContainer)
pluginContainer->plugin()->setZoomLevel(m_zoomLevel, false);
else {
float WebViewImpl::setTextZoomFactor(float textZoomFactor)
{
LocalFrame* frame = mainFrameImpl()->frame();
- if (WebFrameImpl::pluginContainerFromFrame(frame))
+ if (WebLocalFrameImpl::pluginContainerFromFrame(frame))
return 1;
frame->setTextZoomFactor(textZoomFactor);
if (zoomLevel == m_zoomLevel)
return;
- m_zoomLevel = max(min(zoomLevel, m_maximumZoomLevel), m_minimumZoomLevel);
+ m_zoomLevel = std::max(std::min(zoomLevel, m_maximumZoomLevel), m_minimumZoomLevel);
m_client->zoomLevelChanged();
}
if (!page())
return 1;
- return page()->pageScaleFactor();
+ if (!pinchVirtualViewportEnabled())
+ return page()->pageScaleFactor();
+
+ return page()->frameHost().pinchViewport().scale();
}
float WebViewImpl::clampPageScaleFactorToLimits(float scaleFactor) const
return view->clampOffsetAtScale(offset, scale);
}
-void WebViewImpl::setPageScaleFactor(float scaleFactor, const WebPoint& origin)
+bool WebViewImpl::pinchVirtualViewportEnabled() const
{
- if (!page())
+ ASSERT(page());
+ return page()->settings().pinchVirtualViewportEnabled();
+}
+
+void WebViewImpl::setPinchViewportOffset(const WebFloatPoint& offset)
+{
+ ASSERT(page());
+
+ if (!pinchVirtualViewportEnabled())
return;
- IntPoint newScrollOffset = origin;
+ page()->frameHost().pinchViewport().setLocation(offset);
+}
+
+WebFloatPoint WebViewImpl::pinchViewportOffset() const
+{
+ ASSERT(page());
+
+ if (!pinchVirtualViewportEnabled())
+ return WebFloatPoint();
+
+ return page()->frameHost().pinchViewport().visibleRect().location();
+}
+
+void WebViewImpl::setPageScaleFactor(float scaleFactor)
+{
+ ASSERT(page());
+
scaleFactor = clampPageScaleFactorToLimits(scaleFactor);
- newScrollOffset = clampOffsetAtScale(newScrollOffset, scaleFactor);
+ if (scaleFactor == pageScaleFactor())
+ return;
+
+ // TODO(bokan): Old-style pinch path. Remove when we're migrated to
+ // virtual viewport pinch.
+ if (!pinchVirtualViewportEnabled()) {
+ IntPoint scrollOffset(mainFrame()->scrollOffset().width, mainFrame()->scrollOffset().height);
+ setPageScaleFactor(scaleFactor, scrollOffset);
+ return;
+ }
+
+ page()->frameHost().pinchViewport().setScale(scaleFactor);
+ deviceOrPageScaleFactorChanged();
+}
- page()->setPageScaleFactor(scaleFactor, newScrollOffset);
+void WebViewImpl::setMainFrameScrollOffset(const WebPoint& origin)
+{
+ updateMainFrameScrollPosition(origin, false);
}
-void WebViewImpl::setPageScaleFactorPreservingScrollOffset(float scaleFactor)
+void WebViewImpl::setPageScaleFactor(float scaleFactor, const WebPoint& origin)
{
- if (clampPageScaleFactorToLimits(scaleFactor) == pageScaleFactor())
+ if (!page())
return;
- IntPoint scrollOffset(mainFrame()->scrollOffset().width, mainFrame()->scrollOffset().height);
- setPageScaleFactor(scaleFactor, scrollOffset);
+ IntPoint newScrollOffset = origin;
+ scaleFactor = clampPageScaleFactorToLimits(scaleFactor);
+ newScrollOffset = clampOffsetAtScale(newScrollOffset, scaleFactor);
+
+ if (pinchVirtualViewportEnabled())
+ setPageScaleFactor(scaleFactor);
+ // Note, we don't set the offset in the new path. This method is going
+ // away for the new pinch model so that's ok.
+ else
+ page()->setPageScaleFactor(scaleFactor, newScrollOffset);
}
+
float WebViewImpl::deviceScaleFactor() const
{
if (!page())
void WebViewImpl::refreshPageScaleFactorAfterLayout()
{
- if (!mainFrame() || !page() || !page()->mainFrame() || !page()->mainFrame()->view())
+ if (!mainFrame() || !page() || !page()->mainFrame() || !page()->mainFrame()->isLocalFrame() || !page()->deprecatedLocalMainFrame()->view())
return;
- FrameView* view = page()->mainFrame()->view();
+ FrameView* view = page()->deprecatedLocalMainFrame()->view();
updatePageDefinedViewportConstraints(mainFrameImpl()->frame()->document()->viewportDescription());
m_pageScaleConstraintsSet.computeFinalConstraints();
- if (settings()->viewportEnabled() && !m_fixedLayoutSizeLock) {
+ if (settings()->shrinksViewportContentToFit() && !m_fixedLayoutSizeLock) {
int verticalScrollbarWidth = 0;
if (view->verticalScrollbar() && !view->verticalScrollbar()->isOverlayScrollbar())
verticalScrollbarWidth = view->verticalScrollbar()->width();
- m_pageScaleConstraintsSet.adjustFinalConstraintsToContentsSize(m_size, contentsSize(), verticalScrollbarWidth);
+ m_pageScaleConstraintsSet.adjustFinalConstraintsToContentsSize(contentsSize(), verticalScrollbarWidth);
}
+ if (pinchVirtualViewportEnabled())
+ mainFrameImpl()->frameView()->resize(m_pageScaleConstraintsSet.mainFrameSize(contentsSize()));
+
float newPageScaleFactor = pageScaleFactor();
if (m_pageScaleConstraintsSet.needsReset() && m_pageScaleConstraintsSet.finalConstraints().initialScale != -1) {
newPageScaleFactor = m_pageScaleConstraintsSet.finalConstraints().initialScale;
m_pageScaleConstraintsSet.setNeedsReset(false);
}
- setPageScaleFactorPreservingScrollOffset(newPageScaleFactor);
+ setPageScaleFactor(newPageScaleFactor);
updateLayerTreeViewport();
void WebViewImpl::updatePageDefinedViewportConstraints(const ViewportDescription& description)
{
- if (!settings()->viewportEnabled() || !page() || (!m_size.width && !m_size.height))
+ if (!settings()->viewportEnabled() || !page() || (!m_size.width && !m_size.height) || !page()->mainFrame()->isLocalFrame())
return;
+ Document* document = page()->deprecatedLocalMainFrame()->document();
+
+ if (settingsImpl()->useExpandedHeuristicsForGpuRasterization()) {
+ m_matchesHeuristicsForGpuRasterization = description.maxWidth == Length(DeviceWidth)
+ && description.minZoom == 1.0
+ && description.minZoomIsExplicit;
+ } else {
+ m_matchesHeuristicsForGpuRasterization = description.maxWidth == Length(DeviceWidth)
+ && description.minZoom == 1.0
+ && description.minZoomIsExplicit
+ && description.zoom == 1.0
+ && description.zoomIsExplicit
+ && description.userZoom
+ && description.userZoomIsExplicit;
+ }
+ if (m_layerTreeView)
+ m_layerTreeView->heuristicsForGpuRasterizationUpdated(m_matchesHeuristicsForGpuRasterization);
+
+ Length defaultMinWidth = document->viewportDefaultMinWidth();
+ if (defaultMinWidth.isAuto())
+ defaultMinWidth = Length(ExtendToZoom);
+
ViewportDescription adjustedDescription = description;
if (settingsImpl()->viewportMetaLayoutSizeQuirk() && adjustedDescription.type == ViewportDescription::ViewportMeta) {
- if (adjustedDescription.maxWidth.type() == ExtendToZoom)
- adjustedDescription.maxWidth = Length(); // auto
const int legacyWidthSnappingMagicNumber = 320;
if (adjustedDescription.maxWidth.isFixed() && adjustedDescription.maxWidth.value() <= legacyWidthSnappingMagicNumber)
adjustedDescription.maxWidth = Length(DeviceWidth);
adjustedDescription.minWidth = adjustedDescription.maxWidth;
adjustedDescription.minHeight = adjustedDescription.maxHeight;
}
+
float oldInitialScale = m_pageScaleConstraintsSet.pageDefinedConstraints().initialScale;
- m_pageScaleConstraintsSet.updatePageDefinedConstraints(adjustedDescription, m_size);
+ m_pageScaleConstraintsSet.updatePageDefinedConstraints(adjustedDescription, defaultMinWidth);
if (settingsImpl()->clobberUserAgentInitialScaleQuirk()
&& m_pageScaleConstraintsSet.userAgentConstraints().initialScale != -1
&& m_pageScaleConstraintsSet.userAgentConstraints().initialScale * deviceScaleFactor() <= 1) {
if (description.maxWidth == Length(DeviceWidth)
- || (description.maxWidth.type() == ExtendToZoom && m_pageScaleConstraintsSet.pageDefinedConstraints().initialScale == 1.0f))
+ || (description.maxWidth.type() == Auto && m_pageScaleConstraintsSet.pageDefinedConstraints().initialScale == 1.0f))
setInitialPageScaleOverride(-1);
}
- m_pageScaleConstraintsSet.adjustForAndroidWebViewQuirks(adjustedDescription, m_size, page()->settings().layoutFallbackWidth(), deviceScaleFactor(), settingsImpl()->supportDeprecatedTargetDensityDPI(), page()->settings().wideViewportQuirkEnabled(), page()->settings().useWideViewport(), page()->settings().loadWithOverviewMode(), settingsImpl()->viewportMetaNonUserScalableQuirk());
+
+ m_pageScaleConstraintsSet.adjustForAndroidWebViewQuirks(adjustedDescription, defaultMinWidth.intValue(), deviceScaleFactor(), settingsImpl()->supportDeprecatedTargetDensityDPI(), page()->settings().wideViewportQuirkEnabled(), page()->settings().useWideViewport(), page()->settings().loadWithOverviewMode(), settingsImpl()->viewportMetaNonUserScalableQuirk());
float newInitialScale = m_pageScaleConstraintsSet.pageDefinedConstraints().initialScale;
if (oldInitialScale != newInitialScale && newInitialScale != -1) {
m_pageScaleConstraintsSet.setNeedsReset(true);
}
updateMainFrameLayoutSize();
+
+ if (LocalFrame* frame = page()->deprecatedLocalMainFrame()) {
+ if (FastTextAutosizer* textAutosizer = frame->document()->fastTextAutosizer())
+ textAutosizer->updatePageInfoInAllFrames();
+ }
}
void WebViewImpl::updateMainFrameLayoutSize()
{
- if (m_fixedLayoutSizeLock || !mainFrameImpl())
+ if (m_fixedLayoutSizeLock || m_shouldAutoResize || !mainFrameImpl())
return;
RefPtr<FrameView> view = mainFrameImpl()->frameView();
bool textAutosizingEnabled = page()->settings().textAutosizingEnabled();
if (textAutosizingEnabled && layoutSize.width != view->layoutSize().width()) {
- TextAutosizer* textAutosizer = page()->mainFrame()->document()->textAutosizer();
- if (textAutosizer)
+ if (TextAutosizer* textAutosizer = page()->deprecatedLocalMainFrame()->document()->textAutosizer())
textAutosizer->recalculateMultipliers();
}
}
+ if (page()->settings().forceZeroLayoutHeight())
+ layoutSize.height = 0;
+
view->setLayoutSize(layoutSize);
}
IntSize WebViewImpl::contentsSize() const
{
- RenderView* root = page()->mainFrame()->contentRenderer();
+ if (!page()->mainFrame()->isLocalFrame())
+ return IntSize();
+ RenderView* root = page()->deprecatedLocalMainFrame()->contentRenderer();
if (!root)
return IntSize();
return root->documentRect().size();
WebSize WebViewImpl::contentsPreferredMinimumSize()
{
- Document* document = m_page->mainFrame()->document();
+ Document* document = m_page->mainFrame()->isLocalFrame() ? m_page->deprecatedLocalMainFrame()->document() : 0;
if (!document || !document->renderView() || !document->documentElement())
return WebSize();
return m_pageScaleConstraintsSet.finalConstraints().maximumScale;
}
-void WebViewImpl::saveScrollAndScaleState()
+void WebViewImpl::resetScrollAndScaleState()
{
- m_savedPageScaleFactor = pageScaleFactor();
- m_savedScrollOffset = mainFrame()->scrollOffset();
-}
+ // TODO: This is done by the pinchViewport().reset() call below and can be removed when
+ // the new pinch path is the only one.
+ setPageScaleFactor(1);
+ updateMainFrameScrollPosition(IntPoint(), true);
+ page()->frameHost().pinchViewport().reset();
-void WebViewImpl::restoreScrollAndScaleState()
-{
- if (!m_savedPageScaleFactor)
+ if (!page()->mainFrame()->isLocalFrame())
return;
- startPageScaleAnimation(IntPoint(m_savedScrollOffset), false, m_savedPageScaleFactor, scrollAndScaleAnimationDurationInSeconds);
- resetSavedScrollAndScaleState();
-}
-
-void WebViewImpl::resetSavedScrollAndScaleState()
-{
- m_savedPageScaleFactor = 0;
- m_savedScrollOffset = IntSize();
-}
-
-void WebViewImpl::resetScrollAndScaleState()
-{
- page()->setPageScaleFactor(1, IntPoint());
-
// Clear out the values for the current history item. This will prevent the history item from clobbering the
// value determined during page scale initialization, which may be less than 1.
- page()->mainFrame()->loader().clearScrollPositionAndViewState();
+ page()->deprecatedLocalMainFrame()->loader().clearScrollPositionAndViewState();
m_pageScaleConstraintsSet.setNeedsReset(true);
// Clobber saved scales and scroll offsets.
- if (FrameView* view = page()->mainFrame()->document()->view())
+ if (FrameView* view = page()->deprecatedLocalMainFrame()->document()->view())
view->cacheCurrentScrollPosition();
- resetSavedScrollAndScaleState();
}
void WebViewImpl::setFixedLayoutSize(const WebSize& layoutSize)
{
- if (!page())
+ if (!page() || !page()->mainFrame()->isLocalFrame())
return;
- LocalFrame* frame = page()->mainFrame();
+ LocalFrame* frame = page()->deprecatedLocalMainFrame();
if (!frame)
return;
const WebPoint& location)
{
HitTestResult result = hitTestResultForWindowPos(location);
- RefPtr<Node> node = result.innerNonSharedNode();
+ RefPtrWillBeRawPtr<Node> node = result.innerNonSharedNode();
if (!isHTMLVideoElement(*node) && !isHTMLAudioElement(*node))
return;
- RefPtr<HTMLMediaElement> mediaElement =
- static_pointer_cast<HTMLMediaElement>(node);
+ RefPtrWillBeRawPtr<HTMLMediaElement> mediaElement = static_pointer_cast<HTMLMediaElement>(node);
switch (action.type) {
case WebMediaPlayerAction::Play:
if (action.enable)
const WebPoint& location)
{
HitTestResult result = hitTestResultForWindowPos(location);
- RefPtr<Node> node = result.innerNonSharedNode();
+ RefPtrWillBeRawPtr<Node> node = result.innerNonSharedNode();
if (!isHTMLObjectElement(*node) && !isHTMLEmbedElement(*node))
return;
HitTestResult result = hitTestResultForWindowPos(point);
- if (result.absoluteImageURL().isEmpty()) {
+ if (result.absoluteImageURLIncludingCanvasDataURL().isEmpty()) {
// There isn't actually an image at these coordinates. Might be because
// the window scrolled while the context menu was open or because the page
// changed itself between when we thought there was an image here and when
return;
}
- m_page->mainFrame()->editor().copyImage(result);
+ m_page->deprecatedLocalMainFrame()->editor().copyImage(result);
+}
+
+void WebViewImpl::saveImageAt(const WebPoint& point)
+{
+ if (!m_page)
+ return;
+
+ KURL url = hitTestResultForWindowPos(point).absoluteImageURLIncludingCanvasDataURL();
+
+ if (url.isEmpty())
+ return;
+
+ ResourceRequest request(url);
+ m_page->deprecatedLocalMainFrame()->loader().client()->loadURLExternally(
+ request, NavigationPolicyDownloadTo, WebString());
}
void WebViewImpl::dragSourceEndedAt(
screenPoint,
LeftButton, PlatformEvent::MouseMoved, 0, false, false, false,
false, 0);
- m_page->mainFrame()->eventHandler().dragSourceEndedAt(pme,
+ m_page->deprecatedLocalMainFrame()->eventHandler().dragSourceEndedAt(pme,
static_cast<DragOperation>(operation));
}
-void WebViewImpl::dragSourceMovedTo(
- const WebPoint& clientPoint,
- const WebPoint& screenPoint,
- WebDragOperation operation)
-{
-}
-
void WebViewImpl::dragSourceSystemDragEnded()
{
// It's possible for us to get this callback while not doing a drag if
{
ASSERT(m_currentDragData);
+ UserGestureNotifier notifier(m_autofillClient, &m_userGestureObserved);
+
// If this webview transitions from the "drop accepting" state to the "not
// accepting" state, then our IPC message reply indicating that may be in-
// flight, or else delayed by javascript processing in this webview. If a
void WebViewImpl::spellingMarkers(WebVector<uint32_t>* markers)
{
Vector<uint32_t> result;
- for (LocalFrame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- const Vector<DocumentMarker*>& documentMarkers = frame->document()->markers().markers();
+ for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ const WillBeHeapVector<DocumentMarker*>& documentMarkers = toLocalFrame(frame)->document()->markers().markers();
for (size_t i = 0; i < documentMarkers.size(); ++i)
result.append(documentMarkers[i]->hash());
}
if (point.x == -1 || point.y == -1) {
m_page->inspectorController().inspect(0);
} else {
- HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnorePointerEventsNone;
+ HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::AllowChildFrameContent;
HitTestRequest request(hitType);
- FrameView* frameView = m_page->mainFrame()->view();
- IntPoint transformedPoint(point);
- transformedPoint = transformedPoint - frameView->inputEventsOffsetForEmulation();
- transformedPoint.scale(1 / frameView->inputEventsScaleFactor(), 1 / frameView->inputEventsScaleFactor());
- HitTestResult result(m_page->mainFrame()->view()->windowToContents(transformedPoint));
- m_page->mainFrame()->contentRenderer()->hitTest(request, result);
+ WebMouseEvent dummyEvent;
+ dummyEvent.type = WebInputEvent::MouseDown;
+ dummyEvent.x = point.x;
+ dummyEvent.y = point.y;
+ IntPoint transformedPoint = PlatformMouseEventBuilder(m_page->deprecatedLocalMainFrame()->view(), dummyEvent).position();
+ HitTestResult result(m_page->deprecatedLocalMainFrame()->view()->windowToContents(transformedPoint));
+ m_page->deprecatedLocalMainFrame()->contentRenderer()->hitTest(request, result);
Node* node = result.innerNode();
- if (!node && m_page->mainFrame()->document())
- node = m_page->mainFrame()->document()->documentElement();
+ if (!node && m_page->deprecatedLocalMainFrame()->document())
+ node = m_page->deprecatedLocalMainFrame()->document()->documentElement();
m_page->inspectorController().inspect(node);
}
}
void WebViewImpl::setCompositorDeviceScaleFactorOverride(float deviceScaleFactor)
{
+ if (m_compositorDeviceScaleFactorOverride == deviceScaleFactor)
+ return;
m_compositorDeviceScaleFactorOverride = deviceScaleFactor;
if (page() && m_layerTreeView)
updateLayerTreeDeviceScaleFactor();
void WebViewImpl::setRootLayerTransform(const WebSize& rootLayerOffset, float rootLayerScale)
{
+ if (m_rootLayerScale == rootLayerScale && m_rootLayerOffset == rootLayerOffset)
+ return;
m_rootLayerScale = rootLayerScale;
m_rootLayerOffset = rootLayerOffset;
if (mainFrameImpl())
Document* document = mainFrameImpl()->frame()->document();
return WebAXObject(
- document->axObjectCache()->getOrCreate(document->renderer()));
+ document->axObjectCache()->getOrCreate(document->renderView()));
}
void WebViewImpl::performCustomContextMenuAction(unsigned action)
page()->contextMenuController().clearContextMenu();
m_contextMenuAllowed = true;
- if (LocalFrame* focusedFrame = page()->focusController().focusedOrMainFrame())
+ if (LocalFrame* focusedFrame = toLocalFrame(page()->focusController().focusedOrMainFrame()))
focusedFrame->eventHandler().sendContextMenuEventForKey();
m_contextMenuAllowed = false;
}
+// FIXME: This should be removed when the chromium side patch lands
+// http://codereview.chromium.org/260623004
WebString WebViewImpl::getSmartClipData(WebRect rect)
{
- LocalFrame* frame = focusedWebCoreFrame();
+ return WebString();
+}
+
+void WebViewImpl::getSmartClipData(WebRect rect, WebString& clipText, WebRect& clipRect)
+{
+ LocalFrame* frame = toLocalFrame(focusedWebCoreFrame());
if (!frame)
- return WebString();
- return WebCore::SmartClip(frame).dataForRect(rect).toString();
+ return;
+ SmartClipData clipData = WebCore::SmartClip(frame).dataForRect(rect);
+ clipText = clipData.clipData();
+ clipRect = clipData.rect();
+}
+
+void WebViewImpl::extractSmartClipData(WebRect rect, WebString& clipText, WebString& clipHtml, WebRect& clipRect)
+{
+ LocalFrame* localFrame = toLocalFrame(focusedWebCoreFrame());
+ if (!localFrame)
+ return;
+ SmartClipData clipData = WebCore::SmartClip(localFrame).dataForRect(rect);
+ clipText = clipData.clipData();
+ clipRect = clipData.rect();
+
+ WebLocalFrameImpl* frame = mainFrameImpl();
+ if (!frame)
+ return;
+ WebPoint startPoint(rect.x, rect.y);
+ WebPoint endPoint(rect.x + rect.width, rect.y + rect.height);
+ VisiblePosition startVisiblePosition = frame->visiblePositionForWindowPoint(startPoint);
+ VisiblePosition endVisiblePosition = frame->visiblePositionForWindowPoint(endPoint);
+
+ Position startPosition = startVisiblePosition.deepEquivalent();
+ Position endPosition = endVisiblePosition.deepEquivalent();
+
+ RefPtr<Range> range = Range::create(*startPosition.document(), startPosition, endPosition);
+ if (!range)
+ return;
+
+ clipHtml = createMarkup(range.get(), 0, AnnotateForInterchange, false, ResolveNonLocalURLs);
}
void WebViewImpl::hidePopups()
void WebViewImpl::setIsTransparent(bool isTransparent)
{
// Set any existing frames to be transparent.
- LocalFrame* frame = m_page->mainFrame();
+ Frame* frame = m_page->mainFrame();
while (frame) {
- frame->view()->setTransparent(isTransparent);
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->view()->setTransparent(isTransparent);
frame = frame->tree().traverseNext();
}
m_baseBackgroundColor = color;
- if (m_page->mainFrame())
- m_page->mainFrame()->view()->setBaseBackgroundColor(color);
+ if (m_page->mainFrame() && m_page->mainFrame()->isLocalFrame())
+ m_page->deprecatedLocalMainFrame()->view()->setBaseBackgroundColor(color);
updateLayerTreeBackgroundColor();
}
m_page->chrome().setWindowFeatures(features);
}
+void WebViewImpl::setOpenedByDOM()
+{
+ m_page->setOpenedByDOM();
+}
+
void WebViewImpl::setSelectionColors(unsigned activeBackgroundColor,
unsigned activeForegroundColor,
unsigned inactiveBackgroundColor,
// Make sure link highlight from previous page is cleared.
m_linkHighlights.clear();
endActiveFlingAnimation();
- resetSavedScrollAndScaleState();
+ m_userGestureObserved = false;
}
-void WebViewImpl::willInsertBody(WebFrameImpl* webframe)
+void WebViewImpl::willInsertBody(WebLocalFrameImpl* webframe)
{
if (webframe != mainFrameImpl())
return;
- // If we get to the <body> tag and we have no pending stylesheet loads, we
+ if (!m_page->mainFrame()->isLocalFrame())
+ return;
+
+ // If we get to the <body> tag and we have no pending stylesheet and import load, we
// can be fairly confident we'll have something sensible to paint soon and
// can turn off deferred commits.
- if (m_page->mainFrame()->document()->haveStylesheetsLoaded())
+ if (m_page->deprecatedLocalMainFrame()->document()->isRenderingReady())
resumeTreeViewCommits();
}
}
}
-void WebViewImpl::layoutUpdated(WebFrameImpl* webframe)
+void WebViewImpl::layoutUpdated(WebLocalFrameImpl* webframe)
{
if (!m_client || webframe != mainFrameImpl())
return;
WebSize frameSize = mainFrameImpl()->frame()->view()->frameRect().size();
if (frameSize != m_size) {
m_size = frameSize;
+
+ page()->frameHost().pinchViewport().setSize(m_size);
+ m_pageScaleConstraintsSet.didChangeViewSize(m_size);
+
m_client->didAutoResize(m_size);
sendResizeEventAndRepaint();
}
void WebViewImpl::deviceOrPageScaleFactorChanged()
{
- if (pageScaleFactor() && pageScaleFactor() != 1)
- enterForceCompositingMode(true);
m_pageScaleConstraintsSet.setNeedsReset(false);
updateLayerTreeViewport();
}
return;
ASSERT(!m_doingDragAndDrop);
m_doingDragAndDrop = true;
- m_client->startDragging(WebFrameImpl::fromFrame(frame), dragData, mask, dragImage, dragImageOffset);
+ m_client->startDragging(WebLocalFrameImpl::fromFrame(frame), dragData, mask, dragImage, dragImageOffset);
}
void WebViewImpl::setIgnoreInputEvents(bool newValue)
if (!m_rootGraphicsLayer)
return;
+ if (!m_page->mainFrame()->isLocalFrame())
+ return;
+
+ if (pinchVirtualViewportEnabled()) {
+ m_page->deprecatedLocalMainFrame()->view()->renderView()->compositor()->setOverlayLayer(layer);
+ return;
+ }
+
+ // FIXME(bokan): This path goes away after virtual viewport pinch is enabled everywhere.
if (!m_rootTransformLayer)
- m_rootTransformLayer = m_page->mainFrame()->view()->renderView()->compositor()->ensureRootTransformLayer();
+ m_rootTransformLayer = m_page->deprecatedLocalMainFrame()->view()->renderView()->compositor()->ensureRootTransformLayer();
if (m_rootTransformLayer) {
if (layer->parent() != m_rootTransformLayer)
}
}
-NotificationPresenterImpl* WebViewImpl::notificationPresenterImpl()
-{
- if (!m_notificationPresenter.isInitialized() && m_client)
- m_notificationPresenter.initialize(m_client->notificationPresenter());
- return &m_notificationPresenter;
-}
-
Element* WebViewImpl::focusedElement() const
{
- LocalFrame* frame = m_page->focusController().focusedFrame();
- if (!frame)
+ Frame* frame = m_page->focusController().focusedFrame();
+ if (!frame || !frame->isLocalFrame())
return 0;
- Document* document = frame->document();
+ Document* document = toLocalFrame(frame)->document();
if (!document)
return 0;
HitTestResult WebViewImpl::hitTestResultForWindowPos(const IntPoint& pos)
{
- IntPoint docPoint(m_page->mainFrame()->view()->windowToContents(pos));
- return m_page->mainFrame()->eventHandler().hitTestResultAtPoint(docPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
+ if (!m_page->mainFrame()->isLocalFrame())
+ return HitTestResult();
+ IntPoint docPoint(m_page->deprecatedLocalMainFrame()->view()->windowToContents(pos));
+ return m_page->deprecatedLocalMainFrame()->eventHandler().hitTestResultAtPoint(docPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
}
void WebViewImpl::setTabsToLinks(bool enable)
m_client->suppressCompositorScheduling(enable);
}
-bool WebViewImpl::allowsAcceleratedCompositing()
-{
- return !m_compositorCreationFailed;
-}
-
void WebViewImpl::setRootGraphicsLayer(GraphicsLayer* layer)
{
- bool pinchVirtualViewportEnabled = page()->settings().pinchVirtualViewportEnabled();
suppressInvalidations(true);
- if (pinchVirtualViewportEnabled) {
+ if (pinchVirtualViewportEnabled()) {
PinchViewport& pinchViewport = page()->frameHost().pinchViewport();
pinchViewport.attachToLayerTree(layer, graphicsLayerFactory());
- pinchViewport.setSize(mainFrameImpl()->frame()->view()->frameRect().size());
if (layer) {
m_rootGraphicsLayer = pinchViewport.rootGraphicsLayer();
m_rootLayer = pinchViewport.rootGraphicsLayer()->platformLayer();
- m_rootTransformLayer = 0;
+ m_rootTransformLayer = pinchViewport.rootGraphicsLayer();
} else {
m_rootGraphicsLayer = 0;
m_rootLayer = 0;
m_layerTreeView->setRootLayer(*m_rootLayer);
// We register viewport layers here since there may not be a layer
// tree view prior to this point.
- if (pinchVirtualViewportEnabled) {
+ if (pinchVirtualViewportEnabled()) {
page()->frameHost().pinchViewport().registerLayersWithTreeView(m_layerTreeView);
} else {
GraphicsLayer* rootScrollLayer = compositor()->scrollLayer();
}
} else {
m_layerTreeView->clearRootLayer();
- if (pinchVirtualViewportEnabled)
+ if (pinchVirtualViewportEnabled())
page()->frameHost().pinchViewport().clearLayersForTreeView(m_layerTreeView);
else
m_layerTreeView->clearViewportLayers();
{
if (!page()
|| !page()->mainFrame()
- || !page()->mainFrame()->document()
- || !page()->mainFrame()->document()->renderView())
+ || !page()->mainFrame()->isLocalFrame()
+ || !page()->deprecatedLocalMainFrame()->document()
+ || !page()->deprecatedLocalMainFrame()->document()->renderView())
return 0;
- return page()->mainFrame()->document()->renderView()->compositor();
+ return page()->deprecatedLocalMainFrame()->document()->renderView()->compositor();
}
void WebViewImpl::registerForAnimations(WebLayer* layer)
if (m_isAcceleratedCompositingActive == active)
return;
+ if (!m_client)
+ return;
+
if (!active) {
m_isAcceleratedCompositingActive = false;
- // We need to finish all GL rendering before sending didDeactivateCompositor() to prevent
- // flickering when compositing turns off. This is only necessary if we're not in
- // force-compositing-mode.
- if (m_layerTreeView && !page()->settings().forceCompositingMode())
- m_layerTreeView->finishAllRendering();
- m_client->didDeactivateCompositor();
if (!m_layerTreeViewCommitsDeferred
&& blink::Platform::current()->isThreadedCompositingEnabled()) {
ASSERT(m_layerTreeView);
updateLayerTreeViewport();
if (m_pageOverlays)
m_pageOverlays->update();
-
- m_client->didActivateCompositor(0);
} else {
TRACE_EVENT0("webkit", "WebViewImpl::setIsAcceleratedCompositingActive(true)");
m_layerTreeView->setHasTransparentBackground(isTransparent());
#if USE(RUBBER_BANDING)
RefPtr<Image> overhangImage = OverscrollTheme::theme()->getOverhangImage();
- if (overhangImage)
+ if (overhangImage && overhangImage->nativeImageForCurrentFrame())
m_layerTreeView->setOverhangBitmap(overhangImage->nativeImageForCurrentFrame()->bitmap());
#endif
updateLayerTreeViewport();
- m_client->didActivateCompositor(0);
m_isAcceleratedCompositingActive = true;
- m_compositorCreationFailed = false;
if (m_pageOverlays)
m_pageOverlays->update();
m_layerTreeView->setShowFPSCounter(m_showFPSCounter);
m_layerTreeView->setShowDebugBorders(m_showDebugBorders);
m_layerTreeView->setContinuousPaintingEnabled(m_continuousPaintingEnabled);
m_layerTreeView->setShowScrollBottleneckRects(m_showScrollBottleneckRects);
+ m_layerTreeView->heuristicsForGpuRasterizationUpdated(m_matchesHeuristicsForGpuRasterization);
} else {
+ // FIXME: It appears that only unittests, <webview> and android webview
+ // printing can hit this code. We should make them not hit this code and
+ // then delete this else clause and allowsBrokenNullLayerTreeView.
+ // crbug.com/322276 and crbug.com/364716.
+ ASSERT(m_client->allowsBrokenNullLayerTreeView());
m_isAcceleratedCompositingActive = false;
- m_client->didDeactivateCompositor();
- m_compositorCreationFailed = true;
+ m_page->settings().setAcceleratedCompositingEnabled(false);
+ m_page->updateAcceleratedCompositingSettings();
}
}
- if (page())
- page()->mainFrame()->view()->setClipsRepaints(!m_isAcceleratedCompositingActive);
+ if (page() && page()->mainFrame()->isLocalFrame())
+ page()->deprecatedLocalMainFrame()->view()->setClipsRepaints(!m_isAcceleratedCompositingActive);
}
void WebViewImpl::updateMainFrameScrollPosition(const IntPoint& scrollPosition, bool programmaticScroll)
{
- FrameView* frameView = page()->mainFrame()->view();
+ if (!page()->mainFrame()->isLocalFrame())
+ return;
+
+ FrameView* frameView = page()->deprecatedLocalMainFrame()->view();
if (!frameView)
return;
if (!mainFrameImpl() || !mainFrameImpl()->frameView())
return;
- // With virtual viewport we need only set the scale (see TODO below).
- if (page()->settings().pinchVirtualViewportEnabled()) {
- WebSize scrollOffset = mainFrame()->scrollOffset();
- WebPoint scrollPoint(scrollOffset.width, scrollOffset.height);
- setPageScaleFactor(pageScaleFactor() * pageScaleDelta, scrollPoint);
- m_doubleTapZoomPending = false;
+ if (pinchVirtualViewportEnabled()) {
+ if (pageScaleDelta != 1) {
+ // When the virtual viewport is enabled, offsets are already set for us.
+ setPageScaleFactor(pageScaleFactor() * pageScaleDelta);
+ m_doubleTapZoomPending = false;
+ }
+
return;
}
}
}
-void WebViewImpl::didExitCompositingMode()
-{
- ASSERT(m_isAcceleratedCompositingActive);
- setIsAcceleratedCompositingActive(false);
- m_compositorCreationFailed = true;
- m_client->didInvalidateRect(IntRect(0, 0, m_size.width, m_size.height));
-
- // Force a style recalc to remove all the composited layers.
- m_page->mainFrame()->document()->setNeedsStyleRecalc(SubtreeStyleChange);
-
- if (m_pageOverlays)
- m_pageOverlays->update();
-}
-
void WebViewImpl::updateLayerTreeViewport()
{
if (!page() || !m_layerTreeView)
if (!m_rootGraphicsLayer)
return;
- if (!m_rootTransformLayer)
- m_rootTransformLayer = m_page->mainFrame()->view()->renderView()->compositor()->ensureRootTransformLayer();
+ // FIXME(bokan): m_rootTransformLayer is always set here in pinch virtual viewport. This can go away once
+ // that's default everywhere.
+ if (!m_rootTransformLayer && m_page->mainFrame()->isLocalFrame())
+ m_rootTransformLayer = m_page->deprecatedLocalMainFrame()->view()->renderView()->compositor()->ensureRootTransformLayer();
if (m_rootTransformLayer) {
WebCore::TransformationMatrix transform;