/*
 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "WebFrameView.h"

#import "WebClipView.h"
#import "WebDataSourcePrivate.h"
#import "WebDocument.h"
#import "WebDynamicScrollBarsViewInternal.h"
#import "WebFrame.h"
#import "WebFrameInternal.h"
#import "WebFrameViewInternal.h"
#import "WebFrameViewPrivate.h"
#import "WebHistoryItemInternal.h"
#import "WebHTMLViewPrivate.h"
#import "WebKeyGenerator.h"
#import "WebKitErrorsPrivate.h"
#import "WebKitStatisticsPrivate.h"
#import "WebKitVersionChecks.h"
#import "WebNSDictionaryExtras.h"
#import "WebNSObjectExtras.h"
#import "WebNSPasteboardExtras.h"
#import "WebNSViewExtras.h"
#import "WebNSWindowExtras.h"
#import "WebPDFView.h"
#import "WebPreferenceKeysPrivate.h"
#import "WebResourceInternal.h"
#import "WebSystemInterface.h"
#import "WebViewFactory.h"
#import "WebViewInternal.h"
#import "WebViewPrivate.h"
#import <Foundation/NSURLRequest.h>
#import <WebCore/BackForwardListImpl.h>
#import <WebCore/DragController.h>
#import <WebCore/EventHandler.h>
#import <WebCore/Frame.h>
#import <WebCore/FrameView.h>
#import <WebCore/HistoryItem.h>
#import <WebCore/Page.h>
#import <WebCore/RenderPart.h>
#import <WebCore/ThreadCheck.h>
#import <WebCore/WebCoreFrameView.h>
#import <WebCore/WebCoreView.h>
#import <WebKitSystemInterface.h>
#import <wtf/Assertions.h>

using namespace WebCore;

@interface NSWindow (WindowPrivate)
- (BOOL)_needsToResetDragMargins;
- (void)_setNeedsToResetDragMargins:(BOOL)s;
@end

@interface NSClipView (AppKitSecretsIKnow)
- (BOOL)_scrollTo:(const NSPoint *)newOrigin animate:(BOOL)animate; // need the boolean result from this method
@end

enum {
    SpaceKey = 0x0020
};

@interface WebFrameView (WebFrameViewFileInternal) <WebCoreFrameView>
- (float)_verticalKeyboardScrollDistance;
@end

@interface WebFrameViewPrivate : NSObject {
@public
    WebFrame *webFrame;
    WebDynamicScrollBarsView *frameScrollView;
    BOOL includedInWebKitStatistics;
}
@end

@implementation WebFrameViewPrivate

- (void)dealloc
{
    [frameScrollView release];
    [super dealloc];
}

@end

@implementation WebFrameView (WebFrameViewFileInternal)

- (float)_verticalKeyboardScrollDistance
{
    // Arrow keys scroll the same distance that clicking the scroll arrow does.
    return [[self _scrollView] verticalLineScroll];
}

- (Frame*)_web_frame
{
    return core(_private->webFrame);
}

@end

@implementation WebFrameView (WebInternal)

// Note that the WebVew is not retained.
- (WebView *)_webView
{
    return [_private->webFrame webView];
}

- (void)_setDocumentView:(NSView <WebDocumentView> *)view
{
    WebDynamicScrollBarsView *sv = [self _scrollView];
    core([self _webView])->dragController()->setDidInitiateDrag(false);
    
    [sv setSuppressLayout:YES];
    
    // If the old view is the first responder, transfer first responder status to the new view as 
    // a convenience and so that we don't leave the window pointing to a view that's no longer in it.
    NSWindow *window = [sv window];
    NSResponder *firstResponder = [window firstResponder];
    bool makeNewViewFirstResponder = [firstResponder isKindOfClass:[NSView class]] && [(NSView *)firstResponder isDescendantOf:[sv documentView]];

    // Suppress the resetting of drag margins since we know we can't affect them.
    BOOL resetDragMargins = [window _needsToResetDragMargins];
    [window _setNeedsToResetDragMargins:NO];
    [sv setDocumentView:view];
    [window _setNeedsToResetDragMargins:resetDragMargins];

    if (makeNewViewFirstResponder)
        [window makeFirstResponder:view];
    [sv setSuppressLayout:NO];
}

-(NSView <WebDocumentView> *)_makeDocumentViewForDataSource:(WebDataSource *)dataSource
{
    NSString* MIMEType = [dataSource _responseMIMEType];
    if (!MIMEType)
        MIMEType = @"text/html";
    Class viewClass = [self _viewClassForMIMEType:MIMEType];
    NSView <WebDocumentView> *documentView;
    if (viewClass) {
        // If the dataSource's representation has already been created, and it is also the
        // same class as the desired documentView, then use it as the documentView instead
        // of creating another one (Radar 4340787).
        id <WebDocumentRepresentation> dataSourceRepresentation = [dataSource representation];
        if (dataSourceRepresentation && [dataSourceRepresentation class] == viewClass)
            documentView = (NSView <WebDocumentView> *)[dataSourceRepresentation retain];
        else
            documentView = [[viewClass alloc] initWithFrame:[self bounds]];
    } else
        documentView = nil;
    
    [self _setDocumentView:documentView];
    [documentView release];
    
    return documentView;
}

- (void)_setWebFrame:(WebFrame *)webFrame
{
    if (!webFrame) {
        NSView *docV = [self documentView];
        if ([docV respondsToSelector:@selector(close)])
            [docV performSelector:@selector(close)];
    }

    // Not retained because the WebView owns the WebFrame, which owns the WebFrameView.
    _private->webFrame = webFrame;    

    if (!_private->includedInWebKitStatistics && [webFrame _isIncludedInWebKitStatistics]) {
        _private->includedInWebKitStatistics = YES;
        ++WebFrameViewCount;
    }
}

- (WebDynamicScrollBarsView *)_scrollView
{
    // This can be called by [super dealloc] when cleaning up the key view loop,
    // after _private has been nilled out.
    if (_private == nil)
        return nil;
    return _private->frameScrollView;
}

- (float)_verticalPageScrollDistance
{
    float height = [[self _contentView] bounds].size.height;
    return max<float>(height * Scrollbar::minFractionToStepWhenPaging(), height - Scrollbar::maxOverlapBetweenPages());
}

static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCClass, NSArray *supportTypes)
{
    NSEnumerator *enumerator = [supportTypes objectEnumerator];
    ASSERT(enumerator != nil);
    NSString *mime = nil;
    while ((mime = [enumerator nextObject]) != nil) {
        // Don't clobber previously-registered classes.
        if ([allTypes objectForKey:mime] == nil)
            [allTypes setObject:objCClass forKey:mime];
    }
}

+ (NSMutableDictionary *)_viewTypesAllowImageTypeOmission:(BOOL)allowImageTypeOmission
{
    static NSMutableDictionary *viewTypes = nil;
    static BOOL addedImageTypes = NO;
    
    if (!viewTypes) {
        viewTypes = [[NSMutableDictionary alloc] init];
        addTypesFromClass(viewTypes, [WebHTMLView class], [WebHTMLView supportedNonImageMIMETypes]);

        // Since this is a "secret default" we don't bother registering it.
        BOOL omitPDFSupport = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitOmitPDFSupport"];
        if (!omitPDFSupport)
            addTypesFromClass(viewTypes, [WebPDFView class], [WebPDFView supportedMIMETypes]);
    }
    
    if (!addedImageTypes && !allowImageTypeOmission) {
        addTypesFromClass(viewTypes, [WebHTMLView class], [WebHTMLView supportedImageMIMETypes]);
        addedImageTypes = YES;
    }
    
    return viewTypes;
}

+ (BOOL)_canShowMIMETypeAsHTML:(NSString *)MIMEType
{
    return [[[self _viewTypesAllowImageTypeOmission:YES] _webkit_objectForMIMEType:MIMEType] isSubclassOfClass:[WebHTMLView class]];
}

+ (Class)_viewClassForMIMEType:(NSString *)MIMEType allowingPlugins:(BOOL)allowPlugins
{
    Class viewClass;
    return [WebView _viewClass:&viewClass andRepresentationClass:nil forMIMEType:MIMEType allowingPlugins:allowPlugins] ? viewClass : nil;
}

- (Class)_viewClassForMIMEType:(NSString *)MIMEType
{
    return [[self class] _viewClassForMIMEType:MIMEType allowingPlugins:[[[self _webView] preferences] arePlugInsEnabled]];
}

- (void)_install
{
    ASSERT(_private->webFrame);
    ASSERT(_private->frameScrollView);

    Frame* frame = core(_private->webFrame);

    ASSERT(frame);
    ASSERT(frame->page());

    // If this isn't the main frame, it must have an owner element set, or it
    // won't ever get installed in the view hierarchy.
    ASSERT(frame == frame->page()->mainFrame() || frame->ownerElement());

    FrameView* view = frame->view();

    view->setPlatformWidget(_private->frameScrollView);

    // FIXME: Frame tries to do this too. Is this code needed?
    if (RenderPart* owner = frame->ownerRenderer()) {
        owner->setWidget(view);
        // Now the render part owns the view, so we don't any more.
    }

    view->updateCanHaveScrollbars();
}

@end

@implementation WebFrameView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (!self)
        return nil;
 
    static bool didFirstTimeInitialization;
    if (!didFirstTimeInitialization) {
        didFirstTimeInitialization = true;
        InitWebCoreSystemInterface();
        
        // Need to tell WebCore what function to call for the "History Item has Changed" notification.
        // Note: We also do this in WebHistoryItem's init method.
        WebCore::notifyHistoryItemChanged = WKNotifyHistoryItemChanged;

        [WebViewFactory createSharedFactory];

// FIXME: Remove the NSAppKitVersionNumberWithDeferredWindowDisplaySupport check once
// once AppKit's Deferred Window Display support is available.
#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) || !defined(NSAppKitVersionNumberWithDeferredWindowDisplaySupport)
        // CoreGraphics deferred updates are disabled if WebKitEnableCoalescedUpdatesPreferenceKey is NO
        // or has no value. For compatibility with Mac OS X 10.5 and lower, deferred updates are off by default.
        if (![[NSUserDefaults standardUserDefaults] boolForKey:WebKitEnableDeferredUpdatesPreferenceKey])
            WKDisableCGDeferredUpdates();
#endif
        if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_MAIN_THREAD_EXCEPTIONS))
            setDefaultThreadViolationBehavior(LogOnFirstThreadViolation, ThreadViolationRoundOne);

        bool throwExceptionsForRoundTwo = WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_ROUND_TWO_MAIN_THREAD_EXCEPTIONS);
#ifdef MAIL_THREAD_WORKAROUND
        // Even if old Mail is linked with new WebKit, don't throw exceptions.
        if ([WebResource _needMailThreadWorkaroundIfCalledOffMainThread])
            throwExceptionsForRoundTwo = false;
#endif
        if (!throwExceptionsForRoundTwo)
            setDefaultThreadViolationBehavior(LogOnFirstThreadViolation, ThreadViolationRoundTwo);
    }

    _private = [[WebFrameViewPrivate alloc] init];

    WebDynamicScrollBarsView *scrollView = [[WebDynamicScrollBarsView alloc] initWithFrame:NSMakeRect(0.0f, 0.0f, frame.size.width, frame.size.height)];
    _private->frameScrollView = scrollView;
    [scrollView setContentView:[[[WebClipView alloc] initWithFrame:[scrollView bounds]] autorelease]];
    [scrollView setDrawsBackground:NO];
    [scrollView setHasVerticalScroller:NO];
    [scrollView setHasHorizontalScroller:NO];
    [scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
    [scrollView setLineScroll:Scrollbar::pixelsPerLineStep()];
    [self addSubview:scrollView];

    // Don't call our overridden version of setNextKeyView here; we need to make the standard NSView
    // link between us and our subview so that previousKeyView and previousValidKeyView work as expected.
    // This works together with our becomeFirstResponder and setNextKeyView overrides.
    [super setNextKeyView:scrollView];
    
    return self;
}

- (void)dealloc 
{
    if (_private && _private->includedInWebKitStatistics)
        --WebFrameViewCount;
    
    [_private release];
    _private = nil;
    
    [super dealloc];
}

- (void)finalize 
{
    if (_private && _private->includedInWebKitStatistics)
        --WebFrameViewCount;

    [super finalize];
}

- (WebFrame *)webFrame
{
    // This method can be called beneath -[NSView dealloc] after _private has been cleared.
    return _private ? _private->webFrame : nil;
}

- (void)setAllowsScrolling:(BOOL)flag
{
    WebCore::Frame *frame = core([self webFrame]);
    if (WebCore::FrameView *view = frame? frame->view() : 0)
        view->setCanHaveScrollbars(flag);
}

- (BOOL)allowsScrolling
{
    WebCore::Frame *frame = core([self webFrame]);
    if (WebCore::FrameView *view = frame? frame->view() : 0)
        return view->canHaveScrollbars();
    return YES;
}

- (NSView <WebDocumentView> *)documentView
{
    return [[self _scrollView] documentView];
}

- (BOOL)acceptsFirstResponder
{
    // We always accept first responder; this matches OS X 10.2 WebKit
    // behavior (see 3469791).
    return YES;
}

- (BOOL)becomeFirstResponder
{
    // This works together with setNextKeyView to splice the WebFrameView into
    // the key loop similar to the way NSScrollView does this. Note that
    // WebView has similar code.
    
    NSWindow *window = [self window];
    if ([window keyViewSelectionDirection] == NSSelectingPrevious) {
        NSView *previousValidKeyView = [self previousValidKeyView];
        // If we couldn't find a previous valid key view, ask the WebView. This handles frameset
        // cases (one is mentioned in Radar bug 3748628). Note that previousValidKeyView should
        // never be self but can be due to AppKit oddness (mentioned in Radar bug 3748628).
        if (previousValidKeyView == nil || previousValidKeyView == self)
            previousValidKeyView = [[[self webFrame] webView] previousValidKeyView];
        [window makeFirstResponder:previousValidKeyView];
    } else {
        // If the scroll view won't accept first-responderness now, then just become
        // the first responder ourself like a normal view. This lets us be the first 
        // responder in cases where no page has yet been loaded.
        if ([[self _scrollView] acceptsFirstResponder])
            [window makeFirstResponder:[self _scrollView]];
    }
    
    return YES;
}

- (void)setNextKeyView:(NSView *)aView
{
    // This works together with becomeFirstResponder to splice the WebFrameView into
    // the key loop similar to the way NSScrollView does this. Note that
    // WebView has very similar code.
    if ([self _scrollView] != nil) {
        [[self _scrollView] setNextKeyView:aView];
    } else {
        [super setNextKeyView:aView];
    }
}

- (BOOL)isOpaque
{
    return [[self _webView] drawsBackground];
}

- (void)drawRect:(NSRect)rect
{
    if ([self documentView] == nil) {
        // Need to paint ourselves if there's no documentView to do it instead.
        if ([[self _webView] drawsBackground]) {
            [[[self _webView] backgroundColor] set];
            NSRectFill(rect);
        }
    } else {
#ifndef NDEBUG
        if ([[self _scrollView] drawsBackground]) {
            [[NSColor cyanColor] set];
            NSRectFill(rect);
        }
#endif
    }
}

- (NSRect)visibleRect
{
    // This method can be called beneath -[NSView dealloc] after we have cleared _private.
    if (!_private)
        return [super visibleRect];

    // FIXME: <rdar://problem/6213380> This method does not work correctly with transforms, for two reasons:
    // 1) [super visibleRect] does not account for the transform, since it is not represented
    //    in the NSView hierarchy.
    // 2) -_getVisibleRect: does not correct for transforms.

    NSRect rendererVisibleRect;
    if (![[self webFrame] _getVisibleRect:&rendererVisibleRect])
        return [super visibleRect];

    if (NSIsEmptyRect(rendererVisibleRect))
        return NSZeroRect;

    NSRect viewVisibleRect = [super visibleRect];
    if (NSIsEmptyRect(viewVisibleRect))
        return NSZeroRect;

    NSRect frame = [self frame];
    // rendererVisibleRect is in the parent's coordinate space, and frame is in the superview's coordinate space.
    // The return value from this method needs to be in this view's coordinate space. We get that right by subtracting
    // the origins (and correcting for flipping), but when we support transforms, we will need to do better than this.
    rendererVisibleRect.origin.x -= frame.origin.x;
    rendererVisibleRect.origin.y = NSMaxY(frame) - NSMaxY(rendererVisibleRect);
    return NSIntersectionRect(rendererVisibleRect, viewVisibleRect);
}

- (void)setFrameSize:(NSSize)size
{
    if (!NSEqualSizes(size, [self frame].size)) {
        // See WebFrameLoaderClient::provisionalLoadStarted.
        if ([[[self webFrame] webView] drawsBackground])
            [[self _scrollView] setDrawsBackground:YES];
        if (Frame* coreFrame = [self _web_frame]) {
            if (FrameView* coreFrameView = coreFrame->view())
                coreFrameView->setNeedsLayout();
        }
    }
    [super setFrameSize:size];
}

- (void)setBoundsSize:(NSSize)size
{
    [super setBoundsSize:size];
    [[self _scrollView] setFrameSize:size];
}

- (void)viewDidMoveToWindow
{
    // See WebFrameLoaderClient::provisionalLoadStarted.
    // Need to check _private for nil because this can be called inside -[WebView initWithCoder:].
    if (_private && [[[self webFrame] webView] drawsBackground])
        [[self _scrollView] setDrawsBackground:YES];
    [super viewDidMoveToWindow];
}

- (BOOL)_scrollOverflowInDirection:(ScrollDirection)direction granularity:(ScrollGranularity)granularity
{
    // scrolling overflows is only applicable if we're dealing with an WebHTMLView
    if (![[self documentView] isKindOfClass:[WebHTMLView class]])
        return NO;
    Frame* frame = core([self webFrame]);
    if (!frame)
        return NO;
    return frame->eventHandler()->scrollOverflow(direction, granularity);
}


- (BOOL)_isVerticalDocument
{
    Frame* coreFrame = [self _web_frame];
    if (!coreFrame)
        return YES;
    Document* document = coreFrame->document();
    if (!document)
        return YES;
    RenderObject* renderView = document->renderer();
    if (!renderView)
        return YES;
    return renderView->style()->isHorizontalWritingMode();
}

- (BOOL)_isFlippedDocument
{
    Frame* coreFrame = [self _web_frame];
    if (!coreFrame)
        return NO;
    Document* document = coreFrame->document();
    if (!document)
        return NO;
    RenderObject* renderView = document->renderer();
    if (!renderView)
        return NO;
    return renderView->style()->isFlippedBlocksWritingMode();
}

- (BOOL)_scrollToBeginningOfDocument
{
    if ([self _scrollOverflowInDirection:ScrollUp granularity:ScrollByDocument])
        return YES;
    if (![self _isScrollable])
        return NO;
    NSPoint point = [[[self _scrollView] documentView] frame].origin;
    point.x += [[self _scrollView] scrollOrigin].x;
    point.y += [[self _scrollView] scrollOrigin].y;
    return [[self _contentView] _scrollTo:&point animate:YES];
}

- (BOOL)_scrollToEndOfDocument
{
    if ([self _scrollOverflowInDirection:ScrollDown granularity:ScrollByDocument])
        return YES;
    if (![self _isScrollable])
        return NO;
    NSRect frame = [[[self _scrollView] documentView] frame];
    
    bool isVertical = [self _isVerticalDocument];
    bool isFlipped = [self _isFlippedDocument];

    NSPoint point;
    if (isVertical) {
        if (!isFlipped)
            point = NSMakePoint(frame.origin.x, NSMaxY(frame));
        else
            point = NSMakePoint(frame.origin.x, NSMinY(frame));
    } else {
        if (!isFlipped)
            point = NSMakePoint(NSMaxX(frame), frame.origin.y);
        else
            point = NSMakePoint(NSMinX(frame), frame.origin.y);
    }
    
    // Reset the position opposite to the block progression direction.
    if (isVertical)
        point.x += [[self _scrollView] scrollOrigin].x;
    else
        point.y += [[self _scrollView] scrollOrigin].y;
    return [[self _contentView] _scrollTo:&point animate:YES];
}

- (void)scrollToBeginningOfDocument:(id)sender
{
    if ([self _scrollToBeginningOfDocument])
        return;
    
    if (WebFrameView *child = [self _largestScrollableChild]) {
        if ([child _scrollToBeginningOfDocument])
            return;
    }
    [[self nextResponder] tryToPerform:@selector(scrollToBeginningOfDocument:) with:sender];
}

- (void)scrollToEndOfDocument:(id)sender
{
    if ([self _scrollToEndOfDocument])
        return;

    if (WebFrameView *child = [self _largestScrollableChild]) {
        if ([child _scrollToEndOfDocument])
            return;
    }
    [[self nextResponder] tryToPerform:@selector(scrollToEndOfDocument:) with:sender];
}

- (void)_goBack
{
    [[self _webView] goBack];
}

- (void)_goForward
{
    [[self _webView] goForward];
}

- (BOOL)_scrollVerticallyBy:(float)delta
{
    // This method uses the secret method _scrollTo on NSClipView.
    // It does that because it needs to know definitively whether scrolling was
    // done or not to help implement the "scroll parent if we are at the limit" feature.
    // In the presence of smooth scrolling, there's no easy way to tell if the method
    // did any scrolling or not with the public API.
    NSPoint point = [[self _contentView] bounds].origin;
    point.y += delta;
    return [[self _contentView] _scrollTo:&point animate:YES];
}

- (BOOL)_scrollHorizontallyBy:(float)delta
{
    NSPoint point = [[self _contentView] bounds].origin;
    point.x += delta;
    return [[self _contentView] _scrollTo:&point animate:YES];
}

- (float)_horizontalKeyboardScrollDistance
{
    // Arrow keys scroll the same distance that clicking the scroll arrow does.
    return [[self _scrollView] horizontalLineScroll];
}

- (float)_horizontalPageScrollDistance
{
    float width = [[self _contentView] bounds].size.width;
    return max<float>(width * Scrollbar::minFractionToStepWhenPaging(), width - Scrollbar::maxOverlapBetweenPages());
}

- (BOOL)_pageVertically:(BOOL)up
{
    if ([self _scrollOverflowInDirection:up ? ScrollUp : ScrollDown granularity:ScrollByPage])
        return YES;
    
    if (![self _isScrollable])
        return [[self _largestScrollableChild] _pageVertically:up];

    float delta = [self _verticalPageScrollDistance];
    return [self _scrollVerticallyBy:up ? -delta : delta];
}

- (BOOL)_pageHorizontally:(BOOL)left
{
    if ([self _scrollOverflowInDirection:left ? ScrollLeft : ScrollRight granularity:ScrollByPage])
        return YES;

    if (![self _isScrollable])
        return [[self _largestScrollableChild] _pageHorizontally:left];
    
    float delta = [self _horizontalPageScrollDistance];
    return [self _scrollHorizontallyBy:left ? -delta : delta];
}

- (BOOL)_pageInBlockProgressionDirection:(BOOL)forward
{
    // Determine whether we're calling _pageVertically or _pageHorizontally.
    BOOL isVerticalDocument = [self _isVerticalDocument];
    BOOL isFlippedBlock = [self _isFlippedDocument];
    if (isVerticalDocument)
        return [self _pageVertically:isFlippedBlock ? !forward : forward];
    return [self _pageHorizontally:isFlippedBlock ? !forward : forward];
}

- (BOOL)_scrollLineVertically:(BOOL)up
{
    if ([self _scrollOverflowInDirection:up ? ScrollUp : ScrollDown granularity:ScrollByLine])
        return YES;

    if (![self _isScrollable])
        return [[self _largestScrollableChild] _scrollLineVertically:up];
    
    float delta = [self _verticalKeyboardScrollDistance];
    return [self _scrollVerticallyBy:up ? -delta : delta];
}

- (BOOL)_scrollLineHorizontally:(BOOL)left
{
    if ([self _scrollOverflowInDirection:left ? ScrollLeft : ScrollRight granularity:ScrollByLine])
        return YES;

    if (![self _isScrollable])
        return [[self _largestScrollableChild] _scrollLineHorizontally:left];

    float delta = [self _horizontalKeyboardScrollDistance];
    return [self _scrollHorizontallyBy:left ? -delta : delta];
}

- (void)scrollPageUp:(id)sender
{
    if (![self _pageInBlockProgressionDirection:YES]) {
        // If we were already at the top, tell the next responder to scroll if it can.
        [[self nextResponder] tryToPerform:@selector(scrollPageUp:) with:sender];
    }
}

- (void)scrollPageDown:(id)sender
{
    if (![self _pageInBlockProgressionDirection:NO]) {
        // If we were already at the bottom, tell the next responder to scroll if it can.
        [[self nextResponder] tryToPerform:@selector(scrollPageDown:) with:sender];
    }
}

- (void)scrollLineUp:(id)sender
{
    if (![self _scrollLineVertically:YES])
        [[self nextResponder] tryToPerform:@selector(scrollLineUp:) with:sender];
}

- (void)scrollLineDown:(id)sender
{
    if (![self _scrollLineVertically:NO])
        [[self nextResponder] tryToPerform:@selector(scrollLineDown:) with:sender];
}

- (BOOL)_firstResponderIsFormControl
{
    NSResponder *firstResponder = [[self window] firstResponder];
    
    // WebHTMLView is an NSControl subclass these days, but it's not a form control
    if ([firstResponder isKindOfClass:[WebHTMLView class]]) {
        return NO;
    }
    return [firstResponder isKindOfClass:[NSControl class]];
}

- (void)keyDown:(NSEvent *)event
{
    // Implement common browser behaviors for all kinds of content.

    // FIXME: This is not a good time to execute commands for WebHTMLView. We should run these at the time commands sent by key bindings
    // are executed for consistency.
    // This doesn't work automatically because most of the keys handled here are translated into moveXXX commands, which are not handled
    // by Editor when focus is not in editable content.

    NSString *characters = [event characters];
    int index, count;
    BOOL callSuper = YES;
    Frame* coreFrame = [self _web_frame];
    BOOL maintainsBackForwardList = coreFrame && static_cast<BackForwardListImpl*>(coreFrame->page()->backForwardList())->enabled() ? YES : NO;
    
    count = [characters length];
    for (index = 0; index < count; ++index) {
        switch ([characters characterAtIndex:index]) {
            case NSDeleteCharacter:
                if (!maintainsBackForwardList) {
                    callSuper = YES;
                    break;
                }
                // This odd behavior matches some existing browsers,
                // including Windows IE
                if ([event modifierFlags] & NSShiftKeyMask) {
                    [self _goForward];
                } else {
                    [self _goBack];
                }
                callSuper = NO;
                break;
            case SpaceKey:
                // Checking for a control will allow events to percolate 
                // correctly when the focus is on a form control and we
                // are in full keyboard access mode.
                if ((![self allowsScrolling] && ![self _largestScrollableChild]) || [self _firstResponderIsFormControl]) {
                    callSuper = YES;
                    break;
                }
                if ([event modifierFlags] & NSShiftKeyMask) {
                    [self scrollPageUp:nil];
                } else {
                    [self scrollPageDown:nil];
                }
                callSuper = NO;
                break;
            case NSPageUpFunctionKey:
                if (![self allowsScrolling] && ![self _largestScrollableChild]) {
                    callSuper = YES;
                    break;
                }
                [self scrollPageUp:nil];
                callSuper = NO;
                break;
            case NSPageDownFunctionKey:
                if (![self allowsScrolling] && ![self _largestScrollableChild]) {
                    callSuper = YES;
                    break;
                }
                [self scrollPageDown:nil];
                callSuper = NO;
                break;
            case NSHomeFunctionKey:
                if (![self allowsScrolling] && ![self _largestScrollableChild]) {
                    callSuper = YES;
                    break;
                }
                [self scrollToBeginningOfDocument:nil];
                callSuper = NO;
                break;
            case NSEndFunctionKey:
                if (![self allowsScrolling] && ![self _largestScrollableChild]) {
                    callSuper = YES;
                    break;
                }
                [self scrollToEndOfDocument:nil];
                callSuper = NO;
                break;
            case NSUpArrowFunctionKey:
                // We don't handle shifted or control-arrow keys here, so let super have a chance.
                if ([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask)) {
                    callSuper = YES;
                    break;
                }
                if ((![self allowsScrolling] && ![self _largestScrollableChild]) ||
                    [[[self window] firstResponder] isKindOfClass:[NSPopUpButton class]]) {
                    // Let arrow keys go through to pop up buttons
                    // <rdar://problem/3455910>: hitting up or down arrows when focus is on a 
                    // pop-up menu should pop the menu
                    callSuper = YES;
                    break;
                }
                if ([event modifierFlags] & NSCommandKeyMask) {
                    [self scrollToBeginningOfDocument:nil];
                } else if ([event modifierFlags] & NSAlternateKeyMask) {
                    [self scrollPageUp:nil];
                } else {
                    [self scrollLineUp:nil];
                }
                callSuper = NO;
                break;
            case NSDownArrowFunctionKey:
                // We don't handle shifted or control-arrow keys here, so let super have a chance.
                if ([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask)) {
                    callSuper = YES;
                    break;
                }
                if ((![self allowsScrolling] && ![self _largestScrollableChild]) ||
                    [[[self window] firstResponder] isKindOfClass:[NSPopUpButton class]]) {
                    // Let arrow keys go through to pop up buttons
                    // <rdar://problem/3455910>: hitting up or down arrows when focus is on a 
                    // pop-up menu should pop the menu
                    callSuper = YES;
                    break;
                }
                if ([event modifierFlags] & NSCommandKeyMask) {
                    [self scrollToEndOfDocument:nil];
                } else if ([event modifierFlags] & NSAlternateKeyMask) {
                    [self scrollPageDown:nil];
                } else {
                    [self scrollLineDown:nil];
                }
                callSuper = NO;
                break;
            case NSLeftArrowFunctionKey:
                // We don't handle shifted or control-arrow keys here, so let super have a chance.
                if ([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask)) {
                    callSuper = YES;
                    break;
                }
                // Check back/forward related keys.
                if ([event modifierFlags] & NSCommandKeyMask) {
                    if (!maintainsBackForwardList) {
                        callSuper = YES;
                        break;
                    }
                    [self _goBack];
                } else {
                    // Now check scrolling related keys.
                    if ((![self allowsScrolling] && ![self _largestScrollableChild])) {
                        callSuper = YES;
                        break;
                    }

                    if ([event modifierFlags] & NSAlternateKeyMask) {
                        [self _pageHorizontally:YES];
                    } else {
                        [self _scrollLineHorizontally:YES];
                    }
                }
                callSuper = NO;
                break;
            case NSRightArrowFunctionKey:
                // We don't handle shifted or control-arrow keys here, so let super have a chance.
                if ([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask)) {
                    callSuper = YES;
                    break;
                }
                // Check back/forward related keys.
                if ([event modifierFlags] & NSCommandKeyMask) {
                    if (!maintainsBackForwardList) {
                        callSuper = YES;
                        break;
                    }
                    [self _goForward];
                } else {
                    // Now check scrolling related keys.
                    if ((![self allowsScrolling] && ![self _largestScrollableChild])) {
                        callSuper = YES;
                        break;
                    }

                    if ([event modifierFlags] & NSAlternateKeyMask) {
                        [self _pageHorizontally:NO];
                    } else {
                        [self _scrollLineHorizontally:NO];
                    }
                }
                callSuper = NO;
                break;
        }
    }
    
    if (callSuper) {
        [super keyDown:event];
    } else {
        // if we did something useful, get the cursor out of the way
        [NSCursor setHiddenUntilMouseMoves:YES];
    }
}

- (NSView *)_webcore_effectiveFirstResponder
{
    NSView *view = [self documentView];
    return view ? [view _webcore_effectiveFirstResponder] : [super _webcore_effectiveFirstResponder];
}

- (BOOL)canPrintHeadersAndFooters
{
    NSView *documentView = [[self _scrollView] documentView];
    if ([documentView respondsToSelector:@selector(canPrintHeadersAndFooters)]) {
        return [(id)documentView canPrintHeadersAndFooters];
    }
    return NO;
}

- (NSPrintOperation *)printOperationWithPrintInfo:(NSPrintInfo *)printInfo
{
    NSView *documentView = [[self _scrollView] documentView];
    if (!documentView) {
        return nil;
    }
    if ([documentView respondsToSelector:@selector(printOperationWithPrintInfo:)]) {
        return [(id)documentView printOperationWithPrintInfo:printInfo];
    }
    return [NSPrintOperation printOperationWithView:documentView printInfo:printInfo];
}

- (BOOL)documentViewShouldHandlePrint
{
    NSView *documentView = [[self _scrollView] documentView];
    if (documentView && [documentView respondsToSelector:@selector(documentViewShouldHandlePrint)])
        return [(id)documentView documentViewShouldHandlePrint];
    
    return NO;
}

- (void)printDocumentView
{
    NSView *documentView = [[self _scrollView] documentView];
    if (documentView && [documentView respondsToSelector:@selector(printDocumentView)])
        [(id)documentView printDocumentView];
}

@end

@implementation WebFrameView (WebPrivate)

- (float)_area
{
    NSRect frame = [self frame];
    return frame.size.height * frame.size.width;
}

- (BOOL)_isScrollable
{
    WebDynamicScrollBarsView *scrollView = [self _scrollView];
    return [scrollView horizontalScrollingAllowed] || [scrollView verticalScrollingAllowed];
}

- (WebFrameView *)_largestScrollableChild
{
    WebFrameView *largest = nil;
    NSArray *frameChildren = [[self webFrame] childFrames];
    
    unsigned i;
    for (i=0; i < [frameChildren count]; i++) {
        WebFrameView *childFrameView = [[frameChildren objectAtIndex:i] frameView];
        WebFrameView *scrollableFrameView = [childFrameView _isScrollable] ? childFrameView : [childFrameView _largestScrollableChild];
        if (!scrollableFrameView)
            continue;
        
        // Some ads lurk in child frames of zero width and height, see radar 4406994. These don't count as scrollable.
        // Maybe someday we'll discover that this minimum area check should be larger, but this covers the known cases.
        float area = [scrollableFrameView _area];
        if (area < 1.0)
            continue;
        
        if (!largest || (area > [largest _area])) {
            largest = scrollableFrameView;
        }
    }
    
    return largest;
}

- (BOOL)_hasScrollBars
{
    // FIXME: This method was used by Safari 4.0.x and older versions, but has not been used by any other WebKit
    // clients to my knowledge, and will not be used by future versions of Safari. It can probably be removed 
    // once we no longer need to keep nightly WebKit builds working with Safari 4.0.x and earlier.
    NSScrollView *scrollView = [self _scrollView];
    return [scrollView hasHorizontalScroller] || [scrollView hasVerticalScroller];
}

- (WebFrameView *)_largestChildWithScrollBars
{
    // FIXME: This method was used by Safari 4.0.x and older versions, but has not been used by any other WebKit
    // clients to my knowledge, and will not be used by future versions of Safari. It can probably be removed 
    // once we no longer need to keep nightly WebKit builds working with Safari 4.0.x and earlier.
    WebFrameView *largest = nil;
    NSArray *frameChildren = [[self webFrame] childFrames];
    
    unsigned i;
    for (i=0; i < [frameChildren count]; i++) {
        WebFrameView *childFrameView = [[frameChildren objectAtIndex:i] frameView];
        WebFrameView *scrollableFrameView = [childFrameView _hasScrollBars] ? childFrameView : [childFrameView _largestChildWithScrollBars];
        if (!scrollableFrameView)
            continue;
        
        // Some ads lurk in child frames of zero width and height, see radar 4406994. These don't count as scrollable.
        // Maybe someday we'll discover that this minimum area check should be larger, but this covers the known cases.
        float area = [scrollableFrameView _area];
        if (area < 1.0)
            continue;
        
        if (!largest || (area > [largest _area])) {
            largest = scrollableFrameView;
        }
    }
    
    return largest;
}

- (NSClipView *)_contentView
{
    return [[self _scrollView] contentView];
}

- (Class)_customScrollViewClass
{
    if ([_private->frameScrollView class] == [WebDynamicScrollBarsView class])
        return nil;
    return [_private->frameScrollView class];
}

- (void)_setCustomScrollViewClass:(Class)customClass
{
    if (!customClass)
        customClass = [WebDynamicScrollBarsView class];
    ASSERT([customClass isSubclassOfClass:[WebDynamicScrollBarsView class]]);
    if (customClass == [_private->frameScrollView class])
        return;
    if (![customClass isSubclassOfClass:[WebDynamicScrollBarsView class]])
        return;

    WebDynamicScrollBarsView *oldScrollView = _private->frameScrollView; // already retained
    NSView <WebDocumentView> *documentView = [[self documentView] retain];

    WebDynamicScrollBarsView *scrollView  = [[customClass alloc] initWithFrame:[oldScrollView frame]];
    [scrollView setContentView:[[[WebClipView alloc] initWithFrame:[scrollView bounds]] autorelease]];
    [scrollView setDrawsBackground:[oldScrollView drawsBackground]];
    [scrollView setHasVerticalScroller:[oldScrollView hasVerticalScroller]];
    [scrollView setHasHorizontalScroller:[oldScrollView hasHorizontalScroller]];
    [scrollView setAutoresizingMask:[oldScrollView autoresizingMask]];
    [scrollView setLineScroll:[oldScrollView lineScroll]];
    [self addSubview:scrollView];

    // don't call our overridden version here; we need to make the standard NSView link between us
    // and our subview so that previousKeyView and previousValidKeyView work as expected. This works
    // together with our becomeFirstResponder and setNextKeyView overrides.
    [super setNextKeyView:scrollView];

    _private->frameScrollView = scrollView;

    [self _setDocumentView:documentView];
    [self _install];

    [oldScrollView removeFromSuperview];
    [oldScrollView release];
    [documentView release];
}

@end
