| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 #include "sky/engine/public/platform/WebVector.h" | 87 #include "sky/engine/public/platform/WebVector.h" |
| 88 #include "sky/engine/public/web/WebActiveWheelFlingParameters.h" | 88 #include "sky/engine/public/web/WebActiveWheelFlingParameters.h" |
| 89 #include "sky/engine/public/web/WebBeginFrameArgs.h" | 89 #include "sky/engine/public/web/WebBeginFrameArgs.h" |
| 90 #include "sky/engine/public/web/WebFrameClient.h" | 90 #include "sky/engine/public/web/WebFrameClient.h" |
| 91 #include "sky/engine/public/web/WebHitTestResult.h" | 91 #include "sky/engine/public/web/WebHitTestResult.h" |
| 92 #include "sky/engine/public/web/WebNode.h" | 92 #include "sky/engine/public/web/WebNode.h" |
| 93 #include "sky/engine/public/web/WebRange.h" | 93 #include "sky/engine/public/web/WebRange.h" |
| 94 #include "sky/engine/public/web/WebTextInputInfo.h" | 94 #include "sky/engine/public/web/WebTextInputInfo.h" |
| 95 #include "sky/engine/public/web/WebViewClient.h" | 95 #include "sky/engine/public/web/WebViewClient.h" |
| 96 #include "sky/engine/web/CompositionUnderlineVectorBuilder.h" | 96 #include "sky/engine/web/CompositionUnderlineVectorBuilder.h" |
| 97 #include "sky/engine/web/GraphicsLayerFactoryChromium.h" | |
| 98 #include "sky/engine/web/LinkHighlight.h" | |
| 99 #include "sky/engine/web/WebInputEventConversion.h" | 97 #include "sky/engine/web/WebInputEventConversion.h" |
| 100 #include "sky/engine/web/WebLocalFrameImpl.h" | 98 #include "sky/engine/web/WebLocalFrameImpl.h" |
| 101 #include "sky/engine/web/WebSettingsImpl.h" | 99 #include "sky/engine/web/WebSettingsImpl.h" |
| 102 #include "sky/engine/wtf/CurrentTime.h" | 100 #include "sky/engine/wtf/CurrentTime.h" |
| 103 #include "sky/engine/wtf/RefPtr.h" | 101 #include "sky/engine/wtf/RefPtr.h" |
| 104 #include "sky/engine/wtf/TemporaryChange.h" | 102 #include "sky/engine/wtf/TemporaryChange.h" |
| 105 | 103 |
| 106 // Get rid of WTF's pow define so we can use std::pow. | 104 // Get rid of WTF's pow define so we can use std::pow. |
| 107 #undef pow | 105 #undef pow |
| 108 #include <cmath> // for std::pow | 106 #include <cmath> // for std::pow |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 return eventSwallowed; | 292 return eventSwallowed; |
| 295 default: | 293 default: |
| 296 break; | 294 break; |
| 297 } | 295 } |
| 298 | 296 |
| 299 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), even
t); | 297 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), even
t); |
| 300 | 298 |
| 301 // FIXME: Remove redundant hit tests by pushing the call to EventHandler::ta
rgetGestureEvent | 299 // FIXME: Remove redundant hit tests by pushing the call to EventHandler::ta
rgetGestureEvent |
| 302 // up to this point and pass GestureEventWithHitTestResults around. | 300 // up to this point and pass GestureEventWithHitTestResults around. |
| 303 | 301 |
| 304 // Handle link highlighting outside the main switch to avoid getting lost in
the | |
| 305 // complicated set of cases handled below. | |
| 306 switch (event.type) { | |
| 307 case WebInputEvent::GestureShowPress: | |
| 308 // Queue a highlight animation, then hand off to regular handler. | |
| 309 enableTapHighlightAtPoint(platformEvent); | |
| 310 break; | |
| 311 case WebInputEvent::GestureTapCancel: | |
| 312 case WebInputEvent::GestureTap: | |
| 313 case WebInputEvent::GestureLongPress: | |
| 314 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | |
| 315 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); | |
| 316 break; | |
| 317 default: | |
| 318 break; | |
| 319 } | |
| 320 | |
| 321 switch (event.type) { | 302 switch (event.type) { |
| 322 case WebInputEvent::GestureTap: { | 303 case WebInputEvent::GestureTap: { |
| 323 m_client->cancelScheduledContentIntents(); | 304 m_client->cancelScheduledContentIntents(); |
| 324 if (detectContentOnTouch(platformEvent.position())) { | 305 if (detectContentOnTouch(platformEvent.position())) { |
| 325 eventSwallowed = true; | 306 eventSwallowed = true; |
| 326 break; | 307 break; |
| 327 } | 308 } |
| 328 | 309 |
| 329 // Don't trigger a disambiguation popup on sites designed for mobile dev
ices. | |
| 330 // Instead, assume that the page has been designed with big enough butto
ns and links. | |
| 331 if (event.data.tap.width > 0 && !shouldDisableDesktopWorkarounds()) { | |
| 332 // FIXME: didTapMultipleTargets should just take a rect instead of | |
| 333 // an event. | |
| 334 WebGestureEvent scaledEvent = event; | |
| 335 IntRect boundingBox(scaledEvent.x - scaledEvent.data.tap.width / 2,
scaledEvent.y - scaledEvent.data.tap.height / 2, scaledEvent.data.tap.width, sca
ledEvent.data.tap.height); | |
| 336 Vector<IntRect> goodTargets; | |
| 337 Vector<RawPtr<Node> > highlightNodes; | |
| 338 findGoodTouchTargets(boundingBox, mainFrameImpl()->frame(), goodTarg
ets, highlightNodes); | |
| 339 // FIXME: replace touch adjustment code when numberOfGoodTargets ==
1? | |
| 340 // Single candidate case is currently handled by: https://bugs.webki
t.org/show_bug.cgi?id=85101 | |
| 341 if (goodTargets.size() >= 2 && m_client && m_client->didTapMultipleT
argets(scaledEvent, goodTargets)) { | |
| 342 enableTapHighlights(highlightNodes); | |
| 343 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | |
| 344 m_linkHighlights[i]->startHighlightAnimationIfNeeded(); | |
| 345 eventSwallowed = true; | |
| 346 eventCancelled = true; | |
| 347 break; | |
| 348 } | |
| 349 } | |
| 350 | |
| 351 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); | 310 eventSwallowed = mainFrameImpl()->frame()->eventHandler().handleGestureE
vent(platformEvent); |
| 352 break; | 311 break; |
| 353 } | 312 } |
| 354 case WebInputEvent::GestureTwoFingerTap: | 313 case WebInputEvent::GestureTwoFingerTap: |
| 355 case WebInputEvent::GestureLongPress: | 314 case WebInputEvent::GestureLongPress: |
| 356 case WebInputEvent::GestureLongTap: { | 315 case WebInputEvent::GestureLongTap: { |
| 357 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) | 316 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) |
| 358 break; | 317 break; |
| 359 | 318 |
| 360 m_client->cancelScheduledContentIntents(); | 319 m_client->cancelScheduledContentIntents(); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 ASSERT(newX + newWidth <= maxSize.width); | 554 ASSERT(newX + newWidth <= maxSize.width); |
| 596 | 555 |
| 597 return WebRect(newX, source.y, newWidth, source.height); | 556 return WebRect(newX, source.y, newWidth, source.height); |
| 598 } | 557 } |
| 599 | 558 |
| 600 void WebViewImpl::computeScaleAndScrollForBlockRect(const WebPoint& hitPoint, co
nst WebRect& blockRect, float padding, float defaultScaleWhenAlreadyLegible, flo
at& scale, WebPoint& scroll) | 559 void WebViewImpl::computeScaleAndScrollForBlockRect(const WebPoint& hitPoint, co
nst WebRect& blockRect, float padding, float defaultScaleWhenAlreadyLegible, flo
at& scale, WebPoint& scroll) |
| 601 { | 560 { |
| 602 //FIXME(sky) | 561 //FIXME(sky) |
| 603 } | 562 } |
| 604 | 563 |
| 605 static Node* findCursorDefiningAncestor(Node* node, LocalFrame* frame) | |
| 606 { | |
| 607 // Go up the tree to find the node that defines a mouse cursor style | |
| 608 while (node) { | |
| 609 if (node->renderer()) { | |
| 610 ECursor cursor = node->renderer()->style()->cursor(); | |
| 611 if (cursor != CURSOR_AUTO || frame->eventHandler().useHandCursor(nod
e, node->isLink())) | |
| 612 break; | |
| 613 } | |
| 614 node = NodeRenderingTraversal::parent(node); | |
| 615 } | |
| 616 | |
| 617 return node; | |
| 618 } | |
| 619 | |
| 620 static bool showsHandCursor(Node* node, LocalFrame* frame) | |
| 621 { | |
| 622 if (!node || !node->renderer()) | |
| 623 return false; | |
| 624 | |
| 625 ECursor cursor = node->renderer()->style()->cursor(); | |
| 626 return cursor == CURSOR_POINTER | |
| 627 || (cursor == CURSOR_AUTO && frame->eventHandler().useHandCursor(node, n
ode->isLink())); | |
| 628 } | |
| 629 | |
| 630 Node* WebViewImpl::bestTapNode(const PlatformGestureEvent& tapEvent) | |
| 631 { | |
| 632 TRACE_EVENT0("input", "WebViewImpl::bestTapNode"); | |
| 633 | |
| 634 if (!m_page || !m_page->mainFrame()) | |
| 635 return 0; | |
| 636 | |
| 637 // FIXME: Rely on earlier hit test instead of hit testing again. | |
| 638 GestureEventWithHitTestResults targetedEvent = | |
| 639 m_page->mainFrame()->eventHandler().targetGestureEvent(tapEvent, true); | |
| 640 Node* bestTouchNode = targetedEvent.hitTestResult().targetNode(); | |
| 641 | |
| 642 // We might hit something like an image map that has no renderer on it | |
| 643 // Walk up the tree until we have a node with an attached renderer | |
| 644 // FIXME: This wants to walk composed tree with NodeRenderingTraversal::pare
nt(). | |
| 645 while (bestTouchNode && !bestTouchNode->renderer()) | |
| 646 bestTouchNode = NodeRenderingTraversal::parent(bestTouchNode); | |
| 647 | |
| 648 Node* cursorDefiningAncestor = | |
| 649 findCursorDefiningAncestor(bestTouchNode, m_page->mainFrame()); | |
| 650 // We show a highlight on tap only when the current node shows a hand cursor | |
| 651 if (!cursorDefiningAncestor || !showsHandCursor(cursorDefiningAncestor, m_pa
ge->mainFrame())) { | |
| 652 return 0; | |
| 653 } | |
| 654 | |
| 655 // We should pick the largest enclosing node with hand cursor set. We do thi
s by first jumping | |
| 656 // up to cursorDefiningAncestor (which is already known to have hand cursor
set). Then we locate | |
| 657 // the next cursor-defining ancestor up in the the tree and repeat the jumps
as long as the node | |
| 658 // has hand cursor set. | |
| 659 do { | |
| 660 bestTouchNode = cursorDefiningAncestor; | |
| 661 cursorDefiningAncestor = findCursorDefiningAncestor(NodeRenderingTravers
al::parent(bestTouchNode), | |
| 662 m_page->mainFrame()); | |
| 663 } while (cursorDefiningAncestor && showsHandCursor(cursorDefiningAncestor, m
_page->mainFrame())); | |
| 664 | |
| 665 return bestTouchNode; | |
| 666 } | |
| 667 | |
| 668 void WebViewImpl::enableTapHighlightAtPoint(const PlatformGestureEvent& tapEvent
) | |
| 669 { | |
| 670 Node* touchNode = bestTapNode(tapEvent); | |
| 671 | |
| 672 Vector<RawPtr<Node> > highlightNodes; | |
| 673 highlightNodes.append(touchNode); | |
| 674 | |
| 675 enableTapHighlights(highlightNodes); | |
| 676 } | |
| 677 | |
| 678 void WebViewImpl::enableTapHighlights(Vector<RawPtr<Node> >& highlightNodes) | |
| 679 { | |
| 680 if (highlightNodes.isEmpty()) | |
| 681 return; | |
| 682 | |
| 683 // Always clear any existing highlight when this is invoked, even if we | |
| 684 // don't get a new target to highlight. | |
| 685 m_linkHighlights.clear(); | |
| 686 | |
| 687 // LinkHighlight reads out layout and compositing state, so we need to make
sure that's all up to date. | |
| 688 layout(); | |
| 689 | |
| 690 for (size_t i = 0; i < highlightNodes.size(); ++i) { | |
| 691 Node* node = highlightNodes[i]; | |
| 692 | |
| 693 if (!node || !node->renderer()) | |
| 694 continue; | |
| 695 | |
| 696 Color highlightColor = node->renderer()->style()->tapHighlightColor(); | |
| 697 // Safari documentation for -webkit-tap-highlight-color says if the spec
ified color has 0 alpha, | |
| 698 // then tap highlighting is disabled. | |
| 699 // http://developer.apple.com/library/safari/#documentation/appleapplica
tions/reference/safaricssref/articles/standardcssproperties.html | |
| 700 if (!highlightColor.alpha()) | |
| 701 continue; | |
| 702 | |
| 703 m_linkHighlights.append(LinkHighlight::create(node, this)); | |
| 704 } | |
| 705 } | |
| 706 | |
| 707 bool WebViewImpl::keyEventDefault(const WebKeyboardEvent& event) | 564 bool WebViewImpl::keyEventDefault(const WebKeyboardEvent& event) |
| 708 { | 565 { |
| 709 LocalFrame* frame = focusedCoreFrame(); | 566 LocalFrame* frame = focusedCoreFrame(); |
| 710 if (!frame) | 567 if (!frame) |
| 711 return false; | 568 return false; |
| 712 | 569 |
| 713 switch (event.type) { | 570 switch (event.type) { |
| 714 case WebInputEvent::Char: | 571 case WebInputEvent::Char: |
| 715 if (event.windowsKeyCode == VKEY_SPACE) { | 572 if (event.windowsKeyCode == VKEY_SPACE) { |
| 716 int keyCode = ((event.modifiers & WebInputEvent::ShiftKey) ? VKEY_PR
IOR : VKEY_NEXT); | 573 int keyCode = ((event.modifiers & WebInputEvent::ShiftKey) ? VKEY_PR
IOR : VKEY_NEXT); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 | 765 |
| 909 void WebViewImpl::didCommitFrameToCompositor() | 766 void WebViewImpl::didCommitFrameToCompositor() |
| 910 { | 767 { |
| 911 } | 768 } |
| 912 | 769 |
| 913 void WebViewImpl::layout() | 770 void WebViewImpl::layout() |
| 914 { | 771 { |
| 915 TRACE_EVENT0("blink", "WebViewImpl::layout"); | 772 TRACE_EVENT0("blink", "WebViewImpl::layout"); |
| 916 if (!localFrameRootTemporary()) | 773 if (!localFrameRootTemporary()) |
| 917 return; | 774 return; |
| 918 | |
| 919 PageWidgetDelegate::layout(m_page.get(), localFrameRootTemporary()->frame())
; | 775 PageWidgetDelegate::layout(m_page.get(), localFrameRootTemporary()->frame())
; |
| 920 | |
| 921 for (size_t i = 0; i < m_linkHighlights.size(); ++i) | |
| 922 m_linkHighlights[i]->updateGeometry(); | |
| 923 } | 776 } |
| 924 | 777 |
| 925 void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect) | 778 void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect) |
| 926 { | 779 { |
| 927 double paintStart = currentTime(); | 780 double paintStart = currentTime(); |
| 928 PageWidgetDelegate::paint(m_page.get(), canvas, rect, isTransparent() ? Page
WidgetDelegate::Translucent : PageWidgetDelegate::Opaque); | 781 PageWidgetDelegate::paint(m_page.get(), canvas, rect, isTransparent() ? Page
WidgetDelegate::Translucent : PageWidgetDelegate::Opaque); |
| 929 double paintEnd = currentTime(); | 782 double paintEnd = currentTime(); |
| 930 double pixelsPerSec = (rect.width * rect.height) / (paintEnd - paintStart); | 783 double pixelsPerSec = (rect.width * rect.height) / (paintEnd - paintStart); |
| 931 Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintDurationM
S", (paintEnd - paintStart) * 1000, 0, 120, 30); | 784 Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintDurationM
S", (paintEnd - paintStart) * 1000, 0, 120, 30); |
| 932 Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintMegapixPe
rSecond", pixelsPerSec / 1000000, 10, 210, 30); | 785 Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintMegapixPe
rSecond", pixelsPerSec / 1000000, 10, 210, 30); |
| (...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1852 } | 1705 } |
| 1853 | 1706 |
| 1854 void WebViewImpl::setSelectionColors(unsigned activeBackgroundColor, | 1707 void WebViewImpl::setSelectionColors(unsigned activeBackgroundColor, |
| 1855 unsigned activeForegroundColor, | 1708 unsigned activeForegroundColor, |
| 1856 unsigned inactiveBackgroundColor, | 1709 unsigned inactiveBackgroundColor, |
| 1857 unsigned inactiveForegroundColor) { | 1710 unsigned inactiveForegroundColor) { |
| 1858 } | 1711 } |
| 1859 | 1712 |
| 1860 void WebViewImpl::didCommitLoad(bool isNewNavigation, bool isNavigationWithinPag
e) | 1713 void WebViewImpl::didCommitLoad(bool isNewNavigation, bool isNavigationWithinPag
e) |
| 1861 { | 1714 { |
| 1862 // Make sure link highlight from previous page is cleared. | |
| 1863 m_linkHighlights.clear(); | |
| 1864 endActiveFlingAnimation(); | 1715 endActiveFlingAnimation(); |
| 1865 m_userGestureObserved = false; | 1716 m_userGestureObserved = false; |
| 1866 if (!isNavigationWithinPage) | 1717 if (!isNavigationWithinPage) |
| 1867 UserGestureIndicator::clearProcessedUserGestureSinceLoad(); | 1718 UserGestureIndicator::clearProcessedUserGestureSinceLoad(); |
| 1868 } | 1719 } |
| 1869 | 1720 |
| 1870 void WebViewImpl::layoutUpdated(WebLocalFrameImpl* webframe) | 1721 void WebViewImpl::layoutUpdated(WebLocalFrameImpl* webframe) |
| 1871 { | 1722 { |
| 1872 if (!m_client) | 1723 if (!m_client) |
| 1873 return; | 1724 return; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1967 | 1818 |
| 1968 void WebViewImpl::setVisibilityState(WebPageVisibilityState visibilityState, | 1819 void WebViewImpl::setVisibilityState(WebPageVisibilityState visibilityState, |
| 1969 bool isInitialState) { | 1820 bool isInitialState) { |
| 1970 if (!page()) | 1821 if (!page()) |
| 1971 return; | 1822 return; |
| 1972 | 1823 |
| 1973 ASSERT(visibilityState == WebPageVisibilityStateVisible || visibilityState =
= WebPageVisibilityStateHidden); | 1824 ASSERT(visibilityState == WebPageVisibilityStateVisible || visibilityState =
= WebPageVisibilityStateHidden); |
| 1974 m_page->setVisibilityState(static_cast<PageVisibilityState>(static_cast<int>
(visibilityState)), isInitialState); | 1825 m_page->setVisibilityState(static_cast<PageVisibilityState>(static_cast<int>
(visibilityState)), isInitialState); |
| 1975 } | 1826 } |
| 1976 | 1827 |
| 1977 bool WebViewImpl::shouldDisableDesktopWorkarounds() | |
| 1978 { | |
| 1979 return true; | |
| 1980 } | |
| 1981 | |
| 1982 } // namespace blink | 1828 } // namespace blink |
| OLD | NEW |