summaryrefslogtreecommitdiffstats
path: root/WebKit/mac/WebView
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /WebKit/mac/WebView
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'WebKit/mac/WebView')
-rw-r--r--WebKit/mac/WebView/WebDocumentInternal.h3
-rw-r--r--WebKit/mac/WebView/WebFrame.mm57
-rw-r--r--WebKit/mac/WebView/WebFrameInternal.h4
-rw-r--r--WebKit/mac/WebView/WebFramePrivate.h3
-rw-r--r--WebKit/mac/WebView/WebFullScreenController.h78
-rw-r--r--WebKit/mac/WebView/WebFullScreenController.mm923
-rw-r--r--WebKit/mac/WebView/WebHTMLView.mm13
-rw-r--r--WebKit/mac/WebView/WebPDFView.mm36
-rw-r--r--WebKit/mac/WebView/WebScriptDebugger.mm2
-rw-r--r--WebKit/mac/WebView/WebScriptWorld.mm2
-rw-r--r--WebKit/mac/WebView/WebTextCompletionController.mm2
-rw-r--r--WebKit/mac/WebView/WebVideoFullscreenController.mm12
-rw-r--r--WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm4
-rw-r--r--WebKit/mac/WebView/WebView.mm39
-rw-r--r--WebKit/mac/WebView/WebViewData.h7
-rw-r--r--WebKit/mac/WebView/WebViewInternal.h9
16 files changed, 1128 insertions, 66 deletions
diff --git a/WebKit/mac/WebView/WebDocumentInternal.h b/WebKit/mac/WebView/WebDocumentInternal.h
index 4bf11d1..bcb6c07 100644
--- a/WebKit/mac/WebView/WebDocumentInternal.h
+++ b/WebKit/mac/WebView/WebDocumentInternal.h
@@ -68,7 +68,8 @@
@end
@protocol WebDocumentOptionsSearching <NSObject>
-- (BOOL)findString:(NSString *)string options:(WebFindOptions)options;
+// Prefixed with an underscore to avoid conflict with Mail's -[WebHTMLView(MailExtras) findString:options:].
+- (BOOL)_findString:(NSString *)string options:(WebFindOptions)options;
@end
/* Used to save and restore state in the view, typically when going back/forward */
diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm
index b0f9bb9..5c2f256 100644
--- a/WebKit/mac/WebView/WebFrame.mm
+++ b/WebKit/mac/WebView/WebFrame.mm
@@ -56,11 +56,12 @@
#import <WebCore/AccessibilityObject.h>
#import <WebCore/AnimationController.h>
#import <WebCore/CSSMutableStyleDeclaration.h>
+#import <WebCore/CachedResourceLoader.h>
#import <WebCore/Chrome.h>
#import <WebCore/ColorMac.h>
#import <WebCore/DOMImplementation.h>
-#import <WebCore/CachedResourceLoader.h>
#import <WebCore/DocumentFragment.h>
+#import <WebCore/DocumentMarkerController.h>
#import <WebCore/EventHandler.h>
#import <WebCore/EventNames.h>
#import <WebCore/Frame.h>
@@ -688,27 +689,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
return _private->coreFrame->view() ? _private->coreFrame->view()->needsLayout() : false;
}
-- (id)_accessibilityTree
-{
-#if HAVE(ACCESSIBILITY)
- if (!AXObjectCache::accessibilityEnabled()) {
- AXObjectCache::enableAccessibility();
- if ([[NSApp accessibilityAttributeValue:NSAccessibilityEnhancedUserInterfaceAttribute] boolValue])
- AXObjectCache::enableEnhancedUserInterfaceAccessibility();
- }
-
- if (!_private->coreFrame || !_private->coreFrame->document())
- return nil;
- RenderView* root = toRenderView(_private->coreFrame->document()->renderer());
- if (!root)
- return nil;
- return _private->coreFrame->document()->axObjectCache()->getOrCreate(root)->wrapper();
-#else
- return nil;
-#endif
-}
-
-- (DOMRange *)_rangeByAlteringCurrentSelection:(SelectionController::EAlteration)alteration direction:(SelectionController::EDirection)direction granularity:(TextGranularity)granularity
+- (DOMRange *)_rangeByAlteringCurrentSelection:(SelectionController::EAlteration)alteration direction:(SelectionDirection)direction granularity:(TextGranularity)granularity
{
if (_private->coreFrame->selection()->isNone())
return nil;
@@ -1338,13 +1319,14 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
if (!AXObjectCache::accessibilityEnabled())
return;
- RenderView* root = toRenderView(_private->coreFrame->document()->renderer());
- if (!root)
+ if (!_private->coreFrame || !_private->coreFrame->document())
return;
- AccessibilityObject* rootObject = _private->coreFrame->document()->axObjectCache()->getOrCreate(root);
- String strName(name);
- rootObject->setAccessibleName(strName);
+ AccessibilityObject* rootObject = _private->coreFrame->document()->axObjectCache()->rootObject();
+ if (rootObject) {
+ String strName(name);
+ rootObject->setAccessibleName(strName);
+ }
#endif
}
@@ -1365,6 +1347,27 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
return coreFrame->editor()->selectionStartHasSpellingMarkerFor(from, length);
}
+- (id)accessibilityRoot
+{
+#if HAVE(ACCESSIBILITY)
+ if (!AXObjectCache::accessibilityEnabled()) {
+ AXObjectCache::enableAccessibility();
+ if ([[NSApp accessibilityAttributeValue:NSAccessibilityEnhancedUserInterfaceAttribute] boolValue])
+ AXObjectCache::enableEnhancedUserInterfaceAccessibility();
+ }
+
+ if (!_private->coreFrame || !_private->coreFrame->document())
+ return nil;
+
+ AccessibilityObject* rootObject = _private->coreFrame->document()->axObjectCache()->rootObject();
+ if (rootObject)
+ return rootObject->wrapper();
+ return nil;
+#else
+ return nil;
+#endif
+}
+
@end
@implementation WebFrame
diff --git a/WebKit/mac/WebView/WebFrameInternal.h b/WebKit/mac/WebView/WebFrameInternal.h
index 8cdc272..7ff5e75 100644
--- a/WebKit/mac/WebView/WebFrameInternal.h
+++ b/WebKit/mac/WebView/WebFrameInternal.h
@@ -138,9 +138,7 @@ WebView *getWebView(WebFrame *webFrame);
- (NSRect)_firstRectForDOMRange:(DOMRange *)range;
- (void)_scrollDOMRangeToVisible:(DOMRange *)range;
-- (id)_accessibilityTree;
-
-- (DOMRange *)_rangeByAlteringCurrentSelection:(WebCore::SelectionController::EAlteration)alteration direction:(WebCore::SelectionController::EDirection)direction granularity:(WebCore::TextGranularity)granularity;
+- (DOMRange *)_rangeByAlteringCurrentSelection:(WebCore::SelectionController::EAlteration)alteration direction:(WebCore::SelectionDirection)direction granularity:(WebCore::TextGranularity)granularity;
- (NSRange)_convertToNSRange:(WebCore::Range*)range;
- (DOMRange *)_convertNSRangeToDOMRange:(NSRange)range;
- (NSRange)_convertDOMRangeToNSRange:(DOMRange *)range;
diff --git a/WebKit/mac/WebView/WebFramePrivate.h b/WebKit/mac/WebView/WebFramePrivate.h
index b0cb0f3..ddfa5cc 100644
--- a/WebKit/mac/WebView/WebFramePrivate.h
+++ b/WebKit/mac/WebView/WebFramePrivate.h
@@ -142,4 +142,7 @@ typedef enum {
// Returns whether there is a spelling marker in the specified range of the focused node.
- (BOOL)hasSpellingMarker:(int)location length:(int)length;
+// The top of the accessibility tree.
+- (id)accessibilityRoot;
+
@end
diff --git a/WebKit/mac/WebView/WebFullScreenController.h b/WebKit/mac/WebView/WebFullScreenController.h
new file mode 100644
index 0000000..f867dc2
--- /dev/null
+++ b/WebKit/mac/WebView/WebFullScreenController.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#if ENABLE(FULLSCREEN_API)
+
+#import <wtf/RefPtr.h>
+
+@class WebWindowFadeAnimation;
+@class WebView;
+namespace WebCore {
+ class Element;
+ class RenderBox;
+ class EventListener;
+}
+
+@interface WebFullScreenController : NSWindowController {
+@private
+ RefPtr<WebCore::Element> _element;
+ WebCore::RenderBox* _renderer; // (set)
+ RefPtr<WebCore::Element> _replacementElement;
+ NSWindow *_backgroundFullscreenWindow; // (retain)
+ WebWindowFadeAnimation *_fadeAnimation; // (retain)
+ WebView *_webView;
+ NSView* _placeholderView;
+ CALayer* _rendererLayer;
+ CALayer* _backgroundLayer;
+ RefPtr<WebCore::EventListener> _mediaEventListener;
+
+ BOOL _isAnimating;
+ BOOL _isFullscreen;
+ BOOL _isWindowLoaded;
+ BOOL _forceDisableAnimation;
+ BOOL _isPlaying;
+ uint32_t _idleDisplaySleepAssertion;
+ uint32_t _idleSystemSleepAssertion;
+ NSTimer *_tickleTimer;
+ SystemUIMode _savedUIMode;
+ SystemUIOptions _savedUIOptions;
+ CGRect _initialFrame;
+}
+
+- (WebView*)webView;
+- (void)setWebView:(WebView*)webView;
+
+- (void)setElement:(PassRefPtr<WebCore::Element>)element;
+- (WebCore::Element*)element;
+
+- (void)setRenderer:(WebCore::RenderBox*)renderer;
+- (WebCore::RenderBox*)renderer;
+
+- (void)enterFullscreen:(NSScreen *)screen;
+- (void)exitFullscreen;
+
+@end
+
+#endif // ENABLE(FULLSCREEN_API)
diff --git a/WebKit/mac/WebView/WebFullScreenController.mm b/WebKit/mac/WebView/WebFullScreenController.mm
new file mode 100644
index 0000000..a958e90
--- /dev/null
+++ b/WebKit/mac/WebView/WebFullScreenController.mm
@@ -0,0 +1,923 @@
+/*
+ * Copyright (C) 2009 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
+ */
+
+#if ENABLE(FULLSCREEN_API)
+
+#import "WebFullScreenController.h"
+
+#import "WebPreferencesPrivate.h"
+#import "WebWindowAnimation.h"
+#import "WebViewInternal.h"
+#import <IOKit/pwr_mgt/IOPMLib.h>
+#import <WebCore/AnimationList.h>
+#import <WebCore/CSSPropertyNames.h>
+#import <WebCore/Color.h>
+#import <WebCore/Document.h>
+#import <WebCore/DOMDocument.h>
+#import <WebCore/DOMDocumentInternal.h>
+#import <WebCore/DOMHTMLElement.h>
+#import <WebCore/DOMWindow.h>
+#import <WebCore/EventListener.h>
+#import <WebCore/EventNames.h>
+#import <WebCore/HTMLElement.h>
+#import <WebCore/HTMLNames.h>
+#import <WebCore/HTMLMediaElement.h>
+#import <WebCore/IntRect.h>
+#import <WebCore/NodeList.h>
+#import <WebCore/SoftLinking.h>
+#import <WebCore/RenderBlock.h>
+#import <WebCore/RenderLayer.h>
+#import <WebCore/RenderLayerBacking.h>
+#import <objc/objc-runtime.h>
+#import <wtf/UnusedParam.h>
+
+static const NSTimeInterval tickleTimerInterval = 1.0;
+static NSString* const isEnteringFullscreenKey = @"isEnteringFullscreen";
+
+using namespace WebCore;
+
+#if defined(BUILDING_ON_LEOPARD)
+@interface CATransaction(SnowLeopardConvenienceFunctions)
++ (void)setDisableActions:(BOOL)flag;
++ (void)setAnimationDuration:(CFTimeInterval)dur;
+@end
+
+@implementation CATransaction(SnowLeopardConvenienceFunctions)
++ (void)setDisableActions:(BOOL)flag
+{
+ [self setValue:[NSNumber numberWithBool:flag] forKey:kCATransactionDisableActions];
+}
+
++ (void)setAnimationDuration:(CFTimeInterval)dur
+{
+ [self setValue:[NSNumber numberWithDouble:dur] forKey:kCATransactionAnimationDuration];
+}
+@end
+
+#endif
+
+@interface WebFullscreenWindow : NSWindow
+#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER)
+<NSAnimationDelegate>
+#endif
+{
+ NSView* _animationView;
+
+ CALayer* _rendererLayer;
+ CALayer* _backgroundLayer;
+}
+- (CALayer*)rendererLayer;
+- (void)setRendererLayer:(CALayer*)rendererLayer;
+- (CALayer*)backgroundLayer;
+- (NSView*)animationView;
+@end
+
+class MediaEventListener : public EventListener {
+public:
+ static PassRefPtr<MediaEventListener> create(WebFullScreenController* delegate);
+ virtual bool operator==(const EventListener&);
+ virtual void handleEvent(ScriptExecutionContext*, Event*);
+
+private:
+ MediaEventListener(WebFullScreenController* delegate);
+ WebFullScreenController* delegate;
+};
+
+@interface WebFullScreenController(Private)
+- (void)_requestExitFullscreenWithAnimation:(BOOL)animation;
+- (void)_updateMenuAndDockForFullscreen;
+- (void)_updatePowerAssertions;
+- (WebFullscreenWindow *)_fullscreenWindow;
+- (Document*)_document;
+- (CFTimeInterval)_animationDuration;
+- (BOOL)_isAnyMoviePlaying;
+@end
+
+@interface NSWindow(IsOnActiveSpaceAdditionForTigerAndLeopard)
+- (BOOL)isOnActiveSpace;
+@end
+
+@implementation WebFullScreenController
+
+#pragma mark -
+#pragma mark Initialization
+- (id)init
+{
+ // Do not defer window creation, to make sure -windowNumber is created (needed by WebWindowScaleAnimation).
+ NSWindow *window = [[WebFullscreenWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+ self = [super initWithWindow:window];
+ [window release];
+ if (!self)
+ return nil;
+ [self windowDidLoad];
+ _mediaEventListener = MediaEventListener::create(self);
+ return self;
+
+}
+
+- (void)dealloc
+{
+ ASSERT(!_tickleTimer);
+
+ [self setWebView:nil];
+ [_placeholderView release];
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [super dealloc];
+}
+
+- (void)windowDidLoad
+{
+#ifdef BUILDING_ON_TIGER
+ // WebFullScreenController is not supported on Tiger:
+ ASSERT_NOT_REACHED();
+#else
+
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidResignActive:) name:NSApplicationDidResignActiveNotification object:NSApp];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeScreenParameters:) name:NSApplicationDidChangeScreenParametersNotification object:NSApp];
+#endif
+}
+
+#pragma mark -
+#pragma mark Accessors
+
+- (WebView*)webView
+{
+ return _webView;
+}
+
+- (void)setWebView:(WebView *)webView
+{
+ [webView retain];
+ [_webView release];
+ _webView = webView;
+}
+
+- (Element*)element
+{
+ return _element.get();
+}
+
+- (void)setElement:(PassRefPtr<Element>)element
+{
+#ifdef BUILDING_ON_TIGER
+ // WebFullScreenController is not supported on Tiger:
+ ASSERT_NOT_REACHED();
+#else
+ // When a new Element is set as the current full screen element, register event
+ // listeners on that Element's window, listening for changes in media play states.
+ // We will use these events to determine whether to disable the screensaver and
+ // display sleep timers when playing video in full screen. Make sure to unregister
+ // the events on the old element's window, if necessary, as well.
+
+ EventNames& eventNames = WebCore::eventNames();
+
+ if (_element) {
+ DOMWindow* window = _element->document()->domWindow();
+ if (window) {
+ window->removeEventListener(eventNames.playEvent, _mediaEventListener.get(), true);
+ window->removeEventListener(eventNames.pauseEvent, _mediaEventListener.get(), true);
+ window->removeEventListener(eventNames.endedEvent, _mediaEventListener.get(), true);
+ }
+ }
+
+ _element = element;
+
+ if (_element) {
+ DOMWindow* window = _element->document()->domWindow();
+ if (window) {
+ window->addEventListener(eventNames.playEvent, _mediaEventListener, true);
+ window->addEventListener(eventNames.pauseEvent, _mediaEventListener, true);
+ window->addEventListener(eventNames.endedEvent, _mediaEventListener, true);
+ }
+ }
+#endif
+}
+
+- (RenderBox*)renderer
+{
+ return _renderer;
+}
+
+- (void)setRenderer:(RenderBox*)renderer
+{
+#ifdef BUILDING_ON_TIGER
+ // WebFullScreenController is not supported on Tiger:
+ ASSERT_NOT_REACHED();
+#else
+ _renderer = renderer;
+#endif
+}
+
+#pragma mark -
+#pragma mark Notifications
+
+- (void)windowDidExitFullscreen:(BOOL)finished
+{
+ if (!_isAnimating)
+ return;
+
+ if (_isFullscreen)
+ return;
+
+ NSDisableScreenUpdates();
+ ASSERT(_element);
+ [self _document]->setFullScreenRendererBackgroundColor(Color::black);
+ [self _document]->webkitDidExitFullScreenForElement(_element.get());
+ [self setElement:nil];
+
+ if (finished) {
+ [self _updateMenuAndDockForFullscreen];
+ [self _updatePowerAssertions];
+
+ [[_webView window] display];
+ [[self _fullscreenWindow] setRendererLayer:nil];
+ [[self window] close];
+ }
+
+ NSEnableScreenUpdates();
+
+ _isAnimating = NO;
+ [self autorelease]; // Associated -retain is in -exitFullscreen.
+}
+
+- (void)windowDidEnterFullscreen:(BOOL)finished
+{
+ if (!_isAnimating)
+ return;
+
+ if (!_isFullscreen)
+ return;
+
+ NSDisableScreenUpdates();
+ [self _document]->webkitDidEnterFullScreenForElement(_element.get());
+ [self _document]->setFullScreenRendererBackgroundColor(Color::black);
+
+ if (finished) {
+ [self _updateMenuAndDockForFullscreen];
+ [self _updatePowerAssertions];
+ [NSCursor setHiddenUntilMouseMoves:YES];
+
+ // Move the webView into our fullscreen Window
+ if (!_placeholderView)
+ _placeholderView = [[NSView alloc] init];
+
+ // Do not swap the placeholder into place if already is in a window,
+ // assuming the placeholder's window will always be the webView's
+ // original window.
+ if (![_placeholderView window]) {
+ WebView* webView = [self webView];
+ [_placeholderView setFrame:[webView frame]];
+ [_placeholderView setAutoresizingMask:[webView autoresizingMask]];
+ [_placeholderView removeFromSuperview];
+ [[webView superview] replaceSubview:webView with:_placeholderView];
+
+ [[[self window] contentView] addSubview:webView];
+ [webView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
+ [webView setFrame:[[[self window] contentView] bounds]];
+ }
+
+ WebFullscreenWindow* window = [self _fullscreenWindow];
+ [window setBackgroundColor:[NSColor blackColor]];
+ [window setOpaque:YES];
+
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+ [[[window animationView] layer] setOpacity:0];
+ [CATransaction commit];
+ }
+ NSEnableScreenUpdates();
+
+ _isAnimating = NO;
+}
+
+- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)finished
+{
+ BOOL isEnteringFullscreenAnimation = [[anim valueForKey:isEnteringFullscreenKey] boolValue];
+
+ if (!isEnteringFullscreenAnimation)
+ [self windowDidExitFullscreen:finished];
+ else
+ [self windowDidEnterFullscreen:finished];
+}
+
+- (void)applicationDidResignActive:(NSNotification*)notification
+{
+ // Check to see if the fullscreenWindow is on the active space; this function is available
+ // on 10.6 and later, so default to YES if the function is not available:
+ NSWindow* fullscreenWindow = [self _fullscreenWindow];
+ BOOL isOnActiveSpace = ([fullscreenWindow respondsToSelector:@selector(isOnActiveSpace)] ? [fullscreenWindow isOnActiveSpace] : YES);
+
+ // Replicate the QuickTime Player (X) behavior when losing active application status:
+ // Is the fullscreen screen the main screen? (Note: this covers the case where only a
+ // single screen is available.) Is the fullscreen screen on the current space? IFF so,
+ // then exit fullscreen mode.
+ if ([fullscreenWindow screen] == [[NSScreen screens] objectAtIndex:0] && isOnActiveSpace)
+ [self _requestExitFullscreenWithAnimation:NO];
+}
+
+- (void)applicationDidChangeScreenParameters:(NSNotification*)notification
+{
+ // The user may have changed the main screen by moving the menu bar, or they may have changed
+ // the Dock's size or location, or they may have changed the fullscreen screen's dimensions.
+ // Update our presentation parameters, and ensure that the full screen window occupies the
+ // entire screen:
+ [self _updateMenuAndDockForFullscreen];
+ NSWindow* window = [self window];
+ [window setFrame:[[window screen] frame] display:YES];
+}
+
+#pragma mark -
+#pragma mark Exposed Interface
+
+- (void)enterFullscreen:(NSScreen *)screen
+{
+ // Disable animation if we are already in full-screen mode.
+ BOOL shouldAnimate = !_isFullscreen;
+
+ if (_isAnimating) {
+ // The CAAnimation delegate functions will only be called the
+ // next trip through the run-loop, so manually call the delegate
+ // function here, letting it know the animation did not complete:
+ [self windowDidExitFullscreen:NO];
+ ASSERT(!_isAnimating);
+ }
+ _isFullscreen = YES;
+ _isAnimating = YES;
+
+ // setElement: must be called with a non-nil value before calling enterFullscreen:.
+ ASSERT(_element);
+
+ NSDisableScreenUpdates();
+
+ if (!screen)
+ screen = [NSScreen mainScreen];
+ NSRect screenFrame = [screen frame];
+
+ WebView* webView = [self webView];
+ NSRect webViewFrame = [webView convertRectToBase:[webView frame]];
+ webViewFrame.origin = [[webView window] convertBaseToScreen:webViewFrame.origin];
+
+ NSRect elementFrame = _element->screenRect();
+
+ // In the case of a multi-monitor setup where the webView straddles two
+ // monitors, we must create a window large enough to contain the destination
+ // frame and the initial frame.
+ NSRect windowFrame = NSUnionRect(screenFrame, elementFrame);
+ [[self window] setFrame:windowFrame display:YES];
+
+ // In a previous incarnation, the NSWindow attached to this controller may have
+ // been on a different screen. Temporarily change the collectionBehavior of the window:
+ NSWindowCollectionBehavior behavior = [[self window] collectionBehavior];
+ [[self window] setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
+ [[self window] makeKeyAndOrderFront:self];
+ [[self window] setCollectionBehavior:behavior];
+
+ NSView* animationView = [[self _fullscreenWindow] animationView];
+ NSRect viewBounds = [animationView bounds];
+
+ NSRect backgroundBounds = {[[self window] convertScreenToBase:screenFrame.origin], screenFrame.size};
+ backgroundBounds = [animationView convertRectFromBase:backgroundBounds];
+ // Flip the background layer's coordinate system.
+ backgroundBounds.origin.y = windowFrame.size.height - NSMaxY(backgroundBounds);
+
+ // Set our fullscreen element's initial frame, and flip the coordinate systems from
+ // screen coordinates (bottom/left) to layer coordinates (top/left):
+ _initialFrame = NSRectToCGRect(NSIntersectionRect(elementFrame, webViewFrame));
+ _initialFrame.origin.y = screenFrame.size.height - CGRectGetMaxY(_initialFrame);
+
+ // Inform the document that we will begin entering full screen. This will change
+ // pseudo-classes on the fullscreen element and the document element.
+ Document* document = [self _document];
+ document->webkitWillEnterFullScreenForElement(_element.get());
+
+ // Check to see if the fullscreen renderer is composited. If not, accelerated graphics
+ // may be disabled. In this case, do not attempt to animate the contents into place;
+ // merely snap to the final position:
+ if (!shouldAnimate || !_renderer || !_renderer->layer()->isComposited()) {
+ [self windowDidEnterFullscreen:YES];
+ NSEnableScreenUpdates();
+ return;
+ }
+
+ // Set up the final style of the FullScreen render block. Set an absolute
+ // width and height equal to the size of the screen, and anchor the layer
+ // at the top, left at (0,0). The RenderFullScreen style is already set
+ // to position:fixed.
+ [self _document]->setFullScreenRendererSize(IntSize(screenFrame.size));
+ [self _document]->setFullScreenRendererBackgroundColor(Color::transparent);
+
+ // Cause the document to layout, thus calculating a new fullscreen element size:
+ [self _document]->updateLayout();
+
+ // FIXME: try to use the fullscreen element's calculated x, y, width, and height instead of the
+ // renderBox functions:
+ RenderBox* childRenderer = _renderer->firstChildBox();
+ CGRect destinationFrame = CGRectMake(childRenderer->x(), childRenderer->y(), childRenderer->width(), childRenderer->height());
+
+ // Some properties haven't propogated from the GraphicsLayer to the CALayer yet. So
+ // tell the renderer's layer to sync it's compositing state:
+ GraphicsLayer* rendererGraphics = _renderer->layer()->backing()->graphicsLayer();
+ rendererGraphics->syncCompositingState();
+
+ CALayer* rendererLayer = rendererGraphics->platformLayer();
+ [[self _fullscreenWindow] setRendererLayer:rendererLayer];
+
+ CFTimeInterval duration = [self _animationDuration];
+
+ // Create a transformation matrix that will transform the renderer layer such that
+ // the fullscreen element appears to move from its starting position and size to its
+ // final one. Perform the transformation in two steps, using the CALayer's matrix
+ // math to calculate the effects of each step:
+ // 1. Apply a scale tranform to shrink the apparent size of the layer to the original
+ // element screen size.
+ // 2. Apply a translation transform to move the shrunk layer into the same screen position
+ // as the original element.
+ CATransform3D shrinkTransform = CATransform3DMakeScale(_initialFrame.size.width / destinationFrame.size.width, _initialFrame.size.height / destinationFrame.size.height, 1);
+ [rendererLayer setTransform:shrinkTransform];
+ CGRect shrunkDestinationFrame = [rendererLayer convertRect:destinationFrame toLayer:[animationView layer]];
+ CATransform3D moveTransform = CATransform3DMakeTranslation(_initialFrame.origin.x - shrunkDestinationFrame.origin.x, _initialFrame.origin.y - shrunkDestinationFrame.origin.y, 0);
+ CATransform3D finalTransform = CATransform3DConcat(shrinkTransform, moveTransform);
+ [rendererLayer setTransform:finalTransform];
+ CGRect translatedDestinationFrame = [rendererLayer convertRect:destinationFrame toLayer:[animationView layer]];
+
+ CALayer* backgroundLayer = [[self _fullscreenWindow] backgroundLayer];
+
+ // Start the opacity animation. We can use implicit animations here because we don't care when
+ // the animation finishes.
+ [CATransaction begin];
+ [CATransaction setAnimationDuration:duration];
+ [backgroundLayer setOpacity:1];
+ [CATransaction commit];
+
+ // Use a CABasicAnimation here for the zoom effect. We want to be notified that the animation has
+ // completed by way of the CAAnimation delegate.
+ CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
+ [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:finalTransform]];
+ [zoomAnimation setToValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]];
+ [zoomAnimation setDelegate:self];
+ [zoomAnimation setDuration:duration];
+ [zoomAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
+ [zoomAnimation setFillMode:kCAFillModeForwards];
+ [zoomAnimation setValue:(id)kCFBooleanTrue forKey:isEnteringFullscreenKey];
+
+ // Disable implicit animations and set the layer's transformation matrix to its final state.
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+ [rendererLayer setTransform:CATransform3DIdentity];
+ [rendererLayer addAnimation:zoomAnimation forKey:@"zoom"];
+ [backgroundLayer setFrame:NSRectToCGRect(backgroundBounds)];
+ [CATransaction commit];
+
+ NSEnableScreenUpdates();
+}
+
+- (void)exitFullscreen
+{
+ if (!_isFullscreen)
+ return;
+
+ CATransform3D startTransform = CATransform3DIdentity;
+ if (_isAnimating) {
+ if (_renderer && _renderer->layer()->isComposited()) {
+ CALayer* rendererLayer = _renderer->layer()->backing()->graphicsLayer()->platformLayer();
+ startTransform = [[rendererLayer presentationLayer] transform];
+ }
+
+ // The CAAnimation delegate functions will only be called the
+ // next trip through the run-loop, so manually call the delegate
+ // function here, letting it know the animation did not complete:
+ [self windowDidEnterFullscreen:NO];
+ ASSERT(!_isAnimating);
+ }
+ _isFullscreen = NO;
+ _isAnimating = YES;
+
+ NSDisableScreenUpdates();
+
+ // The user may have moved the fullscreen window in Spaces, so temporarily change
+ // the collectionBehavior of the webView's window:
+ NSWindow* webWindow = [[self webView] window];
+ NSWindowCollectionBehavior behavior = [webWindow collectionBehavior];
+ [webWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
+ [webWindow orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]];
+ [webWindow setCollectionBehavior:behavior];
+
+ // The fullscreen animation may have been cancelled before the
+ // webView was moved to the fullscreen window. Check to see
+ // if the _placeholderView exists and is in a window before
+ // attempting to swap the webView back to it's original tree:
+ if (_placeholderView && [_placeholderView window]) {
+ // Move the webView back to its own native window:
+ WebView* webView = [self webView];
+ [webView setFrame:[_placeholderView frame]];
+ [webView setAutoresizingMask:[_placeholderView autoresizingMask]];
+ [webView removeFromSuperview];
+ [[_placeholderView superview] replaceSubview:_placeholderView with:webView];
+
+ // Because the animation view is layer-hosted, make sure to
+ // disable animations when changing the layer's opacity. Other-
+ // wise, the content will appear to fade into view.
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+ WebFullscreenWindow* window = [self _fullscreenWindow];
+ [[[window animationView] layer] setOpacity:1];
+ [window setBackgroundColor:[NSColor clearColor]];
+ [window setOpaque:NO];
+ [CATransaction commit];
+ }
+
+ NSView* animationView = [[self _fullscreenWindow] animationView];
+ CGRect layerEndFrame = NSRectToCGRect([animationView convertRect:NSRectFromCGRect(_initialFrame) fromView:nil]);
+
+ // The _renderer might be NULL due to its ancestor being removed:
+ CGRect layerStartFrame = CGRectZero;
+ if (_renderer) {
+ RenderBox* childRenderer = _renderer->firstChildBox();
+ layerStartFrame = CGRectMake(childRenderer->x(), childRenderer->y(), childRenderer->width(), childRenderer->height());
+ }
+
+ [self _document]->webkitWillExitFullScreenForElement(_element.get());
+ [self _document]->updateLayout();
+
+ // We have to retain ourselves because we want to be alive for the end of the animation.
+ // If our owner releases us we could crash if this is not the case.
+ // Balanced in windowDidExitFullscreen
+ [self retain];
+
+ // Check to see if the fullscreen renderer is composited. If not, accelerated graphics
+ // may be disabled. In this case, do not attempt to animate the contents into place;
+ // merely snap to the final position:
+ if (!_renderer || !_renderer->layer()->isComposited()) {
+ [self windowDidExitFullscreen:YES];
+ NSEnableScreenUpdates();
+ return;
+ }
+
+ GraphicsLayer* rendererGraphics = _renderer->layer()->backing()->graphicsLayer();
+
+ [self _document]->setFullScreenRendererBackgroundColor(Color::transparent);
+
+ rendererGraphics->syncCompositingState();
+
+ CALayer* rendererLayer = rendererGraphics->platformLayer();
+ [[self _fullscreenWindow] setRendererLayer:rendererLayer];
+
+ // Create a transformation matrix that will transform the renderer layer such that
+ // the fullscreen element appears to move from the full screen to its original position
+ // and size. Perform the transformation in two steps, using the CALayer's matrix
+ // math to calculate the effects of each step:
+ // 1. Apply a scale tranform to shrink the apparent size of the layer to the original
+ // element screen size.
+ // 2. Apply a translation transform to move the shrunk layer into the same screen position
+ // as the original element.
+ CATransform3D shrinkTransform = CATransform3DMakeScale(layerEndFrame.size.width / layerStartFrame.size.width, layerEndFrame.size.height / layerStartFrame.size.height, 1);
+ [rendererLayer setTransform:shrinkTransform];
+ CGRect shrunkDestinationFrame = [rendererLayer convertRect:layerStartFrame toLayer:[animationView layer]];
+ CATransform3D moveTransform = CATransform3DMakeTranslation(layerEndFrame.origin.x - shrunkDestinationFrame.origin.x, layerEndFrame.origin.y - shrunkDestinationFrame.origin.y, 0);
+ CATransform3D finalTransform = CATransform3DConcat(shrinkTransform, moveTransform);
+ [rendererLayer setTransform:finalTransform];
+ CGRect translatedDestinationFrame = [rendererLayer convertRect:layerStartFrame toLayer:[animationView layer]];
+
+ CFTimeInterval duration = [self _animationDuration];
+
+ CALayer* backgroundLayer = [[self _fullscreenWindow] backgroundLayer];
+ [CATransaction begin];
+ [CATransaction setAnimationDuration:duration];
+ [backgroundLayer setOpacity:0];
+ [CATransaction commit];
+
+ CABasicAnimation* zoomAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
+ [zoomAnimation setFromValue:[NSValue valueWithCATransform3D:startTransform]];
+ [zoomAnimation setToValue:[NSValue valueWithCATransform3D:finalTransform]];
+ [zoomAnimation setDelegate:self];
+ [zoomAnimation setDuration:duration];
+ [zoomAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
+ [zoomAnimation setFillMode:kCAFillModeBoth];
+ [zoomAnimation setRemovedOnCompletion:NO];
+ [zoomAnimation setValue:(id)kCFBooleanFalse forKey:isEnteringFullscreenKey];
+
+ [rendererLayer addAnimation:zoomAnimation forKey:@"zoom"];
+
+ NSEnableScreenUpdates();
+}
+
+#pragma mark -
+#pragma mark Internal Interface
+
+- (void)_updateMenuAndDockForFullscreen
+{
+ // NSApplicationPresentationOptions is available on > 10.6 only:
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ NSApplicationPresentationOptions options = NSApplicationPresentationDefault;
+ NSScreen* fullscreenScreen = [[self window] screen];
+
+ if (_isFullscreen) {
+ // Auto-hide the menu bar if the fullscreenScreen contains the menu bar:
+ // NOTE: if the fullscreenScreen contains the menu bar but not the dock, we must still
+ // auto-hide the dock, or an exception will be thrown.
+ if ([[NSScreen screens] objectAtIndex:0] == fullscreenScreen)
+ options |= (NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock);
+ // Check if the current screen contains the dock by comparing the screen's frame to its
+ // visibleFrame; if a dock is present, the visibleFrame will differ. If the current screen
+ // contains the dock, hide it.
+ else if (!NSEqualRects([fullscreenScreen frame], [fullscreenScreen visibleFrame]))
+ options |= NSApplicationPresentationAutoHideDock;
+ }
+
+ if ([NSApp respondsToSelector:@selector(setPresentationOptions:)])
+ [NSApp setPresentationOptions:options];
+ else
+#endif
+ SetSystemUIMode(_isFullscreen ? kUIModeNormal : kUIModeAllHidden, 0);
+}
+
+#if !defined(BUILDING_ON_TIGER) // IOPMAssertionCreateWithName not defined on < 10.5
+- (void)_disableIdleDisplaySleep
+{
+ if (_idleDisplaySleepAssertion == kIOPMNullAssertionID)
+#if defined(BUILDING_ON_LEOPARD) // IOPMAssertionCreateWithName is not defined in the 10.5 SDK
+ IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &_idleDisplaySleepAssertion);
+#else // IOPMAssertionCreate is depreciated in > 10.5
+ IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, CFSTR("WebKit playing a video fullscreen."), &_idleDisplaySleepAssertion);
+#endif
+}
+
+- (void)_enableIdleDisplaySleep
+{
+ if (_idleDisplaySleepAssertion != kIOPMNullAssertionID) {
+ IOPMAssertionRelease(_idleDisplaySleepAssertion);
+ _idleDisplaySleepAssertion = kIOPMNullAssertionID;
+ }
+}
+
+- (void)_disableIdleSystemSleep
+{
+ if (_idleSystemSleepAssertion == kIOPMNullAssertionID)
+#if defined(BUILDING_ON_LEOPARD) // IOPMAssertionCreateWithName is not defined in the 10.5 SDK
+ IOPMAssertionCreate(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &_idleSystemSleepAssertion);
+#else // IOPMAssertionCreate is depreciated in > 10.5
+ IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR("WebKit playing a video fullscreen."), &_idleSystemSleepAssertion);
+#endif
+}
+
+- (void)_enableIdleSystemSleep
+{
+ if (_idleSystemSleepAssertion != kIOPMNullAssertionID) {
+ IOPMAssertionRelease(_idleSystemSleepAssertion);
+ _idleSystemSleepAssertion = kIOPMNullAssertionID;
+ }
+}
+
+- (void)_enableTickleTimer
+{
+ [_tickleTimer invalidate];
+ [_tickleTimer release];
+ _tickleTimer = [[NSTimer scheduledTimerWithTimeInterval:tickleTimerInterval target:self selector:@selector(_tickleTimerFired) userInfo:nil repeats:YES] retain];
+}
+
+- (void)_disableTickleTimer
+{
+ [_tickleTimer invalidate];
+ [_tickleTimer release];
+ _tickleTimer = nil;
+}
+
+- (void)_tickleTimerFired
+{
+ UpdateSystemActivity(OverallAct);
+}
+#endif
+
+- (void)_updatePowerAssertions
+{
+#if !defined(BUILDING_ON_TIGER)
+ BOOL isPlaying = [self _isAnyMoviePlaying];
+
+ if (isPlaying && _isFullscreen) {
+ [self _disableIdleSystemSleep];
+ [self _disableIdleDisplaySleep];
+ [self _enableTickleTimer];
+ } else {
+ [self _enableIdleSystemSleep];
+ [self _enableIdleDisplaySleep];
+ [self _disableTickleTimer];
+ }
+#endif
+}
+
+- (void)_requestExit
+{
+ [self exitFullscreen];
+ _forceDisableAnimation = NO;
+}
+
+- (void)_requestExitFullscreenWithAnimation:(BOOL)animation
+{
+ _forceDisableAnimation = !animation;
+ [self performSelector:@selector(_requestExit) withObject:nil afterDelay:0];
+
+}
+
+- (BOOL)_isAnyMoviePlaying
+{
+ if (!_element)
+ return NO;
+
+ Node* nextNode = _element.get();
+ while (nextNode)
+ {
+ if (nextNode->hasTagName(HTMLNames::videoTag)) {
+ HTMLMediaElement* element = static_cast<HTMLMediaElement*>(nextNode);
+ if (!element->paused() && !element->ended())
+ return YES;
+ }
+
+ nextNode = nextNode->traverseNextNode(_element.get());
+ }
+
+ return NO;
+}
+
+#pragma mark -
+#pragma mark Utility Functions
+
+- (WebFullscreenWindow *)_fullscreenWindow
+{
+ return (WebFullscreenWindow *)[self window];
+}
+
+- (Document*)_document
+{
+ return core([[[self webView] mainFrame] DOMDocument]);
+}
+
+- (CFTimeInterval)_animationDuration
+{
+ static const CFTimeInterval defaultDuration = 0.5;
+ CFTimeInterval duration = defaultDuration;
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ NSUInteger modifierFlags = [NSEvent modifierFlags];
+#else
+ NSUInteger modifierFlags = [[NSApp currentEvent] modifierFlags];
+#endif
+ if ((modifierFlags & NSControlKeyMask) == NSControlKeyMask)
+ duration *= 2;
+ if ((modifierFlags & NSShiftKeyMask) == NSShiftKeyMask)
+ duration *= 10;
+ if (_forceDisableAnimation) {
+ // This will disable scale animation
+ duration = 0;
+ }
+ return duration;
+}
+
+@end
+
+#pragma mark -
+@implementation WebFullscreenWindow
+
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag
+{
+ UNUSED_PARAM(aStyle);
+ self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:flag];
+ if (!self)
+ return nil;
+ [self setOpaque:NO];
+ [self setBackgroundColor:[NSColor clearColor]];
+ [self setIgnoresMouseEvents:NO];
+ [self setAcceptsMouseMovedEvents:YES];
+ [self setReleasedWhenClosed:NO];
+ [self setHasShadow:YES];
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ [self setMovable:NO];
+#else
+ [self setMovableByWindowBackground:NO];
+#endif
+
+ NSView* contentView = [self contentView];
+ _animationView = [[NSView alloc] initWithFrame:[contentView bounds]];
+
+ CALayer* contentLayer = [[CALayer alloc] init];
+ [_animationView setLayer:contentLayer];
+ [_animationView setWantsLayer:YES];
+ [_animationView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
+ [contentView addSubview:_animationView];
+
+ _backgroundLayer = [[CALayer alloc] init];
+ [contentLayer addSublayer:_backgroundLayer];
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ [contentLayer setGeometryFlipped:YES];
+#else
+ [contentLayer setSublayerTransform:CATransform3DMakeScale(1, -1, 1)];
+#endif
+ [contentLayer setOpacity:0];
+
+ [_backgroundLayer setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];
+ [_backgroundLayer setOpacity:0];
+ return self;
+}
+
+- (void)dealloc
+{
+ [_animationView release];
+ [_backgroundLayer release];
+ [_rendererLayer release];
+ [super dealloc];
+}
+
+- (BOOL)canBecomeKeyWindow
+{
+ return YES;
+}
+
+- (void)keyDown:(NSEvent *)theEvent
+{
+ if ([[theEvent charactersIgnoringModifiers] isEqual:@"\e"]) // Esacpe key-code
+ [self cancelOperation:self];
+ else [super keyDown:theEvent];
+}
+
+- (void)cancelOperation:(id)sender
+{
+ UNUSED_PARAM(sender);
+ [[self windowController] _requestExitFullscreenWithAnimation:YES];
+}
+
+- (CALayer*)rendererLayer
+{
+ return _rendererLayer;
+}
+
+- (void)setRendererLayer:(CALayer *)rendererLayer
+{
+ [CATransaction begin];
+ [CATransaction setDisableActions:YES];
+ [rendererLayer retain];
+ [_rendererLayer removeFromSuperlayer];
+ [_rendererLayer release];
+ _rendererLayer = rendererLayer;
+
+ if (_rendererLayer)
+ [[[self animationView] layer] addSublayer:_rendererLayer];
+ [CATransaction commit];
+}
+
+- (CALayer*)backgroundLayer
+{
+ return _backgroundLayer;
+}
+
+- (NSView*)animationView
+{
+ return _animationView;
+}
+@end
+
+#pragma mark -
+#pragma mark MediaEventListener
+
+MediaEventListener::MediaEventListener(WebFullScreenController* delegate)
+ : EventListener(CPPEventListenerType)
+ , delegate(delegate)
+{
+}
+
+PassRefPtr<MediaEventListener> MediaEventListener::create(WebFullScreenController* delegate)
+{
+ return adoptRef(new MediaEventListener(delegate));
+}
+
+bool MediaEventListener::operator==(const EventListener& listener)
+{
+ return this == &listener;
+}
+
+void MediaEventListener::handleEvent(ScriptExecutionContext* context, Event* event)
+{
+ [delegate _updatePowerAssertions];
+}
+
+#endif /* ENABLE(FULLSCREEN_API) */
diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm
index 3e8be9a..093f3db 100644
--- a/WebKit/mac/WebView/WebHTMLView.mm
+++ b/WebKit/mac/WebView/WebHTMLView.mm
@@ -83,6 +83,7 @@
#import <WebCore/ContextMenuController.h>
#import <WebCore/Document.h>
#import <WebCore/DocumentFragment.h>
+#import <WebCore/DocumentMarkerController.h>
#import <WebCore/DragController.h>
#import <WebCore/Editor.h>
#import <WebCore/EditorDeleteAction.h>
@@ -4273,7 +4274,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
- (id)accessibilityAttributeValue:(NSString*)attributeName
{
if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute]) {
- id accTree = [[self _frame] _accessibilityTree];
+ id accTree = [[self _frame] accessibilityRoot];
if (accTree)
return [NSArray arrayWithObject:accTree];
return nil;
@@ -4283,7 +4284,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
- (id)accessibilityFocusedUIElement
{
- id accTree = [[self _frame] _accessibilityTree];
+ id accTree = [[self _frame] accessibilityRoot];
if (accTree)
return [accTree accessibilityFocusedUIElement];
return self;
@@ -4291,7 +4292,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
- (id)accessibilityHitTest:(NSPoint)point
{
- id accTree = [[self _frame] _accessibilityTree];
+ id accTree = [[self _frame] accessibilityRoot];
if (accTree) {
NSPoint windowCoord = [[self window] convertScreenToBase:point];
return [accTree accessibilityHitTest:[self convertPoint:windowCoord fromView:nil]];
@@ -4301,7 +4302,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
- (id)_accessibilityParentForSubview:(NSView *)subview
{
- id accTree = [[self _frame] _accessibilityTree];
+ id accTree = [[self _frame] accessibilityRoot];
if (!accTree)
return self;
id parent = [accTree _accessibilityParentForSubview:subview];
@@ -6281,7 +6282,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection
{
- return [self findString:string options:(forward ? 0 : WebFindOptionsBackwards) | (caseFlag ? 0 : WebFindOptionsCaseInsensitive) | (startInSelection ? WebFindOptionsStartInSelection : 0)];
+ return [self _findString:string options:(forward ? 0 : WebFindOptionsBackwards) | (caseFlag ? 0 : WebFindOptionsCaseInsensitive) | (startInSelection ? WebFindOptionsStartInSelection : 0)];
}
@end
@@ -6352,7 +6353,7 @@ static void extractUnderlines(NSAttributedString *string, Vector<CompositionUnde
return result;
}
-- (BOOL)findString:(NSString *)string options:(WebFindOptions)options
+- (BOOL)_findString:(NSString *)string options:(WebFindOptions)options
{
if (![string length])
return NO;
diff --git a/WebKit/mac/WebView/WebPDFView.mm b/WebKit/mac/WebView/WebPDFView.mm
index 0f54980..445b537 100644
--- a/WebKit/mac/WebView/WebPDFView.mm
+++ b/WebKit/mac/WebView/WebPDFView.mm
@@ -106,7 +106,7 @@ extern "C" NSString *_NSPathForSystemFramework(NSString *framework);
- (id)initWithView:(WebPDFView *)view;
@end
-#pragma mark C UTILITY FUNCTIONS
+// MARK: C UTILITY FUNCTIONS
static void _applicationInfoForMIMEType(NSString *type, NSString **name, NSImage **image)
{
@@ -151,7 +151,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
@implementation WebPDFView
-#pragma mark WebPDFView API
+// MARK: WebPDFView API
+ (NSBundle *)PDFKitBundle
{
@@ -190,7 +190,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
return [PDFSubview document];
}
-#pragma mark NSObject OVERRIDES
+// MARK: NSObject OVERRIDES
- (void)dealloc
{
@@ -204,7 +204,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
[super dealloc];
}
-#pragma mark NSResponder OVERRIDES
+// MARK: NSResponder OVERRIDES
- (void)centerSelectionInVisibleArea:(id)sender
{
@@ -257,7 +257,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
[self centerSelectionInVisibleArea:nil];
}
-#pragma mark NSView OVERRIDES
+// MARK: NSView OVERRIDES
- (BOOL)acceptsFirstResponder {
return YES;
@@ -483,7 +483,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
firstResponderIsPDFDocumentView = NO;
}
-#pragma mark NSUserInterfaceValidations PROTOCOL IMPLEMENTATION
+// MARK: NSUserInterfaceValidations PROTOCOL IMPLEMENTATION
- (BOOL)validateUserInterfaceItemWithoutDelegate:(id <NSValidatedUserInterfaceItem>)item
{
@@ -510,7 +510,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
return CallUIDelegateReturningBoolean(result, [self _webView], @selector(webView:validateUserInterfaceItem:defaultValidation:), item, result);
}
-#pragma mark INTERFACE BUILDER ACTIONS FOR SAFARI
+// MARK: INTERFACE BUILDER ACTIONS FOR SAFARI
// Surprisingly enough, this isn't defined in any superclass, though it is defined in assorted AppKit classes since
// it's a standard menu item IBAction.
@@ -526,7 +526,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
[NSPasteboard _web_setFindPasteboardString:[[PDFSubview currentSelection] string] withOwner:self];
}
-#pragma mark WebFrameView UNDECLARED "DELEGATE METHODS"
+// MARK: WebFrameView UNDECLARED "DELEGATE METHODS"
// This is tested in -[WebFrameView canPrintHeadersAndFooters], but isn't declared anywhere (yuck)
- (BOOL)canPrintHeadersAndFooters
@@ -540,7 +540,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
return [[PDFSubview document] getPrintOperationForPrintInfo:printInfo autoRotate:YES];
}
-#pragma mark WebDocumentView PROTOCOL IMPLEMENTATION
+// MARK: WebDocumentView PROTOCOL IMPLEMENTATION
- (void)setDataSource:(WebDataSource *)ds
{
@@ -574,7 +574,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
{
}
-#pragma mark WebDocumentElement PROTOCOL IMPLEMENTATION
+// MARK: WebDocumentElement PROTOCOL IMPLEMENTATION
- (NSDictionary *)elementAtPoint:(NSPoint)point
{
@@ -592,14 +592,14 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
return [self elementAtPoint:point];
}
-#pragma mark WebDocumentSearching PROTOCOL IMPLEMENTATION
+// MARK: WebDocumentSearching PROTOCOL IMPLEMENTATION
- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag
{
return [self searchFor:string direction:forward caseSensitive:caseFlag wrap:wrapFlag startInSelection:NO];
}
-#pragma mark WebDocumentIncrementalSearching PROTOCOL IMPLEMENTATION
+// MARK: WebDocumentIncrementalSearching PROTOCOL IMPLEMENTATION
- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection
{
@@ -612,7 +612,7 @@ static BOOL _PDFSelectionsAreEqual(PDFSelection *selectionA, PDFSelection *selec
return YES;
}
-#pragma mark WebMultipleTextMatches PROTOCOL IMPLEMENTATION
+// MARK: WebMultipleTextMatches PROTOCOL IMPLEMENTATION
- (void)setMarkedTextMatchesAreHighlighted:(BOOL)newValue
{
@@ -696,7 +696,7 @@ static BOOL isFrameInRange(WebFrame *frame, DOMRange *range)
return result;
}
-#pragma mark WebDocumentText PROTOCOL IMPLEMENTATION
+// MARK: WebDocumentText PROTOCOL IMPLEMENTATION
- (BOOL)supportsTextEncoding
{
@@ -750,7 +750,7 @@ static BOOL isFrameInRange(WebFrame *frame, DOMRange *range)
[PDFSubview clearSelection];
}
-#pragma mark WebDocumentViewState PROTOCOL IMPLEMENTATION
+// MARK: WebDocumentViewState PROTOCOL IMPLEMENTATION
// Even though to WebKit we are the "docView", in reality a PDFView contains its own scrollview and docView.
// And it even turns out there is another PDFKit view between the docView and its enclosing ScrollView, so
@@ -809,7 +809,7 @@ static BOOL isFrameInRange(WebFrame *frame, DOMRange *range)
[PDFSubview setScaleFactor:[[state objectAtIndex:i++] floatValue]];
}
-#pragma mark _WebDocumentTextSizing PROTOCOL IMPLEMENTATION
+// MARK: _WebDocumentTextSizing PROTOCOL IMPLEMENTATION
- (IBAction)_zoomOut:(id)sender
{
@@ -841,7 +841,7 @@ static BOOL isFrameInRange(WebFrame *frame, DOMRange *range)
return [PDFSubview scaleFactor] != 1.0;
}
-#pragma mark WebDocumentSelection PROTOCOL IMPLEMENTATION
+// MARK: WebDocumentSelection PROTOCOL IMPLEMENTATION
- (NSRect)selectionRect
{
@@ -934,7 +934,7 @@ static BOOL isFrameInRange(WebFrame *frame, DOMRange *range)
[pasteboard setString:[self selectedString] forType:NSStringPboardType];
}
-#pragma mark PDFView DELEGATE METHODS
+// MARK: PDFView DELEGATE METHODS
- (void)PDFViewWillClickOnLink:(PDFView *)sender withURL:(NSURL *)URL
{
diff --git a/WebKit/mac/WebView/WebScriptDebugger.mm b/WebKit/mac/WebView/WebScriptDebugger.mm
index f67b46f..25ef4b7 100644
--- a/WebKit/mac/WebView/WebScriptDebugger.mm
+++ b/WebKit/mac/WebView/WebScriptDebugger.mm
@@ -220,10 +220,12 @@ void WebScriptDebugger::exception(const DebuggerCallFrame& debuggerCallFrame, in
void WebScriptDebugger::willExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineno)
{
+ callEvent(debuggerCallFrame, sourceID, lineno);
}
void WebScriptDebugger::didExecuteProgram(const DebuggerCallFrame& debuggerCallFrame, intptr_t sourceID, int lineno)
{
+ returnEvent(debuggerCallFrame, sourceID, lineno);
}
void WebScriptDebugger::didReachBreakpoint(const DebuggerCallFrame&, intptr_t, int)
diff --git a/WebKit/mac/WebView/WebScriptWorld.mm b/WebKit/mac/WebView/WebScriptWorld.mm
index 8ca6f44..61daff1 100644
--- a/WebKit/mac/WebView/WebScriptWorld.mm
+++ b/WebKit/mac/WebView/WebScriptWorld.mm
@@ -77,7 +77,7 @@ static WorldMap& allWorlds()
- (void)unregisterWorld
{
- _private->world->unregisterWorld();
+ _private->world->clearWrappers();
}
- (void)dealloc
diff --git a/WebKit/mac/WebView/WebTextCompletionController.mm b/WebKit/mac/WebView/WebTextCompletionController.mm
index 82ad16c..48b5035 100644
--- a/WebKit/mac/WebView/WebTextCompletionController.mm
+++ b/WebKit/mac/WebView/WebTextCompletionController.mm
@@ -173,7 +173,7 @@ using namespace std;
WebFrame *frame = [_htmlView _frame];
DOMRange *selection = kit(core(frame)->selection()->toNormalizedRange().get());
DOMRange *wholeWord = [frame _rangeByAlteringCurrentSelection:SelectionController::AlterationExtend
- direction:SelectionController::DirectionBackward granularity:WordGranularity];
+ direction:DirectionBackward granularity:WordGranularity];
DOMRange *prefix = [wholeWord cloneRange];
[prefix setEnd:[selection startContainer] offset:[selection startOffset]];
diff --git a/WebKit/mac/WebView/WebVideoFullscreenController.mm b/WebKit/mac/WebView/WebVideoFullscreenController.mm
index 2687b14..93e3d8c 100644
--- a/WebKit/mac/WebView/WebVideoFullscreenController.mm
+++ b/WebKit/mac/WebView/WebVideoFullscreenController.mm
@@ -219,8 +219,8 @@ static const NSTimeInterval tickleTimerInterval = 1.0;
}
-#pragma mark -
-#pragma mark Exposed Interface
+// MARK: -
+// MARK: Exposed Interface
static void constrainFrameToRatioOfFrame(NSRect *frameToConstrain, const NSRect *frame)
{
@@ -422,8 +422,8 @@ static NSWindow *createBackgroundFullscreenWindow(NSRect frame, int level)
#endif
}
-#pragma mark -
-#pragma mark Window callback
+// MARK: -
+// MARK: Window callback
- (void)_requestExit
{
@@ -452,8 +452,8 @@ static NSWindow *createBackgroundFullscreenWindow(NSRect frame, int level)
[_hudController fadeWindowIn];
}
-#pragma mark -
-#pragma mark QTMovie callbacks
+// MARK: -
+// MARK: QTMovie callbacks
- (void)rateChanged:(NSNotification *)unusedNotification
{
diff --git a/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm
index 6907311..0a5aca4 100644
--- a/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm
+++ b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm
@@ -623,7 +623,7 @@ static NSString *timeToString(double time)
return timeToString([_delegate mediaElement]->currentTime());
}
-#pragma mark NSResponder
+// MARK: NSResponder
- (void)mouseEntered:(NSEvent *)theEvent
{
@@ -659,7 +659,7 @@ static NSString *timeToString(double time)
[_delegate requestExitFullscreen];
}
-#pragma mark NSWindowDelegate
+// MARK: NSWindowDelegate
- (void)windowDidExpose:(NSNotification *)notification
{
diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm
index bd13ff0..9c7de2c 100644
--- a/WebKit/mac/WebView/WebView.mm
+++ b/WebKit/mac/WebView/WebView.mm
@@ -60,6 +60,7 @@
#import "WebFormDelegatePrivate.h"
#import "WebFrameInternal.h"
#import "WebFrameViewInternal.h"
+#import "WebFullScreenController.h"
#import "WebGeolocationClient.h"
#import "WebGeolocationPositionInternal.h"
#import "WebHTMLRepresentation.h"
@@ -4286,7 +4287,7 @@ static WebFrame *incrementFrame(WebFrame *frame, WebFindOptions options = 0)
static BOOL findString(NSView <WebDocumentSearching> *searchView, NSString *string, WebFindOptions options)
{
if ([searchView conformsToProtocol:@protocol(WebDocumentOptionsSearching)])
- return [(NSView <WebDocumentOptionsSearching> *)searchView findString:string options:options];
+ return [(NSView <WebDocumentOptionsSearching> *)searchView _findString:string options:options];
if ([searchView conformsToProtocol:@protocol(WebDocumentIncrementalSearching)])
return [(NSView <WebDocumentIncrementalSearching> *)searchView searchFor:string direction:!(options & WebFindOptionsBackwards) caseSensitive:!(options & WebFindOptionsCaseInsensitive) wrap:!!(options & WebFindOptionsWrapAround) startInSelection:!!(options & WebFindOptionsStartInSelection)];
return [searchView searchFor:string direction:!(options & WebFindOptionsBackwards) caseSensitive:!(options & WebFindOptionsCaseInsensitive) wrap:!!(options & WebFindOptionsWrapAround)];
@@ -6027,6 +6028,42 @@ static void layerSyncRunLoopObserverCallBack(CFRunLoopObserverRef, CFRunLoopActi
#endif
+#if ENABLE(FULLSCREEN_API)
+- (BOOL)_supportsFullScreenForElement:(const WebCore::Element*)element
+{
+ if (![[WebPreferences standardPreferences] fullScreenEnabled])
+ return NO;
+
+ // FIXME: If the element is in an IFrame, we should ensure it has
+ // an AllowsFullScreen=YES attribute before allowing fullscreen access.
+ return YES;
+}
+
+- (void)_enterFullScreenForElement:(WebCore::Element*)element
+{
+ if (!_private->newFullscreenController)
+ _private->newFullscreenController = [[WebFullScreenController alloc] init];
+
+ [_private->newFullscreenController setElement:element];
+ [_private->newFullscreenController setWebView:self];
+ [_private->newFullscreenController enterFullscreen:[[self window] screen]];
+}
+
+- (void)_exitFullScreenForElement:(WebCore::Element*)element
+{
+ if (!_private->newFullscreenController)
+ return;
+ [_private->newFullscreenController exitFullscreen];
+}
+
+- (void)_fullScreenRendererChanged:(WebCore::RenderBox*)renderer
+{
+ if (!_private->newFullscreenController)
+ _private->newFullscreenController = [[WebFullScreenController alloc] init];
+ [_private->newFullscreenController setRenderer:renderer];
+}
+#endif
+
#if ENABLE(GLIB_SUPPORT)
static void glibContextIterationCallback(CFRunLoopObserverRef, CFRunLoopActivity, void*)
diff --git a/WebKit/mac/WebView/WebViewData.h b/WebKit/mac/WebView/WebViewData.h
index 8b834ca..97d0fc3 100644
--- a/WebKit/mac/WebView/WebViewData.h
+++ b/WebKit/mac/WebView/WebViewData.h
@@ -49,6 +49,9 @@ namespace WebCore {
#if ENABLE(VIDEO)
@class WebVideoFullscreenController;
#endif
+#if ENABLE(FULLSCREEN_API)
+@class WebFullScreenController;
+#endif
extern BOOL applicationIsTerminating;
extern int pluginDatabaseClientCount;
@@ -171,6 +174,10 @@ extern int pluginDatabaseClientCount;
#if ENABLE(VIDEO)
WebVideoFullscreenController *fullscreenController;
#endif
+
+#if ENABLE(FULLSCREEN_API)
+ WebFullScreenController *newFullscreenController;
+#endif
#if ENABLE(GLIB_SUPPORT)
CFRunLoopObserverRef glibRunLoopObserver;
diff --git a/WebKit/mac/WebView/WebViewInternal.h b/WebKit/mac/WebView/WebViewInternal.h
index 0a6f462..555c4d1 100644
--- a/WebKit/mac/WebView/WebViewInternal.h
+++ b/WebKit/mac/WebView/WebViewInternal.h
@@ -39,10 +39,12 @@
#include <wtf/Forward.h>
namespace WebCore {
+ class Element;
class Frame;
class KURL;
class KeyboardEvent;
class Page;
+ class RenderBox;
class Node;
}
#endif
@@ -185,6 +187,13 @@ namespace WebCore {
- (void)_exitFullscreen;
#endif
+#if ENABLE(FULLSCREEN_API) && defined(__cplusplus)
+- (BOOL)_supportsFullScreenForElement:(WebCore::Element*)element;
+- (void)_enterFullScreenForElement:(WebCore::Element*)element;
+- (void)_exitFullScreenForElement:(WebCore::Element*)element;
+- (void)_fullScreenRendererChanged:(WebCore::RenderBox*)renderer;
+#endif
+
- (JSValueRef)_computedStyleIncludingVisitedInfo:(JSContextRef)context forElement:(JSValueRef)value;
@end