mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 21:17:03 +00:00
Fixed: web view AppKit scrollbars often did not reflect the true content size of the view.
The reason for this is that the size changes as the page progressively loads, and this continues after the 'load' event fired. For now, we use a simple timer to poll the size a few times after loading. These polls are very bad for performance and battery life so we terminate them quickly, meaning that the underlying problem where the contents of the web view can get out of sync with its scrollbars fundamentally remains - this fix merely alleviates the problem.
This commit is contained in:
+52
-5
@@ -40,7 +40,22 @@ CPWebViewScrollAuto = 0;
|
||||
CPWebViewScrollAppKit = 1;
|
||||
CPWebViewScrollNative = 2;
|
||||
|
||||
// FIXME: somehow make CPWebView work with CPScrollView instead of native scrollbars (is this even possible?)
|
||||
|
||||
/*!
|
||||
How often the size of the document will be checked at page load time when
|
||||
AppKit scrollbars are used.
|
||||
*/
|
||||
CPWebViewAppKitScrollPollInterval = 1.0;
|
||||
/*!
|
||||
How many times the size of the size of the document will be checked at
|
||||
page load time when AppKit scrollbars are used.
|
||||
|
||||
The polling method is bad for performance so we wish to disable it as
|
||||
soon as the page has finished loading. The assumption is that after
|
||||
CPWebViewAppKitScrollMaxPollCount * CPWebViewAppKitScrollPollInterval,
|
||||
the page should be fully loaded and the size final.
|
||||
*/
|
||||
CPWebViewAppKitScrollMaxPollCount = 3;
|
||||
|
||||
/*!
|
||||
@ingroup appkit
|
||||
@@ -85,6 +100,8 @@ CPWebViewScrollNative = 2;
|
||||
int _scrollMode;
|
||||
int _effectiveScrollMode;
|
||||
BOOL _contentIsAccessible;
|
||||
CPTimer _contentSizeCheckTimer;
|
||||
int _contentSizePollCount;
|
||||
CGSize _scrollSize;
|
||||
|
||||
int _loadHTMLStringTimer;
|
||||
@@ -240,10 +257,13 @@ CPWebViewScrollNative = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO If we do have access to the content, it might be that the 'body' element simply hasn't loaded yet.
|
||||
CPLog.warn("using default size 800*1600");
|
||||
|
||||
[_frameView setFrameSize:CGSizeMake(800, 1600)];
|
||||
// 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];
|
||||
@@ -297,12 +317,31 @@ CPWebViewScrollNative = 2;
|
||||
var parent = _iframe.parentNode;
|
||||
parent.removeChild(_iframe);
|
||||
|
||||
[_contentSizeCheckTimer invalidate];
|
||||
if (_effectiveScrollMode === CPWebViewScrollAppKit)
|
||||
{
|
||||
[_scrollView setHasHorizontalScroller:YES];
|
||||
[_scrollView setHasVerticalScroller:YES];
|
||||
|
||||
_iframe.setAttribute("scrolling", "no");
|
||||
|
||||
/*
|
||||
FIXME Need better method.
|
||||
We don't know when the content of the iframe changes size (e.g. a
|
||||
picture finishes loading, dynamic content is loaded). Often when a
|
||||
page has initially 'loaded', it does not yet have its final size. In
|
||||
lieu of any resize events we will simply check back in a few times
|
||||
some time after loading.
|
||||
|
||||
We run these checks only a limited number of times as to not deplete
|
||||
battery life and slow down the software needlessly. This does mean
|
||||
there are situations where the content changes size and the AppKit
|
||||
scrollbars will be out of sync. Users who have dynamic content
|
||||
in their web view will, for now, have to implement domain specific
|
||||
fixes.
|
||||
*/
|
||||
_contentSizePollCount = 0;
|
||||
_contentSizeCheckTimer = [CPTimer scheduledTimerWithTimeInterval:CPWebViewAppKitScrollPollInterval target:self selector:@selector(_maybePollWebFrameSize) userInfo:nil repeats:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -319,6 +358,14 @@ CPWebViewScrollNative = 2;
|
||||
[self _resizeWebFrame];
|
||||
}
|
||||
|
||||
- (void)_maybePollWebFrameSize
|
||||
{
|
||||
if (CPWebViewAppKitScrollMaxPollCount == 0 || _contentSizePollCount++ < CPWebViewAppKitScrollMaxPollCount)
|
||||
[self _resizeWebFrame];
|
||||
else
|
||||
[_contentSizeCheckTimer invalidate];
|
||||
}
|
||||
|
||||
/*!
|
||||
Loads a string of HTML into the webview.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user