| 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 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 handleGestureEvent(syntheticGestureEvent); | 690 handleGestureEvent(syntheticGestureEvent); |
| 691 } | 691 } |
| 692 } | 692 } |
| 693 | 693 |
| 694 #if ENABLE(GESTURE_EVENTS) | 694 #if ENABLE(GESTURE_EVENTS) |
| 695 bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event) | 695 bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event) |
| 696 { | 696 { |
| 697 bool eventSwallowed = false; | 697 bool eventSwallowed = false; |
| 698 bool eventCancelled = false; // for disambiguation | 698 bool eventCancelled = false; // for disambiguation |
| 699 | 699 |
| 700 // Special handling for slow-path fling gestures, which have no PlatformGest
ureEvent equivalent. |
| 701 switch (event.type) { |
| 702 case WebInputEvent::GestureFlingStart: { |
| 703 if (mainFrameImpl()->frame()->eventHandler()->isScrollbarHandlingGesture
s()) { |
| 704 m_client->didHandleGestureEvent(event, eventCancelled); |
| 705 return eventSwallowed; |
| 706 } |
| 707 m_client->cancelScheduledContentIntents(); |
| 708 m_positionOnFlingStart = WebPoint(event.x / pageScaleFactor(), event.y /
pageScaleFactor()); |
| 709 m_globalPositionOnFlingStart = WebPoint(event.globalX, event.globalY); |
| 710 m_flingModifier = event.modifiers; |
| 711 m_flingSourceDevice = event.sourceDevice; |
| 712 OwnPtr<WebGestureCurve> flingCurve = adoptPtr(Platform::current()->creat
eFlingAnimationCurve(event.sourceDevice, WebFloatPoint(event.data.flingStart.vel
ocityX, event.data.flingStart.velocityY), WebSize())); |
| 713 m_gestureAnimation = WebActiveGestureAnimation::createAtAnimationStart(f
lingCurve.release(), this); |
| 714 scheduleAnimation(); |
| 715 eventSwallowed = true; |
| 716 |
| 717 m_client->didHandleGestureEvent(event, eventCancelled); |
| 718 return eventSwallowed; |
| 719 } |
| 720 case WebInputEvent::GestureFlingCancel: |
| 721 if (m_gestureAnimation) { |
| 722 m_gestureAnimation.clear(); |
| 723 if (m_layerTreeView) |
| 724 m_layerTreeView->didStopFlinging(); |
| 725 eventSwallowed = true; |
| 726 } |
| 727 |
| 728 m_client->didHandleGestureEvent(event, eventCancelled); |
| 729 return eventSwallowed; |
| 730 default: |
| 731 break; |
| 732 } |
| 733 |
| 734 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), even
t); |
| 735 |
| 700 // Handle link highlighting outside the main switch to avoid getting lost in
the | 736 // Handle link highlighting outside the main switch to avoid getting lost in
the |
| 701 // complicated set of cases handled below. | 737 // complicated set of cases handled below. |
| 702 switch (event.type) { | 738 switch (event.type) { |
| 703 case WebInputEvent::GestureTapDown: | 739 case WebInputEvent::GestureTapDown: |
| 704 // Queue a highlight animation, then hand off to regular handler. | 740 // Queue a highlight animation, then hand off to regular handler. |
| 705 #if OS(LINUX) | 741 #if OS(LINUX) |
| 706 if (settingsImpl()->gestureTapHighlightEnabled()) | 742 if (settingsImpl()->gestureTapHighlightEnabled()) |
| 707 enableTouchHighlight(event); | 743 enableTapHighlight(platformEvent); |
| 708 #endif | 744 #endif |
| 709 break; | 745 break; |
| 710 case WebInputEvent::GestureTapCancel: | 746 case WebInputEvent::GestureTapCancel: |
| 711 case WebInputEvent::GestureTap: | 747 case WebInputEvent::GestureTap: |
| 712 case WebInputEvent::GestureLongPress: | 748 case WebInputEvent::GestureLongPress: |
| 713 if (m_linkHighlight) | 749 if (m_linkHighlight) |
| 714 m_linkHighlight->startHighlightAnimationIfNeeded(); | 750 m_linkHighlight->startHighlightAnimationIfNeeded(); |
| 715 break; | 751 break; |
| 716 default: | 752 default: |
| 717 break; | 753 break; |
| 718 } | 754 } |
| 719 | 755 |
| 720 switch (event.type) { | 756 switch (event.type) { |
| 721 case WebInputEvent::GestureFlingStart: { | |
| 722 if (mainFrameImpl()->frame()->eventHandler()->isScrollbarHandlingGesture
s()) | |
| 723 break; | |
| 724 m_client->cancelScheduledContentIntents(); | |
| 725 m_positionOnFlingStart = WebPoint(event.x, event.y); | |
| 726 m_globalPositionOnFlingStart = WebPoint(event.globalX, event.globalY); | |
| 727 m_flingModifier = event.modifiers; | |
| 728 m_flingSourceDevice = event.sourceDevice; | |
| 729 OwnPtr<WebGestureCurve> flingCurve = adoptPtr(Platform::current()->creat
eFlingAnimationCurve(event.sourceDevice, WebFloatPoint(event.data.flingStart.vel
ocityX, event.data.flingStart.velocityY), WebSize())); | |
| 730 m_gestureAnimation = WebActiveGestureAnimation::createAtAnimationStart(f
lingCurve.release(), this); | |
| 731 scheduleAnimation(); | |
| 732 eventSwallowed = true; | |
| 733 break; | |
| 734 } | |
| 735 case WebInputEvent::GestureFlingCancel: | |
| 736 if (m_gestureAnimation) { | |
| 737 m_gestureAnimation.clear(); | |
| 738 if (m_layerTreeView) | |
| 739 m_layerTreeView->didStopFlinging(); | |
| 740 eventSwallowed = true; | |
| 741 } | |
| 742 break; | |
| 743 case WebInputEvent::GestureTap: { | 757 case WebInputEvent::GestureTap: { |
| 744 m_client->cancelScheduledContentIntents(); | 758 m_client->cancelScheduledContentIntents(); |
| 745 if (detectContentOnTouch(WebPoint(event.x, event.y))) { | 759 if (detectContentOnTouch(platformEvent.position())) { |
| 746 eventSwallowed = true; | 760 eventSwallowed = true; |
| 747 break; | 761 break; |
| 748 } | 762 } |
| 749 | 763 |
| 750 RefPtr<WebCore::PopupContainer> selectPopup; | 764 RefPtr<WebCore::PopupContainer> selectPopup; |
| 751 selectPopup = m_selectPopup; | 765 selectPopup = m_selectPopup; |
| 752 hideSelectPopup(); | 766 hideSelectPopup(); |
| 753 ASSERT(!m_selectPopup); | 767 ASSERT(!m_selectPopup); |
| 754 | 768 |
| 755 // Don't trigger a disambiguation popup on sites designed for mobile dev
ices. | 769 // Don't trigger a disambiguation popup on sites designed for mobile dev
ices. |
| 756 // Instead, assume that the page has been designed with big enough butto
ns and links. | 770 // Instead, assume that the page has been designed with big enough butto
ns and links. |
| 757 if (event.data.tap.width > 0 && !shouldDisableDesktopWorkarounds()) { | 771 if (event.data.tap.width > 0 && !shouldDisableDesktopWorkarounds()) { |
| 758 // FIXME: didTapMultipleTargets should just take a rect instead of | 772 // FIXME: didTapMultipleTargets should just take a rect instead of |
| 759 // an event. | 773 // an event. |
| 760 WebGestureEvent scaledEvent; | 774 WebGestureEvent scaledEvent = event; |
| 761 scaledEvent.x = event.x / pageScaleFactor(); | 775 scaledEvent.x = event.x / pageScaleFactor(); |
| 762 scaledEvent.y = event.y / pageScaleFactor(); | 776 scaledEvent.y = event.y / pageScaleFactor(); |
| 763 scaledEvent.data.tap.width = event.data.tap.width / pageScaleFactor(
); | 777 scaledEvent.data.tap.width = event.data.tap.width / pageScaleFactor(
); |
| 764 scaledEvent.data.tap.height = event.data.tap.height / pageScaleFacto
r(); | 778 scaledEvent.data.tap.height = event.data.tap.height / pageScaleFacto
r(); |
| 765 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); | 779 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); |
| 766 Vector<IntRect> goodTargets; | 780 Vector<IntRect> goodTargets; |
| 767 findGoodTouchTargets(boundingBox, mainFrameImpl()->frame(), goodTarg
ets); | 781 findGoodTouchTargets(boundingBox, mainFrameImpl()->frame(), goodTarg
ets); |
| 768 // FIXME: replace touch adjustment code when numberOfGoodTargets ==
1? | 782 // FIXME: replace touch adjustment code when numberOfGoodTargets ==
1? |
| 769 // Single candidate case is currently handled by: https://bugs.webki
t.org/show_bug.cgi?id=85101 | 783 // Single candidate case is currently handled by: https://bugs.webki
t.org/show_bug.cgi?id=85101 |
| 770 if (goodTargets.size() >= 2 && m_client && m_client->didTapMultipleT
argets(scaledEvent, goodTargets)) { | 784 if (goodTargets.size() >= 2 && m_client && m_client->didTapMultipleT
argets(scaledEvent, goodTargets)) { |
| 771 eventSwallowed = true; | 785 eventSwallowed = true; |
| 772 eventCancelled = true; | 786 eventCancelled = true; |
| 773 break; | 787 break; |
| 774 } | 788 } |
| 775 } | 789 } |
| 776 | 790 |
| 777 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(),
event); | |
| 778 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); | 791 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); |
| 779 | 792 |
| 780 if (m_selectPopup && m_selectPopup == selectPopup) { | 793 if (m_selectPopup && m_selectPopup == selectPopup) { |
| 781 // That tap triggered a select popup which is the same as the one th
at | 794 // That tap triggered a select popup which is the same as the one th
at |
| 782 // was showing before the tap. It means the user tapped the select | 795 // was showing before the tap. It means the user tapped the select |
| 783 // while the popup was showing, and as a result we first closed then | 796 // while the popup was showing, and as a result we first closed then |
| 784 // immediately reopened the select popup. It needs to be closed. | 797 // immediately reopened the select popup. It needs to be closed. |
| 785 hideSelectPopup(); | 798 hideSelectPopup(); |
| 786 } | 799 } |
| 787 | 800 |
| 788 break; | 801 break; |
| 789 } | 802 } |
| 790 case WebInputEvent::GestureTwoFingerTap: | 803 case WebInputEvent::GestureTwoFingerTap: |
| 791 case WebInputEvent::GestureLongPress: | 804 case WebInputEvent::GestureLongPress: |
| 792 case WebInputEvent::GestureLongTap: { | 805 case WebInputEvent::GestureLongTap: { |
| 793 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) | 806 if (!mainFrameImpl() || !mainFrameImpl()->frameView()) |
| 794 break; | 807 break; |
| 795 | 808 |
| 796 m_client->cancelScheduledContentIntents(); | 809 m_client->cancelScheduledContentIntents(); |
| 797 m_page->contextMenuController()->clearContextMenu(); | 810 m_page->contextMenuController()->clearContextMenu(); |
| 798 m_contextMenuAllowed = true; | 811 m_contextMenuAllowed = true; |
| 799 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(),
event); | |
| 800 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); | 812 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); |
| 801 m_contextMenuAllowed = false; | 813 m_contextMenuAllowed = false; |
| 802 | 814 |
| 803 break; | 815 break; |
| 804 } | 816 } |
| 805 case WebInputEvent::GestureTapDown: { | 817 case WebInputEvent::GestureTapDown: { |
| 806 m_client->cancelScheduledContentIntents(); | 818 m_client->cancelScheduledContentIntents(); |
| 807 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(),
event); | |
| 808 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); | 819 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); |
| 809 break; | 820 break; |
| 810 } | 821 } |
| 811 case WebInputEvent::GestureDoubleTap: | 822 case WebInputEvent::GestureDoubleTap: |
| 812 if (m_webSettings->doubleTapToZoomEnabled() && m_minimumPageScaleFactor
!= m_maximumPageScaleFactor) { | 823 if (m_webSettings->doubleTapToZoomEnabled() && m_minimumPageScaleFactor
!= m_maximumPageScaleFactor) { |
| 813 m_client->cancelScheduledContentIntents(); | 824 m_client->cancelScheduledContentIntents(); |
| 814 animateZoomAroundPoint(WebPoint(event.x, event.y), DoubleTap); | 825 animateZoomAroundPoint(platformEvent.position(), DoubleTap); |
| 815 eventSwallowed = true; | 826 eventSwallowed = true; |
| 816 break; | 827 break; |
| 817 } | 828 } |
| 818 case WebInputEvent::GestureScrollBegin: | 829 case WebInputEvent::GestureScrollBegin: |
| 819 case WebInputEvent::GesturePinchBegin: | 830 case WebInputEvent::GesturePinchBegin: |
| 820 m_client->cancelScheduledContentIntents(); | 831 m_client->cancelScheduledContentIntents(); |
| 821 case WebInputEvent::GestureScrollEnd: | 832 case WebInputEvent::GestureScrollEnd: |
| 822 case WebInputEvent::GestureScrollUpdate: | 833 case WebInputEvent::GestureScrollUpdate: |
| 823 case WebInputEvent::GestureScrollUpdateWithoutPropagation: | 834 case WebInputEvent::GestureScrollUpdateWithoutPropagation: |
| 824 case WebInputEvent::GestureTapCancel: | 835 case WebInputEvent::GestureTapCancel: |
| 825 case WebInputEvent::GesturePinchEnd: | 836 case WebInputEvent::GesturePinchEnd: |
| 826 case WebInputEvent::GesturePinchUpdate: { | 837 case WebInputEvent::GesturePinchUpdate: { |
| 827 PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(),
event); | |
| 828 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); | 838 eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGesture
Event(platformEvent); |
| 829 break; | 839 break; |
| 830 } | 840 } |
| 831 default: | 841 default: |
| 832 ASSERT_NOT_REACHED(); | 842 ASSERT_NOT_REACHED(); |
| 833 } | 843 } |
| 834 m_client->didHandleGestureEvent(event, eventCancelled); | 844 m_client->didHandleGestureEvent(event, eventCancelled); |
| 835 return eventSwallowed; | 845 return eventSwallowed; |
| 836 } | 846 } |
| 837 | 847 |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 static bool invokesHandCursor(Node* node, bool shiftKey, Frame* frame) | 1274 static bool invokesHandCursor(Node* node, bool shiftKey, Frame* frame) |
| 1265 { | 1275 { |
| 1266 if (!node || !node->renderer()) | 1276 if (!node || !node->renderer()) |
| 1267 return false; | 1277 return false; |
| 1268 | 1278 |
| 1269 ECursor cursor = node->renderer()->style()->cursor(); | 1279 ECursor cursor = node->renderer()->style()->cursor(); |
| 1270 return cursor == CURSOR_POINTER | 1280 return cursor == CURSOR_POINTER |
| 1271 || (cursor == CURSOR_AUTO && frame->eventHandler()->useHandCursor(node,
node->isLink(), shiftKey)); | 1281 || (cursor == CURSOR_AUTO && frame->eventHandler()->useHandCursor(node,
node->isLink(), shiftKey)); |
| 1272 } | 1282 } |
| 1273 | 1283 |
| 1274 Node* WebViewImpl::bestTouchLinkNode(const WebGestureEvent& touchEvent) | 1284 Node* WebViewImpl::bestTapNode(const PlatformGestureEvent& tapEvent) |
| 1275 { | 1285 { |
| 1276 if (!m_page || !m_page->mainFrame()) | 1286 if (!m_page || !m_page->mainFrame()) |
| 1277 return 0; | 1287 return 0; |
| 1278 | 1288 |
| 1279 Node* bestTouchNode = 0; | 1289 Node* bestTouchNode = 0; |
| 1280 | 1290 |
| 1281 IntSize touchEventSearchRegionSize(touchEvent.data.tapDown.width / 2, touchE
vent.data.tapDown.height / 2); | 1291 IntPoint touchEventLocation(tapEvent.position()); |
| 1282 IntPoint touchEventLocation(touchEvent.x, touchEvent.y); | |
| 1283 #if ENABLE(TOUCH_ADJUSTMENT) | 1292 #if ENABLE(TOUCH_ADJUSTMENT) |
| 1284 m_page->mainFrame()->eventHandler()->adjustGesturePosition(PlatformGestureEv
entBuilder(mainFrameImpl()->frameView(), touchEvent), touchEventLocation); | 1293 m_page->mainFrame()->eventHandler()->adjustGesturePosition(tapEvent, touchEv
entLocation); |
| 1285 #endif | 1294 #endif |
| 1286 | 1295 |
| 1287 IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(touchE
ventLocation); | 1296 IntPoint hitTestPoint = m_page->mainFrame()->view()->windowToContents(touchE
ventLocation); |
| 1288 HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtP
oint( | 1297 HitTestResult result = m_page->mainFrame()->eventHandler()->hitTestResultAtP
oint( |
| 1289 hitTestPoint, false, false, DontHitTestScrollbars, HitTestRequest::Touch
Event); | 1298 hitTestPoint, false, false, DontHitTestScrollbars, HitTestRequest::Touch
Event); |
| 1290 bestTouchNode = result.targetNode(); | 1299 bestTouchNode = result.targetNode(); |
| 1291 | 1300 |
| 1292 // Make sure our highlight candidate uses a hand cursor as a heuristic to | 1301 // Make sure our highlight candidate uses a hand cursor as a heuristic to |
| 1293 // choose appropriate targets. | 1302 // choose appropriate targets. |
| 1294 bool shiftKey = touchEvent.modifiers & WebGestureEvent::ShiftKey; | 1303 while (bestTouchNode && !invokesHandCursor(bestTouchNode, false, m_page->mai
nFrame())) |
| 1295 while (bestTouchNode && !invokesHandCursor(bestTouchNode, shiftKey, m_page->
mainFrame())) | |
| 1296 bestTouchNode = bestTouchNode->parentNode(); | 1304 bestTouchNode = bestTouchNode->parentNode(); |
| 1297 | 1305 |
| 1298 // We should pick the largest enclosing node with hand cursor set. | 1306 // We should pick the largest enclosing node with hand cursor set. |
| 1299 while (bestTouchNode && bestTouchNode->parentNode() && invokesHandCursor(bes
tTouchNode->parentNode(), shiftKey, m_page->mainFrame())) | 1307 while (bestTouchNode && bestTouchNode->parentNode() && invokesHandCursor(bes
tTouchNode->parentNode(), false, m_page->mainFrame())) |
| 1300 bestTouchNode = bestTouchNode->parentNode(); | 1308 bestTouchNode = bestTouchNode->parentNode(); |
| 1301 | 1309 |
| 1302 return bestTouchNode; | 1310 return bestTouchNode; |
| 1303 } | 1311 } |
| 1304 | 1312 |
| 1305 void WebViewImpl::enableTouchHighlight(const WebGestureEvent& touchEvent) | 1313 void WebViewImpl::enableTapHighlight(const PlatformGestureEvent& tapEvent) |
| 1306 { | 1314 { |
| 1307 // Always clear any existing highlight when this is invoked, even if we don'
t get a new target to highlight. | 1315 // Always clear any existing highlight when this is invoked, even if we don'
t get a new target to highlight. |
| 1308 m_linkHighlight.clear(); | 1316 m_linkHighlight.clear(); |
| 1309 | 1317 |
| 1310 Node* touchNode = bestTouchLinkNode(touchEvent); | 1318 Node* touchNode = bestTapNode(tapEvent); |
| 1311 | 1319 |
| 1312 if (!touchNode || !touchNode->renderer() || !touchNode->renderer()->enclosin
gLayer()) | 1320 if (!touchNode || !touchNode->renderer() || !touchNode->renderer()->enclosin
gLayer()) |
| 1313 return; | 1321 return; |
| 1314 | 1322 |
| 1315 Color highlightColor = touchNode->renderer()->style()->tapHighlightColor(); | 1323 Color highlightColor = touchNode->renderer()->style()->tapHighlightColor(); |
| 1316 // Safari documentation for -webkit-tap-highlight-color says if the specifie
d color has 0 alpha, | 1324 // Safari documentation for -webkit-tap-highlight-color says if the specifie
d color has 0 alpha, |
| 1317 // then tap highlighting is disabled. | 1325 // then tap highlighting is disabled. |
| 1318 // http://developer.apple.com/library/safari/#documentation/appleapplication
s/reference/safaricssref/articles/standardcssproperties.html | 1326 // http://developer.apple.com/library/safari/#documentation/appleapplication
s/reference/safaricssref/articles/standardcssproperties.html |
| 1319 if (!highlightColor.alpha()) | 1327 if (!highlightColor.alpha()) |
| 1320 return; | 1328 return; |
| (...skipping 3067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4388 #endif | 4396 #endif |
| 4389 | 4397 |
| 4390 bool WebViewImpl::shouldDisableDesktopWorkarounds() | 4398 bool WebViewImpl::shouldDisableDesktopWorkarounds() |
| 4391 { | 4399 { |
| 4392 ViewportArguments arguments = mainFrameImpl()->frame()->document()->viewport
Arguments(); | 4400 ViewportArguments arguments = mainFrameImpl()->frame()->document()->viewport
Arguments(); |
| 4393 return arguments.width == ViewportArguments::ValueDeviceWidth || !arguments.
userZoom | 4401 return arguments.width == ViewportArguments::ValueDeviceWidth || !arguments.
userZoom |
| 4394 || (arguments.minZoom == arguments.maxZoom && arguments.minZoom != Viewp
ortArguments::ValueAuto); | 4402 || (arguments.minZoom == arguments.maxZoom && arguments.minZoom != Viewp
ortArguments::ValueAuto); |
| 4395 } | 4403 } |
| 4396 | 4404 |
| 4397 } // namespace WebKit | 4405 } // namespace WebKit |
| OLD | NEW |