CPWebView is sized incorrectly after animation [+1] #1893

Open
mikecsh opened this Issue Apr 3, 2013 · 6 comments

Projects

None yet

3 participants

Contributor
mikecsh commented Apr 3, 2013

Apologies in advance for a somewhat unclear issue.

I have a CPWebView within an LPSlideView. When the CPWebView is animated offscreen and then back on screen, it is drawn with incorrect frame size. If animated horizontally, the width is incorrect. If animated vertically, the height is incorrect. I've spent a while tracking this down, to see if it was in my code, LPSlideView, LPViewAnimation, CPAnimation and so on. As far as I can tell, the UIWebView has the correct frame information at each stage of the animation process, including the final state. It appears to be the iframe which is incorrectly sized. This issue does not affect plain CPViews which are animated. It seems to be down to changing the frame origin of the CPWebView.

I have tried to make a reduction in the form of an AppController.j which can be pasted over a newly capp gen'd project. It creates two views, a UIView and a CPWebView. By commenting and uncommenting a line you can set which is added to the window's contentView as a subview. I then use three nested setTimeouts to simulate an animation, changing the frame origin of the chosen view each time, with the final setTimeout resetting the frame origin to its original value (0,0).

Then CPView animates correctly and is drawn correctly after it is returned to its initial value. The CPWebView animates correctly (seemingly) but is drawn incorrectly after it is returned to its initial value.

I would expect it to behave in the same way as the CPView.

You can find the reduction in the following gist:
https://gist.github.com/mikecsh/5297483

Contributor
mikecsh commented Apr 3, 2013

+1

cappbot commented Apr 3, 2013

Milestone: Someday. Vote: 1. Label: #new. What's next? A reviewer should examine this issue.

Contributor

-#new
+bug
+#needs-review
+AppKit

cappbot commented Apr 3, 2013

Milestone: Someday. Vote: 1. Labels: #needs-review, AppKit, bug. What's next? This issue is pending an architectural or implementation design decision and should be discussed or voted on.

Contributor

This is a bug in the _resizeWebFrame method of CPWebView. I'm not quite sure how to fix it though.

It looks like it's actually shrinking the available size of the DOM platform window with this code:

- (void)_resizeWebFrame
{
    // When a webview is not in the DOM we can't inspect its contents for sizing information.
    // If we try, we might end up setting the fallback frame size which will then become
    // somewhat sticky.
    if (![self _isVisible])
    {
        return;
    }

    if (_effectiveScrollMode === CPWebViewScrollAppKit)
    {
        var visibleRect = [_frameView visibleRect];
        [_frameView setFrameSize:CGSizeMake(CGRectGetMaxX(visibleRect), CGRectGetMaxY(visibleRect))];

        // try to get the document size so we can correctly set the frame
        var win = [self DOMWindow];

        if (win && win.document && win.document.body)
        {
            var width = win.document.body.scrollWidth,
                height = win.document.body.scrollHeight;

            _iframe.setAttribute("width", width);
            _iframe.setAttribute("height", height);

            [_frameView setFrameSize:CGSizeMake(width, height)];
        }
        else
        {
            // If we do have access to the content, it might be that the 'body' element simply hasn't loaded yet.
            // The size will be updated by the content size timer in this case.
            if (!win || !win.document)
            {
                CPLog.warn("using default size 800*1600");
                [_frameView setFrameSize:CGSizeMake(800, 1600)];
            }
        }

        [_frameView scrollRectToVisible:visibleRect];
    }
}

In [_frameView setFrameSize:CGSizeMake(width, height)]; it's getting set to the DOMWindow width/height, which apparently changes with the change in origin. This doesn't have a chance to get reset, since the frame size is always set to the current frame size:

var visibleRect = [_frameView visibleRect];
[_frameView setFrameSize:CGSizeMake(CGRectGetMaxX(visibleRect), CGRectGetMaxY(visibleRect))];

Any thoughts?

Contributor
mikecsh commented Apr 20, 2014

I haven't looked at this in much detail but:

var visibleRect = [_frameView visibleRect];

Returns a seemingly incorrect frame in my app. As a workaround I have overridden _resizeWebFrame in a subclass of CPWebView where I set the visibleRect like so:

var visibleRect = [[self superview] visibleRect];

It's a bit of a hacky workaround but it solves my problem for now; I will revisit it when I have time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment