Changeset 284738 in webkit


Ignore:
Timestamp:
Oct 22, 2021 8:25:23 PM (9 months ago)
Author:
Simon Fraser
Message:

Content offset in this codepen when switching tabs
https://bugs.webkit.org/show_bug.cgi?id=231989

Reviewed by Tim Horton.

Source/WebCore:

There were two problems that occurred with async-scrollable iframes when their associated
WKWebView was removed and re-added to the view hierarchy (e.g. when switching tabs).
These resulted in misplaced position:fixed content, and the first user scroll in the
iframe causing the scroll position to jump back to the top.

The positon:fixed issue was caused by an ordering problem in
ScrollingTreeFrameScrollingNode::commitStateBeforeChildren() which resulted in the layout
viewport being computed incorrectly; we called updateViewportForCurrentScrollPosition()
before setting the min and max scroll position, so we'd always clamp the layout viewport to
a location of 0,0.

The second scroll position reset issue was caused by the ScrollingTreeScrollingNode's
m_currentScrollPosition reverting to a stale after re-attaching the iframe's scrolling
subtree. ScrollingTreeScrollingNode::commitStateBeforeChildren() has code to set
m_currentScrollPosition from the state tree node's scroll position on first commit;
the issue was that ScrollingStateScrollingNode's scrollPosition() was not updated on every
scroll, only when something triggered a scrolling tree commit.

Fix by updating ScrollingStateScrollingNode's scrollPosition() for frame nodes on detach
(overflow scrolling nodes have their scroll positions updated eagerly).

Both fixes are tested by the ScrollingCoordinatorTests.ScrollingTreeAfterDetachReattach API test.

  • page/scrolling/AsyncScrollingCoordinator.cpp:

(WebCore::AsyncScrollingCoordinator::frameViewWillBeDetached):

  • page/scrolling/AsyncScrollingCoordinator.h:
  • page/scrolling/ScrollingCoordinator.h:

(WebCore::ScrollingCoordinator::frameViewWillBeDetached):

  • page/scrolling/ScrollingStateScrollingNode.cpp:

(WebCore::ScrollingStateScrollingNode::hasScrollPositionRequest const):

  • page/scrolling/ScrollingStateScrollingNode.h:
  • page/scrolling/ScrollingStateTree.cpp:

(WebCore::ScrollingStateTree::insertNode):

  • page/scrolling/ScrollingTreeFrameScrollingNode.cpp:

(WebCore::ScrollingTreeFrameScrollingNode::commitStateBeforeChildren):

  • page/scrolling/ScrollingTreeScrollingNode.cpp:

(WebCore::ScrollingTreeScrollingNode::commitStateBeforeChildren):
(WebCore::ScrollingTreeScrollingNode::dumpProperties const):

  • page/scrolling/mac/ScrollingCoordinatorMac.mm:

(WebCore::ScrollingCoordinatorMac::commitTreeStateIfNeeded):

  • rendering/RenderLayerCompositor.cpp:

(WebCore::RenderLayerCompositor::detachRootLayer):

Tools:

API test that scrolls an iframe via wheel events, then detached and re-attaches the view.

The two wheel scrolls are necessary to exercise the "stale ScrollingStateScrollingNode
scroll position" issue.

The scrolling tree dumps validate the layout viewport part of the fix.

Also correct some functions where the sense of 'isWaitingForJavaScript' was flipped.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/mac/ScrollingCoordinatorTests.mm: Added.

(TestWebKitAPI::synthesizeWheelEvents):
(TestWebKitAPI::waitForScrollEventAndReturnScrollY):
(TestWebKitAPI::scrollingTreeElidingLastCommittedScrollPosition):
(TestWebKitAPI::TEST):

  • TestWebKitAPI/cocoa/TestWKWebView.mm:

(-[WKWebView objectByEvaluatingJavaScript:]):
(-[WKWebView objectByEvaluatingJavaScriptWithUserGesture:]):
(-[WKWebView objectByCallingAsyncFunction:withArguments:error:]):

LayoutTests:

New baselines.

  • tiled-drawing/scrolling/clamp-out-of-bounds-scrolls-expected.txt:
  • tiled-drawing/scrolling/scrolling-tree-after-scroll-expected.txt:
Location:
trunk
Files:
1 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r284732 r284738  
     12021-10-22  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Content offset in this codepen when switching tabs
     4        https://bugs.webkit.org/show_bug.cgi?id=231989
     5
     6        Reviewed by Tim Horton.
     7
     8        New baselines.
     9
     10        * tiled-drawing/scrolling/clamp-out-of-bounds-scrolls-expected.txt:
     11        * tiled-drawing/scrolling/scrolling-tree-after-scroll-expected.txt:
     12
    1132021-10-22  Eric Hutchison  <ehutchison@apple.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r284737 r284738  
     12021-10-22  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Content offset in this codepen when switching tabs
     4        https://bugs.webkit.org/show_bug.cgi?id=231989
     5
     6        Reviewed by Tim Horton.
     7
     8        There were two problems that occurred with async-scrollable iframes when their associated
     9        WKWebView was removed and re-added to the view hierarchy (e.g. when switching tabs).
     10        These resulted in misplaced position:fixed content, and the first user scroll in the
     11        iframe causing the scroll position to jump back to the top.
     12
     13        The positon:fixed issue was caused by an ordering problem in
     14        ScrollingTreeFrameScrollingNode::commitStateBeforeChildren() which resulted in the layout
     15        viewport being computed incorrectly; we called updateViewportForCurrentScrollPosition()
     16        before setting the min and max scroll position, so we'd always clamp the layout viewport to
     17        a location of 0,0.
     18
     19        The second scroll position reset issue was caused by the ScrollingTreeScrollingNode's
     20        m_currentScrollPosition reverting to a stale after re-attaching the iframe's scrolling
     21        subtree. ScrollingTreeScrollingNode::commitStateBeforeChildren() has code to set
     22        m_currentScrollPosition from the state tree node's scroll position on first commit;
     23        the issue was that ScrollingStateScrollingNode's scrollPosition() was not updated on every
     24        scroll, only when something triggered a scrolling tree commit.
     25
     26        Fix by updating ScrollingStateScrollingNode's scrollPosition() for frame nodes on detach
     27        (overflow scrolling nodes have their scroll positions updated eagerly).
     28
     29        Both fixes are tested by the ScrollingCoordinatorTests.ScrollingTreeAfterDetachReattach API test.
     30
     31        * page/scrolling/AsyncScrollingCoordinator.cpp:
     32        (WebCore::AsyncScrollingCoordinator::frameViewWillBeDetached):
     33        * page/scrolling/AsyncScrollingCoordinator.h:
     34        * page/scrolling/ScrollingCoordinator.h:
     35        (WebCore::ScrollingCoordinator::frameViewWillBeDetached):
     36        * page/scrolling/ScrollingStateScrollingNode.cpp:
     37        (WebCore::ScrollingStateScrollingNode::hasScrollPositionRequest const):
     38        * page/scrolling/ScrollingStateScrollingNode.h:
     39        * page/scrolling/ScrollingStateTree.cpp:
     40        (WebCore::ScrollingStateTree::insertNode):
     41        * page/scrolling/ScrollingTreeFrameScrollingNode.cpp:
     42        (WebCore::ScrollingTreeFrameScrollingNode::commitStateBeforeChildren):
     43        * page/scrolling/ScrollingTreeScrollingNode.cpp:
     44        (WebCore::ScrollingTreeScrollingNode::commitStateBeforeChildren):
     45        (WebCore::ScrollingTreeScrollingNode::dumpProperties const):
     46        * page/scrolling/mac/ScrollingCoordinatorMac.mm:
     47        (WebCore::ScrollingCoordinatorMac::commitTreeStateIfNeeded):
     48        * rendering/RenderLayerCompositor.cpp:
     49        (WebCore::RenderLayerCompositor::detachRootLayer):
     50
    1512021-10-22  Eric Carlson  <eric.carlson@apple.com>
    252
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp

    r284685 r284738  
    185185}
    186186
     187void AsyncScrollingCoordinator::frameViewWillBeDetached(FrameView& frameView)
     188{
     189    ASSERT(isMainThread());
     190    ASSERT(m_page);
     191
     192    if (!coordinatesScrollingForFrameView(frameView))
     193        return;
     194
     195    auto* scrollingNode = downcast<ScrollingStateScrollingNode>(m_scrollingStateTree->stateNodeForID(frameView.scrollingNodeID()));
     196    if (!scrollingNode)
     197        return;
     198
     199    scrollingNode->setScrollPosition(frameView.scrollPosition());
     200}
     201
    187202void AsyncScrollingCoordinator::updateIsMonitoringWheelEventsForFrameView(const FrameView& frameView)
    188203{
  • trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h

    r284534 r284738  
    102102    WEBCORE_EXPORT void frameViewVisualViewportChanged(FrameView&) override;
    103103    WEBCORE_EXPORT void frameViewEventTrackingRegionsChanged(FrameView&) override;
     104    WEBCORE_EXPORT void frameViewWillBeDetached(FrameView&) override;
    104105
    105106    WEBCORE_EXPORT bool requestScrollPositionUpdate(ScrollableArea&, const ScrollPosition&, ScrollType, ScrollClamping) final;
  • trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h

    r284534 r284738  
    9797    virtual void frameViewRootLayerDidChange(FrameView&);
    9898
     99    virtual void frameViewWillBeDetached(FrameView&) { }
     100
    99101    // Traverses the scrolling tree, setting layer positions to represent the current scrolled state.
    100102    virtual void applyScrollingTreeLayerPositions() { }
  • trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.cpp

    r284685 r284738  
    207207}
    208208
     209bool ScrollingStateScrollingNode::hasScrollPositionRequest() const
     210{
     211    return hasChangedProperty(Property::RequestedScrollPosition) && m_requestedScrollData.requestType == ScrollRequestType::PositionUpdate;
     212}
     213
    209214void ScrollingStateScrollingNode::setIsMonitoringWheelEvents(bool isMonitoringWheelEvents)
    210215{
  • trunk/Source/WebCore/page/scrolling/ScrollingStateScrollingNode.h

    r284685 r284738  
    7979    WEBCORE_EXPORT void setRequestedScrollData(const RequestedScrollData&);
    8080
     81    WEBCORE_EXPORT bool hasScrollPositionRequest() const;
     82
    8183    bool isMonitoringWheelEvents() const { return m_isMonitoringWheelEvents; }
    8284    WEBCORE_EXPORT void setIsMonitoringWheelEvents(bool);
  • trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp

    r284685 r284738  
    177177        if (parentID) {
    178178            if (auto unparentedNode = m_unparentedNodes.take(newNodeID)) {
    179                 LOG_WITH_STREAM(ScrollingTree, stream << "ScrollingStateTree " << this << " insertNode " << newNodeID << " getting node from unparented nodes");
     179                LOG_WITH_STREAM(ScrollingTree, stream << "ScrollingStateTree " << this << " insertNode reattaching node " << newNodeID);
    180180                newNode = unparentedNode.get();
    181181                nodeWasReattachedRecursive(*unparentedNode);
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameScrollingNode.cpp

    r284685 r284738  
    7373        m_fixedElementsLayoutRelativeToFrame = state.fixedElementsLayoutRelativeToFrame();
    7474
    75     if (state.hasChangedProperty(ScrollingStateNode::Property::LayoutViewport)) {
     75    if (state.hasChangedProperty(ScrollingStateNode::Property::LayoutViewport))
    7676        m_layoutViewport = state.layoutViewport();
    77         updateViewportForCurrentScrollPosition({ });
    78     }
    7977
    8078    if (state.hasChangedProperty(ScrollingStateNode::Property::MinLayoutViewportOrigin))
     
    8684    if (state.hasChangedProperty(ScrollingStateNode::Property::OverrideVisualViewportSize))
    8785        m_overrideVisualViewportSize = state.overrideVisualViewportSize();
     86
     87    if (state.hasChangedProperty(ScrollingStateNode::Property::LayoutViewport)) {
     88        // This requires that minLayoutViewportOrigin and maxLayoutViewportOrigin have been updated.
     89        updateViewportForCurrentScrollPosition({ });
     90    }
    8891}
    8992
  • trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp

    r284685 r284738  
    6868    if (state.hasChangedProperty(ScrollingStateNode::Property::ScrollPosition)) {
    6969        m_lastCommittedScrollPosition = state.scrollPosition();
    70         if (m_isFirstCommit && !state.hasChangedProperty(ScrollingStateNode::Property::RequestedScrollPosition))
     70        if (m_isFirstCommit && !state.hasScrollPositionRequest())
    7171            m_currentScrollPosition = m_lastCommittedScrollPosition;
    7272    }
     
    337337    ts.dumpProperty("last committed scroll position", m_lastCommittedScrollPosition);
    338338
    339     if (m_scrollOrigin != IntPoint())
     339    if (!m_currentScrollPosition.isZero())
     340        ts.dumpProperty("scroll position", m_currentScrollPosition);
     341
     342    if (!m_scrollOrigin.isZero())
    340343        ts.dumpProperty("scroll origin", m_scrollOrigin);
    341344
  • trunk/Source/WebCore/page/scrolling/mac/ScrollingCoordinatorMac.mm

    r284685 r284738  
    115115        return;
    116116
    117     LOG_WITH_STREAM(ScrollingTree, stream << scrollingStateTreeAsText(debugScrollingStateTreeAsTextBehaviors));
     117    LOG_WITH_STREAM(ScrollingTree, stream << "ScrollingCoordinatorMac::commitTreeState: state tree " << scrollingStateTreeAsText(debugScrollingStateTreeAsTextBehaviors));
    118118
    119119    auto stateTree = scrollingStateTree()->commit(LayerRepresentation::PlatformLayerRepresentation);
  • trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp

    r284093 r284738  
    42454245        return;
    42464246
     4247    if (auto* scrollingCoordinator = this->scrollingCoordinator())
     4248        scrollingCoordinator->frameViewWillBeDetached(m_renderView.frameView());
     4249
    42474250    switch (m_rootLayerAttachment) {
    42484251    case RootLayerAttachedViaEnclosingFrame: {
     
    42584261
    42594262        if (auto frameRootScrollingNodeID = m_renderView.frameView().scrollingNodeID()) {
    4260             if (auto* scrollingCoordinator = this->scrollingCoordinator())
     4263            if (auto* scrollingCoordinator = this->scrollingCoordinator()) {
     4264                scrollingCoordinator->frameViewWillBeDetached(m_renderView.frameView());
    42614265                scrollingCoordinator->unparentNode(frameRootScrollingNodeID);
     4266            }
    42624267        }
    42634268        break;
     
    42654270    case RootLayerAttachedViaChromeClient: {
    42664271        auto& frame = m_renderView.frameView().frame();
     4272
     4273        if (auto* scrollingCoordinator = this->scrollingCoordinator())
     4274            scrollingCoordinator->frameViewWillBeDetached(m_renderView.frameView());
     4275
    42674276        page().chrome().client().attachRootGraphicsLayer(frame, nullptr);
    42684277    }
  • trunk/Tools/ChangeLog

    r284721 r284738  
     12021-10-22  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Content offset in this codepen when switching tabs
     4        https://bugs.webkit.org/show_bug.cgi?id=231989
     5
     6        Reviewed by Tim Horton.
     7
     8        API test that scrolls an iframe via wheel events, then detached and re-attaches the view.
     9
     10        The two wheel scrolls are necessary to exercise the "stale ScrollingStateScrollingNode
     11        scroll position" issue.
     12
     13        The scrolling tree dumps validate the layout viewport part of the fix.
     14
     15        Also correct some functions where the sense of 'isWaitingForJavaScript' was flipped.
     16
     17        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     18        * TestWebKitAPI/Tests/mac/ScrollingCoordinatorTests.mm: Added.
     19        (TestWebKitAPI::synthesizeWheelEvents):
     20        (TestWebKitAPI::waitForScrollEventAndReturnScrollY):
     21        (TestWebKitAPI::scrollingTreeElidingLastCommittedScrollPosition):
     22        (TestWebKitAPI::TEST):
     23        * TestWebKitAPI/cocoa/TestWKWebView.mm:
     24        (-[WKWebView objectByEvaluatingJavaScript:]):
     25        (-[WKWebView objectByEvaluatingJavaScriptWithUserGesture:]):
     26        (-[WKWebView objectByCallingAsyncFunction:withArguments:error:]):
     27
    1282021-10-22  Ryan Haddad  <ryanhaddad@apple.com>
    229
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r284685 r284738  
    8787                0F5651F71FCE4DDC00310FBC /* NoHistoryItemScrollToFragment.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F5651F61FCE4DDB00310FBC /* NoHistoryItemScrollToFragment.mm */; };
    8888                0F5651F91FCE513500310FBC /* scroll-to-anchor.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 0F5651F81FCE50E800310FBC /* scroll-to-anchor.html */; };
     89                0FEFAF64271FC2CD005704D7 /* ScrollingCoordinatorTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0FEFAF63271FC2CD005704D7 /* ScrollingCoordinatorTests.mm */; };
    8990                0FF1134E22D68679009A81DA /* ScrollViewScrollabilityTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0FF1134D22D68679009A81DA /* ScrollViewScrollabilityTests.mm */; };
    9091                115EB3431EE0BA03003C2C0A /* ViewportSizeForViewportUnits.mm in Sources */ = {isa = PBXBuildFile; fileRef = 115EB3421EE0B720003C2C0A /* ViewportSizeForViewportUnits.mm */; };
     
    18621863                0FE447971B76F1E3009498EB /* ParkingLot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParkingLot.cpp; sourceTree = "<group>"; };
    18631864                0FEAE3671B7D19CB00CE17F2 /* Condition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Condition.cpp; sourceTree = "<group>"; };
     1865                0FEFAF63271FC2CD005704D7 /* ScrollingCoordinatorTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollingCoordinatorTests.mm; sourceTree = "<group>"; };
    18641866                0FF1134D22D68679009A81DA /* ScrollViewScrollabilityTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollViewScrollabilityTests.mm; sourceTree = "<group>"; };
    18651867                0FFC45A41B73EBE20085BD62 /* Lock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Lock.cpp; sourceTree = "<group>"; };
     
    30963098                F44A531021B8976900DBB99C /* InstanceMethodSwizzler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = InstanceMethodSwizzler.mm; path = ../TestRunnerShared/cocoa/InstanceMethodSwizzler.mm; sourceTree = "<group>"; };
    30973099                F44A7D1F268D5C6900B49BB8 /* ImageAnalysisTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ImageAnalysisTests.mm; sourceTree = "<group>"; };
    3098                 F44A9AF52649BBDD00E7CB16 /* ImmediateActionTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImmediateActionTests.h; sourceTree = "<group>"; };
    30993100                F44A9AF62649BBDD00E7CB16 /* ImmediateActionTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ImmediateActionTests.mm; sourceTree = "<group>"; };
    31003101                F44C79FB20F9E50C0014478C /* ParserYieldTokenPlugIn.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ParserYieldTokenPlugIn.mm; sourceTree = "<group>"; };
     
    48334834                                9B4F8FA3159D52B1002D9F94 /* HTMLCollectionNamedItem.mm */,
    48344835                                9B26FC6B159D061000CC3765 /* HTMLFormCollectionNamedItem.mm */,
    4835                                 F44A9AF52649BBDD00E7CB16 /* ImmediateActionTests.h */,
    48364836                                F44A9AF62649BBDD00E7CB16 /* ImmediateActionTests.mm */,
    48374837                                C507E8A614C6545B005D6B3B /* InspectorBar.mm */,
     
    48534853                                37C784DE197C8F2E0010A496 /* RenderedImageFromDOMNode.mm */,
    48544854                                3722C8681461E03E00C45D00 /* RenderedImageFromDOMRange.mm */,
     4855                                0FEFAF63271FC2CD005704D7 /* ScrollingCoordinatorTests.mm */,
    48554856                                261516D515B0E60500A2C201 /* SetAndUpdateCacheModel.mm */,
    48564857                                52B8CF9515868CF000281053 /* SetDocumentURI.mm */,
     
    58515852                                CDCFA7AA1E45183200C2433D /* SampleMap.cpp in Sources */,
    58525853                                CE0947372063223B003C9BA0 /* SchemeRegistry.mm in Sources */,
     5854                                0FEFAF64271FC2CD005704D7 /* ScrollingCoordinatorTests.mm in Sources */,
    58535855                                CDC0932B21C872C10030C4B0 /* ScrollingDoesNotPauseMedia.mm in Sources */,
    58545856                                7CCE7F121A411AE600447C4C /* ScrollPinningBehaviors.cpp in Sources */,
  • trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.h

    r284685 r284738  
    140140- (void)sendClicksAtPoint:(NSPoint)pointInWindow numberOfClicks:(NSUInteger)numberOfClicks;
    141141- (void)sendClickAtPoint:(NSPoint)pointInWindow;
     142- (void)wheelEventAtPoint:(CGPoint)pointInWindow wheelDelta:(CGSize)delta;
    142143- (NSWindow *)hostWindow;
    143144- (void)typeCharacter:(char)character modifiers:(NSEventModifierFlags)modifiers;
  • trunk/Tools/TestWebKitAPI/cocoa/TestWKWebView.mm

    r284685 r284738  
    205205- (id)objectByEvaluatingJavaScript:(NSString *)script
    206206{
    207     bool isWaitingForJavaScript = false;
     207    bool callbackComplete = false;
    208208    RetainPtr<id> evalResult;
    209209    [self _evaluateJavaScriptWithoutUserGesture:script completionHandler:[&] (id result, NSError *error) {
    210210        evalResult = result;
    211         isWaitingForJavaScript = true;
     211        callbackComplete = true;
    212212        EXPECT_TRUE(!error);
    213213        if (error)
    214214            NSLog(@"Encountered error: %@ while evaluating script: %@", error, script);
    215215    }];
    216     TestWebKitAPI::Util::run(&isWaitingForJavaScript);
     216    TestWebKitAPI::Util::run(&callbackComplete);
    217217    return evalResult.autorelease();
    218218}
     
    220220- (id)objectByEvaluatingJavaScriptWithUserGesture:(NSString *)script
    221221{
    222     bool isWaitingForJavaScript = false;
     222    bool callbackComplete = false;
    223223    RetainPtr<id> evalResult;
    224224    [self evaluateJavaScript:script completionHandler:[&] (id result, NSError *error) {
    225225        evalResult = result;
    226         isWaitingForJavaScript = true;
     226        callbackComplete = true;
    227227        EXPECT_TRUE(!error);
    228228        if (error)
    229229            NSLog(@"Encountered error: %@ while evaluating script: %@", error, script);
    230230    }];
    231     TestWebKitAPI::Util::run(&isWaitingForJavaScript);
     231    TestWebKitAPI::Util::run(&callbackComplete);
    232232    return evalResult.autorelease();
    233233}
     
    235235- (id)objectByCallingAsyncFunction:(NSString *)script withArguments:(NSDictionary *)arguments error:(NSError **)errorOut
    236236{
    237     bool isWaitingForJavaScript = false;
     237    bool callbackComplete = false;
    238238    if (errorOut)
    239239        *errorOut = nil;
     
    244244        evalResult = result;
    245245        strongError = error;
    246         isWaitingForJavaScript = true;
    247     }];
    248     TestWebKitAPI::Util::run(&isWaitingForJavaScript);
     246        callbackComplete = true;
     247    }];
     248    TestWebKitAPI::Util::run(&callbackComplete);
    249249
    250250    if (errorOut)
     
    863863}
    864864
     865- (void)wheelEventAtPoint:(CGPoint)pointInWindow wheelDelta:(CGSize)delta
     866{
     867    RetainPtr<CGEventRef> cgScrollEvent = adoptCF(CGEventCreateScrollWheelEvent(nullptr, kCGScrollEventUnitPixel, 2, delta.height, delta.width, 0));
     868
     869    CGPoint locationInGlobalScreenCoordinates = [[self window] convertPointToScreen:pointInWindow];
     870    locationInGlobalScreenCoordinates.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - locationInGlobalScreenCoordinates.y;
     871    CGEventSetLocation(cgScrollEvent.get(), locationInGlobalScreenCoordinates);
     872   
     873    NSEvent* event = [NSEvent eventWithCGEvent:cgScrollEvent.get()];
     874    [self scrollWheel:event];
     875}
     876
    865877- (NSWindow *)hostWindow
    866878{
Note: See TracChangeset for help on using the changeset viewer.