summaryrefslogtreecommitdiffstats
path: root/WebKit/mac/WebView
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-10-08 17:19:54 +0100
committerSteve Block <steveblock@google.com>2009-10-20 00:41:58 +0100
commit231d4e3152a9c27a73b6ac7badbe6be673aa3ddf (patch)
treea6c7e2d6cd7bfa7011cc39abbb436142d7a4a7c8 /WebKit/mac/WebView
parente196732677050bd463301566a68a643b6d14b907 (diff)
downloadexternal_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.zip
external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.gz
external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.bz2
Merge webkit.org at R49305 : Automatic merge by git.
Change-Id: I8968561bc1bfd72b8923b7118d3728579c6dbcc7
Diffstat (limited to 'WebKit/mac/WebView')
-rw-r--r--WebKit/mac/WebView/WebDelegateImplementationCaching.h13
-rw-r--r--WebKit/mac/WebView/WebDelegateImplementationCaching.mm18
-rw-r--r--WebKit/mac/WebView/WebDynamicScrollBarsView.h2
-rw-r--r--WebKit/mac/WebView/WebDynamicScrollBarsView.mm66
-rw-r--r--WebKit/mac/WebView/WebFrame.mm9
-rw-r--r--WebKit/mac/WebView/WebFrameLoadDelegatePrivate.h39
-rw-r--r--WebKit/mac/WebView/WebFramePrivate.h2
-rw-r--r--WebKit/mac/WebView/WebFrameView.mm2
-rw-r--r--WebKit/mac/WebView/WebHTMLView.mm87
-rw-r--r--WebKit/mac/WebView/WebHTMLViewInternal.h3
-rw-r--r--WebKit/mac/WebView/WebHistoryDelegate.h42
-rw-r--r--WebKit/mac/WebView/WebJSPDFDoc.h30
-rw-r--r--WebKit/mac/WebView/WebJSPDFDoc.mm76
-rw-r--r--WebKit/mac/WebView/WebNavigationData.h46
-rw-r--r--WebKit/mac/WebView/WebNavigationData.mm108
-rw-r--r--WebKit/mac/WebView/WebPDFDocumentExtras.h32
-rw-r--r--WebKit/mac/WebView/WebPDFDocumentExtras.mm141
-rw-r--r--WebKit/mac/WebView/WebPDFRepresentation.h2
-rw-r--r--WebKit/mac/WebView/WebPDFRepresentation.mm (renamed from WebKit/mac/WebView/WebPDFRepresentation.m)51
-rw-r--r--WebKit/mac/WebView/WebPolicyDelegatePrivate.h2
-rw-r--r--WebKit/mac/WebView/WebPreferenceKeysPrivate.h5
-rw-r--r--WebKit/mac/WebView/WebPreferences.mm61
-rw-r--r--WebKit/mac/WebView/WebPreferencesPrivate.h19
-rw-r--r--WebKit/mac/WebView/WebScriptDebugger.mm7
-rw-r--r--WebKit/mac/WebView/WebTextCompletionController.mm7
-rw-r--r--WebKit/mac/WebView/WebUIDelegatePrivate.h6
-rw-r--r--WebKit/mac/WebView/WebVideoFullscreenController.h64
-rw-r--r--WebKit/mac/WebView/WebVideoFullscreenController.mm444
-rw-r--r--WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.h61
-rw-r--r--WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm583
-rw-r--r--WebKit/mac/WebView/WebView.mm203
-rw-r--r--WebKit/mac/WebView/WebViewData.h9
-rw-r--r--WebKit/mac/WebView/WebViewData.mm3
-rw-r--r--WebKit/mac/WebView/WebViewInternal.h11
-rw-r--r--WebKit/mac/WebView/WebViewPrivate.h48
-rw-r--r--WebKit/mac/WebView/WebWindowAnimation.h59
-rw-r--r--WebKit/mac/WebView/WebWindowAnimation.m239
37 files changed, 2511 insertions, 89 deletions
diff --git a/WebKit/mac/WebView/WebDelegateImplementationCaching.h b/WebKit/mac/WebView/WebDelegateImplementationCaching.h
index 41e44e0..907ba42 100644
--- a/WebKit/mac/WebView/WebDelegateImplementationCaching.h
+++ b/WebKit/mac/WebView/WebDelegateImplementationCaching.h
@@ -67,6 +67,8 @@ struct WebFrameLoadDelegateImplementationCache {
IMP didFirstVisuallyNonEmptyLayoutInFrameFunc;
IMP didReceiveIconForFrameFunc;
IMP didFinishDocumentLoadForFrameFunc;
+ IMP didDisplayInsecureContentFunc;
+ IMP didRunInsecureContentFunc;
};
struct WebScriptDebugDelegateImplementationCache {
@@ -79,9 +81,17 @@ struct WebScriptDebugDelegateImplementationCache {
IMP exceptionWasRaisedFunc;
};
+struct WebHistoryDelegateImplementationCache {
+ IMP navigatedFunc;
+ IMP clientRedirectFunc;
+ IMP serverRedirectFunc;
+ IMP setTitleFunc;
+};
+
WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *);
WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *);
WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *);
+WebHistoryDelegateImplementationCache* WebViewGetHistoryDelegateImplementations(WebView *webView);
id CallFormDelegate(WebView *, SEL, id, id);
id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3, id object4, id object5);
@@ -119,3 +129,6 @@ id CallScriptDebugDelegate(IMP, WebView *, SEL, id, id, NSInteger, id);
id CallScriptDebugDelegate(IMP, WebView *, SEL, id, NSInteger, id, NSInteger, id);
id CallScriptDebugDelegate(IMP, WebView *, SEL, id, NSInteger, id, id, id);
id CallScriptDebugDelegate(IMP, WebView *, SEL, id, NSInteger, NSInteger, id);
+
+id CallHistoryDelegate(IMP, WebView *, SEL, id, id);
+id CallHistoryDelegate(IMP, WebView *, SEL, id, id, id);
diff --git a/WebKit/mac/WebView/WebDelegateImplementationCaching.mm b/WebKit/mac/WebView/WebDelegateImplementationCaching.mm
index 441df92..7757fc7 100644
--- a/WebKit/mac/WebView/WebDelegateImplementationCaching.mm
+++ b/WebKit/mac/WebView/WebDelegateImplementationCaching.mm
@@ -60,6 +60,14 @@ WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplemen
return &webView->_private->scriptDebugDelegateImplementations;
}
+WebHistoryDelegateImplementationCache* WebViewGetHistoryDelegateImplementations(WebView *webView)
+{
+ static WebHistoryDelegateImplementationCache empty;
+ if (!webView)
+ return &empty;
+ return &webView->_private->historyDelegateImplementations;
+}
+
// We use these functions to call the delegates and block exceptions. These functions are
// declared inside a WebView category to get direct access to the delegate data memebers,
// preventing more ObjC message dispatch and compensating for the expense of the @try/@catch.
@@ -540,6 +548,16 @@ id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id o
return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2);
}
+id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2)
+{
+ return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2);
+}
+
+id CallHistoryDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3)
+{
+ return CallDelegate(implementation, self, self->_private->historyDelegate, selector, object1, object2, object3);
+}
+
// The form delegate needs to have it's own implementation, because the first argument is never the WebView
id CallFormDelegate(WebView *self, SEL selector, id object1, id object2)
diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsView.h b/WebKit/mac/WebView/WebDynamicScrollBarsView.h
index ce92b33..40aadc0 100644
--- a/WebKit/mac/WebView/WebDynamicScrollBarsView.h
+++ b/WebKit/mac/WebView/WebDynamicScrollBarsView.h
@@ -43,6 +43,8 @@ extern const int WebCoreScrollbarAlwaysOn;
BOOL suppressLayout;
BOOL suppressScrollers;
BOOL inUpdateScrollers;
+ BOOL verticallyPinnedByPreviousWheelEvent;
+ BOOL horizontallyPinnedByPreviousWheelEvent;
unsigned inUpdateScrollersLayoutPass;
}
- (void)setAllowsHorizontalScrolling:(BOOL)flag; // This method is used by Safari, so it cannot be removed.
diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsView.mm b/WebKit/mac/WebView/WebDynamicScrollBarsView.mm
index 0cf2a98..3c28e3c 100644
--- a/WebKit/mac/WebView/WebDynamicScrollBarsView.mm
+++ b/WebKit/mac/WebView/WebDynamicScrollBarsView.mm
@@ -89,15 +89,26 @@ static const unsigned cMaxUpdateScrollbarsPass = 2;
- (void)updateScrollers
{
- BOOL hasVerticalScroller = [self hasVerticalScroller];
+ NSView *documentView = [self documentView];
+
+ // If we came in here with the view already needing a layout, then go ahead and do that
+ // first. (This will be the common case, e.g., when the page changes due to window resizing for example).
+ // This layout will not re-enter updateScrollers and does not count towards our max layout pass total.
+ if (!suppressLayout && !suppressScrollers && [documentView isKindOfClass:[WebHTMLView class]]) {
+ WebHTMLView* htmlView = (WebHTMLView*)documentView;
+ if ([htmlView _needsLayout]) {
+ inUpdateScrollers = YES;
+ [(id <WebDocumentView>)documentView layout];
+ inUpdateScrollers = NO;
+ }
+ }
+
BOOL hasHorizontalScroller = [self hasHorizontalScroller];
+ BOOL hasVerticalScroller = [self hasVerticalScroller];
BOOL newHasHorizontalScroller = hasHorizontalScroller;
BOOL newHasVerticalScroller = hasVerticalScroller;
- BOOL needsLayout = NO;
-
- NSView *documentView = [self documentView];
if (!documentView) {
newHasHorizontalScroller = NO;
newHasVerticalScroller = NO;
@@ -122,19 +133,7 @@ static const unsigned cMaxUpdateScrollbarsPass = 2;
return;
}
- needsLayout = NO;
-
- // If we came in here with the view already needing a layout, then go ahead and do that
- // first. (This will be the common case, e.g., when the page changes due to window resizing for example).
- // This layout will not re-enter updateScrollers and does not count towards our max layout pass total.
- if ([documentView isKindOfClass:[WebHTMLView class]]) {
- WebHTMLView* htmlView = (WebHTMLView*)documentView;
- if ([htmlView _needsLayout]) {
- inUpdateScrollers = YES;
- [(id <WebDocumentView>)documentView layout];
- inUpdateScrollers = NO;
- }
- }
+ BOOL needsLayout = NO;
NSSize documentSize = [documentView frame].size;
NSSize visibleSize = [self documentVisibleRect].size;
@@ -199,7 +198,8 @@ static const unsigned cMaxUpdateScrollbarsPass = 2;
// http://www.linuxpowered.com/archive/howto/Net-HOWTO-8.html.
// The underlying cause is some problem in the NSText machinery, but I was not
// able to pin it down.
- if (!inUpdateScrollers && [[NSGraphicsContext currentContext] isDrawingToScreen])
+ NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
+ if (!inUpdateScrollers && (!currentContext || [currentContext isDrawingToScreen]))
[self updateScrollers];
}
@@ -328,17 +328,41 @@ static const unsigned cMaxUpdateScrollbarsPass = 2;
BOOL isContinuous;
WKGetWheelEventDeltas(event, &deltaX, &deltaY, &isContinuous);
+ BOOL isLatchingEvent = WKIsLatchingWheelEvent(event);
+
if (fabsf(deltaY) > fabsf(deltaX)) {
if (![self allowsVerticalScrolling]) {
[[self nextResponder] scrollWheel:event];
return;
}
- } else if (![self allowsHorizontalScrolling]) {
- [[self nextResponder] scrollWheel:event];
- return;
+
+ if (isLatchingEvent && !verticallyPinnedByPreviousWheelEvent) {
+ double verticalPosition = [[self verticalScroller] doubleValue];
+ if ((deltaY >= 0.0 && verticalPosition == 0.0) || (deltaY <= 0.0 && verticalPosition == 1.0))
+ return;
+ }
+ } else {
+ if (![self allowsHorizontalScrolling]) {
+ [[self nextResponder] scrollWheel:event];
+ return;
+ }
+
+ if (isLatchingEvent && !horizontallyPinnedByPreviousWheelEvent) {
+ double horizontalPosition = [[self horizontalScroller] doubleValue];
+ if ((deltaX >= 0.0 && horizontalPosition == 0.0) || (deltaX <= 0.0 && horizontalPosition == 1.0))
+ return;
+ }
}
[super scrollWheel:event];
+
+ if (!isLatchingEvent) {
+ double verticalPosition = [[self verticalScroller] doubleValue];
+ double horizontalPosition = [[self horizontalScroller] doubleValue];
+
+ verticallyPinnedByPreviousWheelEvent = (verticalPosition == 0.0 || verticalPosition == 1.0);
+ horizontallyPinnedByPreviousWheelEvent = (horizontalPosition == 0.0 || horizontalPosition == 1.0);
+ }
}
- (BOOL)accessibilityIsIgnored
diff --git a/WebKit/mac/WebView/WebFrame.mm b/WebKit/mac/WebView/WebFrame.mm
index c03ef58..27aac67 100644
--- a/WebKit/mac/WebView/WebFrame.mm
+++ b/WebKit/mac/WebView/WebFrame.mm
@@ -1174,7 +1174,7 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
[result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameHasPlugins];
if (DOMWindow* domWindow = _private->coreFrame->domWindow()) {
- if (domWindow->hasEventListener(eventNames().unloadEvent))
+ if (domWindow->hasEventListeners(eventNames().unloadEvent))
[result setObject:[NSNumber numberWithBool:YES] forKey:WebFrameHasUnloadListener];
if (domWindow->optionalApplicationCache())
@@ -1195,6 +1195,13 @@ static inline WebDataSource *dataSource(DocumentLoader* loader)
return result;
}
+- (BOOL)_allowsFollowingLink:(NSURL *)URL
+{
+ if (!_private->coreFrame)
+ return YES;
+ return SecurityOrigin::canLoad(URL, String(), _private->coreFrame->document());
+}
+
@end
@implementation WebFrame
diff --git a/WebKit/mac/WebView/WebFrameLoadDelegatePrivate.h b/WebKit/mac/WebView/WebFrameLoadDelegatePrivate.h
new file mode 100644
index 0000000..80fa08a
--- /dev/null
+++ b/WebKit/mac/WebView/WebFrameLoadDelegatePrivate.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 Adam Barth. 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 <WebKit/WebFrameLoadDelegate.h>
+
+@class WebSecurityOrigin;
+
+@interface NSObject (WebFrameLoadDelegatePrivate)
+
+- (void)webViewDidDisplayInsecureContent:(WebView *)webView;
+
+- (void)webView:(WebView *)webView didRunInsecureContent:(WebSecurityOrigin *)origin;
+
+@end
diff --git a/WebKit/mac/WebView/WebFramePrivate.h b/WebKit/mac/WebView/WebFramePrivate.h
index 8e7a2ef..7446584 100644
--- a/WebKit/mac/WebView/WebFramePrivate.h
+++ b/WebKit/mac/WebView/WebFramePrivate.h
@@ -110,4 +110,6 @@ typedef enum {
- (void)_replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace;
- (NSMutableDictionary *)_cacheabilityDictionary;
+
+- (BOOL)_allowsFollowingLink:(NSURL *)URL;
@end
diff --git a/WebKit/mac/WebView/WebFrameView.mm b/WebKit/mac/WebView/WebFrameView.mm
index 1a460ea..c300586 100644
--- a/WebKit/mac/WebView/WebFrameView.mm
+++ b/WebKit/mac/WebView/WebFrameView.mm
@@ -273,8 +273,6 @@ static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class objCCl
owner->setWidget(view);
// Now the render part owns the view, so we don't any more.
}
-
- view->initScrollbars();
}
@end
diff --git a/WebKit/mac/WebView/WebHTMLView.mm b/WebKit/mac/WebView/WebHTMLView.mm
index d58c765..102f630 100644
--- a/WebKit/mac/WebView/WebHTMLView.mm
+++ b/WebKit/mac/WebView/WebHTMLView.mm
@@ -125,6 +125,7 @@
using namespace WebCore;
using namespace HTMLNames;
using namespace WTF;
+using namespace std;
@interface NSWindow (BorderViewAccess)
- (NSView*)_web_borderView;
@@ -212,6 +213,9 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
- (void)_setDrawsOwnDescendants:(BOOL)drawsOwnDescendants;
- (void)_propagateDirtyRectsToOpaqueAncestors;
- (void)_windowChangedKeyState;
+#if USE(ACCELERATED_COMPOSITING) && defined(BUILDING_ON_LEOPARD)
+- (void)_updateLayerGeometryFromView;
+#endif
@end
@interface NSApplication (WebNSApplicationDetails)
@@ -979,8 +983,7 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart)
{
// FIXME: this can fail if the dataSource is nil, which happens when the WebView is tearing down from the window closing.
WebHTMLView *view = (WebHTMLView *)[[[[_private->dataSource _webView] mainFrame] frameView] documentView];
- ASSERT(view);
- ASSERT([view isKindOfClass:[WebHTMLView class]]);
+ ASSERT(!view || [view isKindOfClass:[WebHTMLView class]]);
return view;
}
@@ -1148,8 +1151,11 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
{
NSPoint origin = [[self superview] bounds].origin;
if (!NSEqualPoints(_private->lastScrollPosition, origin)) {
- if (Frame* coreFrame = core([self _frame]))
- coreFrame->eventHandler()->sendScrollEvent();
+ if (Frame* coreFrame = core([self _frame])) {
+ if (FrameView* coreView = coreFrame->view())
+ coreView->scrollPositionChanged();
+ }
+
[_private->completionController endRevertingChange:NO moveLeft:NO];
WebView *webView = [self _webView];
@@ -1649,10 +1655,10 @@ static void _updateMouseoverTimerCallback(CFRunLoopTimerRef timer, void *info)
urlStringSize.height = [urlFont ascender] - [urlFont descender];
imageSize.height += urlStringSize.height;
if (urlStringSize.width > MAX_DRAG_LABEL_WIDTH) {
- imageSize.width = MAX(MAX_DRAG_LABEL_WIDTH + DRAG_LABEL_BORDER_X * 2.0f, MIN_DRAG_LABEL_WIDTH_BEFORE_CLIP);
+ imageSize.width = max(MAX_DRAG_LABEL_WIDTH + DRAG_LABEL_BORDER_X * 2, MIN_DRAG_LABEL_WIDTH_BEFORE_CLIP);
clipURLString = YES;
} else {
- imageSize.width = MAX(labelSize.width + DRAG_LABEL_BORDER_X * 2.0f, urlStringSize.width + DRAG_LABEL_BORDER_X * 2.0f);
+ imageSize.width = max(labelSize.width + DRAG_LABEL_BORDER_X * 2, urlStringSize.width + DRAG_LABEL_BORDER_X * 2);
}
}
NSImage *dragImage = [[[NSImage alloc] initWithSize: imageSize] autorelease];
@@ -2299,24 +2305,36 @@ static bool matchesExtensionOrEquivalent(NSString *filename, NSString *extension
return [[webView _editingDelegateForwarder] webView:webView doCommandBySelector:selector];
}
+typedef HashMap<SEL, String> SelectorNameMap;
+
+// Map selectors into Editor command names.
+// This is not needed for any selectors that have the same name as the Editor command.
+static const SelectorNameMap* createSelectorExceptionMap()
+{
+ SelectorNameMap* map = new HashMap<SEL, String>;
+
+ map->add(@selector(insertNewlineIgnoringFieldEditor:), "InsertNewline");
+ map->add(@selector(insertParagraphSeparator:), "InsertNewline");
+ map->add(@selector(insertTabIgnoringFieldEditor:), "InsertTab");
+ map->add(@selector(pageDown:), "MovePageDown");
+ map->add(@selector(pageDownAndModifySelection:), "MovePageDownAndModifySelection");
+ map->add(@selector(pageUp:), "MovePageUp");
+ map->add(@selector(pageUpAndModifySelection:), "MovePageUpAndModifySelection");
+
+ return map;
+}
+
static String commandNameForSelector(SEL selector)
{
- // Change a few command names into ones supported by WebCore::Editor.
- // If this list gets too long we might decide we need to use a hash table.
- if (selector == @selector(insertParagraphSeparator:) || selector == @selector(insertNewlineIgnoringFieldEditor:))
- return "InsertNewline";
- if (selector == @selector(insertTabIgnoringFieldEditor:))
- return "InsertTab";
- if (selector == @selector(pageDown:))
- return "MovePageDown";
- if (selector == @selector(pageDownAndModifySelection:))
- return "MovePageDownAndModifySelection";
- if (selector == @selector(pageUp:))
- return "MovePageUp";
- if (selector == @selector(pageUpAndModifySelection:))
- return "MovePageUpAndModifySelection";
+ // Check the exception map first.
+ static const SelectorNameMap* exceptionMap = createSelectorExceptionMap();
+ SelectorNameMap::const_iterator it = exceptionMap->find(selector);
+ if (it != exceptionMap->end())
+ return it->second;
// Remove the trailing colon.
+ // No need to capitalize the command name since Editor command names are
+ // not case sensitive.
const char* selectorName = sel_getName(selector);
size_t selectorNameLength = strlen(selectorName);
if (selectorNameLength < 2 || selectorName[selectorNameLength - 1] != ':')
@@ -3160,7 +3178,8 @@ WEBCORE_COMMAND(yankAndSelect)
double start = CFAbsoluteTimeGetCurrent();
#endif
- if ([[self _webView] _mustDrawUnionedRect:rect singleRects:rects count:count])
+ WebView *webView = [self _webView];
+ if ([webView _mustDrawUnionedRect:rect singleRects:rects count:count])
[self drawSingleRect:rect];
else
for (int i = 0; i < count; ++i)
@@ -3175,16 +3194,19 @@ WEBCORE_COMMAND(yankAndSelect)
[self _setAsideSubviews];
#if USE(ACCELERATED_COMPOSITING)
- if ([[self _webView] _needsOneShotDrawingSynchronization]) {
+ if ([webView _needsOneShotDrawingSynchronization]) {
// Disable screen updates so that any layer changes committed here
// don't show up on the screen before the window flush at the end
- // of the current window display.
- [[self window] disableScreenUpdatesUntilFlush];
+ // of the current window display, but only if a window flush is actually
+ // going to happen.
+ NSWindow *window = [self window];
+ if ([window viewsNeedDisplay])
+ [window disableScreenUpdatesUntilFlush];
// Make sure any layer changes that happened as a result of layout
// via -viewWillDraw are committed.
[CATransaction flush];
- [[self _webView] _setNeedsOneShotDrawingSynchronization:NO];
+ [webView _setNeedsOneShotDrawingSynchronization:NO];
}
#endif
}
@@ -3407,10 +3429,6 @@ done:
if (!page)
return NSDragOperationNone;
- // FIXME: Why do we override the source provided operation here? Why not in DragController::startDrag
- if (page->dragController()->sourceDragOperation() == DragOperationNone)
- return NSDragOperationGeneric | NSDragOperationCopy;
-
return (NSDragOperation)page->dragController()->sourceDragOperation();
}
@@ -3715,7 +3733,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
#ifdef __LP64__
// If the new bottom is equal to the old bottom (when both are treated as floats), we just copy
// oldBottom over to newBottom. This prevents rounding errors that can occur when converting newBottomFloat to a double.
- if (fabs((float)oldBottom - newBottomFloat) <= std::numeric_limits<float>::epsilon())
+ if (fabs((float)oldBottom - newBottomFloat) <= numeric_limits<float>::epsilon())
*newBottom = oldBottom;
else
#endif
@@ -3750,7 +3768,7 @@ static BOOL isInPasswordField(Frame* coreFrame)
float maxShrinkToFitScaleFactor = 1.0f / PrintingMaximumShrinkFactor;
float shrinkToFitScaleFactor = [self _availablePaperWidthForPrintOperation:printOperation]/viewWidth;
float shrinkToAvoidOrphan = _private->avoidingPrintOrphan ? (1.0f / PrintingOrphanShrinkAdjustment) : 1.0f;
- return userScaleFactor * MAX(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor) * shrinkToAvoidOrphan;
+ return userScaleFactor * max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor) * shrinkToAvoidOrphan;
}
// FIXME 3491344: This is a secret AppKit-internal method that we need to override in order
@@ -5450,13 +5468,13 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
if (!_private->layerHostingView)
return;
- const CGFloat maxHeight = 4096;
+ const CGFloat maxHeight = 2048;
NSRect layerViewFrame = [self bounds];
if (layerViewFrame.size.height > maxHeight) {
CGFloat documentHeight = layerViewFrame.size.height;
- // Clamp the size of the view to <= 4096px to avoid the bug.
+ // Clamp the size of the view to <= maxHeight to avoid the bug.
layerViewFrame.size.height = maxHeight;
NSRect visibleRect = [[self enclosingScrollView] documentVisibleRect];
@@ -5468,7 +5486,8 @@ static CGPoint coreGraphicsScreenPointForAppKitScreenPoint(NSPoint point)
CGFloat bottomOffset = documentHeight - layerViewFrame.size.height - topOffset;
[[_private->layerHostingView layer] setSublayerTransform:CATransform3DMakeTranslation(0, -bottomOffset, 0)];
}
-
+
+ [_private->layerHostingView _updateLayerGeometryFromView]; // Workaround for <rdar://problem/7071636>
[_private->layerHostingView setFrame:layerViewFrame];
}
#endif // defined(BUILDING_ON_LEOPARD)
diff --git a/WebKit/mac/WebView/WebHTMLViewInternal.h b/WebKit/mac/WebView/WebHTMLViewInternal.h
index b5ec1c0..3f1f50d 100644
--- a/WebKit/mac/WebView/WebHTMLViewInternal.h
+++ b/WebKit/mac/WebView/WebHTMLViewInternal.h
@@ -30,6 +30,9 @@
#import "WebHTMLViewPrivate.h"
+#if USE(ACCELERATED_COMPOSITING)
+@class CALayer;
+#endif
@class WebFrame;
namespace WebCore {
diff --git a/WebKit/mac/WebView/WebHistoryDelegate.h b/WebKit/mac/WebView/WebHistoryDelegate.h
new file mode 100644
index 0000000..4029eb0
--- /dev/null
+++ b/WebKit/mac/WebView/WebHistoryDelegate.h
@@ -0,0 +1,42 @@
+/*
+ * 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. ``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
+ * 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 <Foundation/Foundation.h>
+
+@class WebFrame;
+@class WebNavigationData;
+@class WebView;
+
+@interface NSObject (WebHistoryDelegate)
+
+- (void)webView:(WebView *)webView didNavigateWithNavigationData:(WebNavigationData *)navigationData inFrame:(WebFrame *)webFrame;
+
+- (void)webView:(WebView *)webView didPerformClientRedirectFromURL:(NSString *)sourceURL toURL:(NSString *)destinationURL inFrame:(WebFrame *)webFrame;
+
+- (void)webView:(WebView *)webView didPerformServerRedirectFromURL:(NSString *)sourceURL toURL:(NSString *)destinationURL inFrame:(WebFrame *)webFrame;
+
+- (void)webView:(WebView *)webView updateHistoryTitle:(NSString *)title forURL:(NSString *)url;
+
+@end
diff --git a/WebKit/mac/WebView/WebJSPDFDoc.h b/WebKit/mac/WebView/WebJSPDFDoc.h
new file mode 100644
index 0000000..d3e756c
--- /dev/null
+++ b/WebKit/mac/WebView/WebJSPDFDoc.h
@@ -0,0 +1,30 @@
+/*
+ * 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. ``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
+ * 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 <JavaScriptCore/JSBase.h>
+
+@class WebDataSource;
+
+JSObjectRef makeJSPDFDoc(JSContextRef, WebDataSource *);
diff --git a/WebKit/mac/WebView/WebJSPDFDoc.mm b/WebKit/mac/WebView/WebJSPDFDoc.mm
new file mode 100644
index 0000000..24169fe
--- /dev/null
+++ b/WebKit/mac/WebView/WebJSPDFDoc.mm
@@ -0,0 +1,76 @@
+/*
+ * 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. ``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
+ * 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 "WebJSPDFDoc.h"
+
+#import "WebDataSource.h"
+#import "WebDelegateImplementationCaching.h"
+#import "WebFrame.h"
+#import "WebView.h"
+#import <JavaScriptCore/JSObjectRef.h>
+
+static void jsPDFDocInitialize(JSContextRef ctx, JSObjectRef object)
+{
+ WebDataSource *dataSource = (WebDataSource *)JSObjectGetPrivate(object);
+ CFRetain(dataSource);
+}
+
+static void jsPDFDocFinalize(JSObjectRef object)
+{
+ WebDataSource *dataSource = (WebDataSource *)JSObjectGetPrivate(object);
+ CFRelease(dataSource);
+}
+
+static JSValueRef jsPDFDocPrint(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ WebDataSource *dataSource = (WebDataSource *)JSObjectGetPrivate(thisObject);
+
+ WebView *webView = [[dataSource webFrame] webView];
+ CallUIDelegate(webView, @selector(webView:printFrameView:), [[dataSource webFrame] frameView]);
+
+ return JSValueMakeUndefined(ctx);
+}
+
+static JSStaticFunction jsPDFDocStaticFunctions[] = {
+ { "print", jsPDFDocPrint, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+ { 0, 0, 0 },
+};
+
+static JSClassDefinition jsPDFDocClassDefinition = {
+ 0,
+ kJSClassAttributeNone,
+ "Doc",
+ 0,
+ 0,
+ jsPDFDocStaticFunctions,
+ jsPDFDocInitialize, jsPDFDocFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+JSObjectRef makeJSPDFDoc(JSContextRef ctx, WebDataSource *dataSource)
+{
+ static JSClassRef jsPDFDocClass = JSClassCreate(&jsPDFDocClassDefinition);
+
+ return JSObjectMake(ctx, jsPDFDocClass, dataSource);
+}
diff --git a/WebKit/mac/WebView/WebNavigationData.h b/WebKit/mac/WebView/WebNavigationData.h
new file mode 100644
index 0000000..227df16
--- /dev/null
+++ b/WebKit/mac/WebView/WebNavigationData.h
@@ -0,0 +1,46 @@
+/*
+ * 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. ``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
+ * 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 <Foundation/Foundation.h>
+
+@class WebFrame;
+@class WebNavigationDataPrivate;
+@class WebView;
+
+@interface WebNavigationData : NSObject
+{
+@private
+ WebNavigationDataPrivate *_private;
+}
+
+- (id)initWithURLString:(NSString *)url title:(NSString *)title originalRequest:(NSURLRequest *)request response:(NSURLResponse *)response hasSubstituteData:(BOOL)hasSubstituteData clientRedirectSource:(NSString *)redirectSource;
+- (NSString *)url;
+- (NSString *)title;
+- (NSURLRequest *)originalRequest;
+- (NSURLResponse *)response;
+- (BOOL)hasSubstituteData;
+- (NSString *)clientRedirectSource;
+
+@end
diff --git a/WebKit/mac/WebView/WebNavigationData.mm b/WebKit/mac/WebView/WebNavigationData.mm
new file mode 100644
index 0000000..290d8b1
--- /dev/null
+++ b/WebKit/mac/WebView/WebNavigationData.mm
@@ -0,0 +1,108 @@
+/*
+ * 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. ``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
+ * 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 "WebNavigationData.h"
+
+@interface WebNavigationDataPrivate : NSObject
+{
+@public
+ NSString *url;
+ NSString *title;
+ NSURLRequest *originalRequest;
+ NSURLResponse *response;
+ BOOL hasSubstituteData;
+ NSString *clientRedirectSource;
+}
+
+@end
+
+@implementation WebNavigationDataPrivate
+
+- (void)dealloc
+{
+ [url release];
+ [title release];
+ [originalRequest release];
+ [response release];
+ [clientRedirectSource release];
+
+ [super dealloc];
+}
+
+@end
+
+@implementation WebNavigationData
+
+- (id)initWithURLString:(NSString *)url title:(NSString *)title originalRequest:(NSURLRequest *)request response:(NSURLResponse *)response hasSubstituteData:(BOOL)hasSubstituteData clientRedirectSource:(NSString *)redirectSource;
+{
+ _private = [[WebNavigationDataPrivate alloc] init];
+
+ _private->url = [url retain];
+ _private->title = [title retain];
+ _private->originalRequest = [request retain];
+ _private->response = [response retain];
+ _private->hasSubstituteData = hasSubstituteData;
+ _private->clientRedirectSource = [redirectSource retain];
+
+ return self;
+}
+
+- (NSString *)url
+{
+ return _private->url;
+}
+
+- (NSString *)title
+{
+ return _private->title;
+}
+
+- (NSURLRequest *)originalRequest
+{
+ return _private->originalRequest;
+}
+
+- (NSURLResponse *)response
+{
+ return _private->response;
+}
+
+- (BOOL)hasSubstituteData
+{
+ return _private->hasSubstituteData;
+}
+
+- (NSString *)clientRedirectSource
+{
+ return _private->clientRedirectSource;
+}
+
+- (void)dealloc
+{
+ [_private release];
+ [super dealloc];
+}
+
+@end
diff --git a/WebKit/mac/WebView/WebPDFDocumentExtras.h b/WebKit/mac/WebView/WebPDFDocumentExtras.h
new file mode 100644
index 0000000..5a33ccf
--- /dev/null
+++ b/WebKit/mac/WebView/WebPDFDocumentExtras.h
@@ -0,0 +1,32 @@
+/*
+ * 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. ``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
+ * 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 <PDFKit/PDFDocument.h>
+
+@interface PDFDocument (WebPDFDocumentExtras)
+- (NSArray *)_web_allScripts;
+@end
+
+void addWebPDFDocumentExtras(Class);
diff --git a/WebKit/mac/WebView/WebPDFDocumentExtras.mm b/WebKit/mac/WebView/WebPDFDocumentExtras.mm
new file mode 100644
index 0000000..ec580ec
--- /dev/null
+++ b/WebKit/mac/WebView/WebPDFDocumentExtras.mm
@@ -0,0 +1,141 @@
+/*
+ * 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. ``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
+ * 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 "WebPDFDocumentExtras.h"
+
+#import "WebTypesInternal.h"
+#import <JavaScriptCore/Vector.h>
+#import <JavaScriptCore/RetainPtr.h>
+#import <PDFKit/PDFDocument.h>
+#import <objc/objc-runtime.h>
+
+#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
+@interface PDFDocument (Internal)
+- (CGPDFDocumentRef)documentRef;
+@end
+#endif
+
+static void appendValuesInPDFNameSubtreeToVector(CGPDFDictionaryRef subtree, Vector<CGPDFObjectRef>& values)
+{
+ CGPDFArrayRef names;
+ if (CGPDFDictionaryGetArray(subtree, "Names", &names)) {
+ size_t nameCount = CGPDFArrayGetCount(names) / 2;
+ for (size_t i = 0; i < nameCount; ++i) {
+ CGPDFObjectRef object;
+ CGPDFArrayGetObject(names, 2 * i + 1, &object);
+ values.append(object);
+ }
+ return;
+ }
+
+ CGPDFArrayRef kids;
+ if (!CGPDFDictionaryGetArray(subtree, "Kids", &kids))
+ return;
+
+ size_t kidCount = CGPDFArrayGetCount(kids);
+ for (size_t i = 0; i < kidCount; ++i) {
+ CGPDFDictionaryRef kid;
+ if (!CGPDFArrayGetDictionary(kids, i, &kid))
+ continue;
+ appendValuesInPDFNameSubtreeToVector(kid, values);
+ }
+}
+
+static void getAllValuesInPDFNameTree(CGPDFDictionaryRef tree, Vector<CGPDFObjectRef>& allValues)
+{
+ appendValuesInPDFNameSubtreeToVector(tree, allValues);
+}
+
+static NSArray *web_PDFDocumentAllScripts(id self, SEL _cmd)
+{
+ NSMutableArray *scripts = [NSMutableArray array];
+ CGPDFDocumentRef pdfDocument = [self documentRef];
+ if (!pdfDocument)
+ return scripts;
+
+ CGPDFDictionaryRef pdfCatalog = CGPDFDocumentGetCatalog(pdfDocument);
+ if (!pdfCatalog)
+ return scripts;
+
+ // Get the dictionary of all document-level name trees.
+ CGPDFDictionaryRef namesDictionary;
+ if (!CGPDFDictionaryGetDictionary(pdfCatalog, "Names", &namesDictionary))
+ return scripts;
+
+ // Get the document-level "JavaScript" name tree.
+ CGPDFDictionaryRef javaScriptNameTree;
+ if (!CGPDFDictionaryGetDictionary(namesDictionary, "JavaScript", &javaScriptNameTree))
+ return scripts;
+
+ // The names are aribtrary. We are only interested in the values.
+ Vector<CGPDFObjectRef> objects;
+ getAllValuesInPDFNameTree(javaScriptNameTree, objects);
+ size_t objectCount = objects.size();
+
+ for (size_t i = 0; i < objectCount; ++i) {
+ CGPDFDictionaryRef javaScriptAction;
+ if (!CGPDFObjectGetValue(reinterpret_cast<CGPDFObjectRef>(objects[i]), kCGPDFObjectTypeDictionary, &javaScriptAction))
+ continue;
+
+ // A JavaScript action must have an action type of "JavaScript".
+ const char* actionType;
+ if (!CGPDFDictionaryGetName(javaScriptAction, "S", &actionType) || strcmp(actionType, "JavaScript"))
+ continue;
+
+ const UInt8* bytes = 0;
+ CFIndex length;
+ CGPDFStreamRef stream;
+ CGPDFStringRef string;
+ RetainPtr<CFDataRef> data;
+ if (CGPDFDictionaryGetStream(javaScriptAction, "JS", &stream)) {
+ CGPDFDataFormat format;
+ data.adoptCF(CGPDFStreamCopyData(stream, &format));
+ bytes = CFDataGetBytePtr(data.get());
+ length = CFDataGetLength(data.get());
+ } else if (CGPDFDictionaryGetString(javaScriptAction, "JS", &string)) {
+ bytes = CGPDFStringGetBytePtr(string);
+ length = CGPDFStringGetLength(string);
+ }
+ if (!bytes)
+ continue;
+
+ NSStringEncoding encoding = (length > 1 && bytes[0] == 0xFE && bytes[1] == 0xFF) ? NSUnicodeStringEncoding : NSUTF8StringEncoding;
+ NSString *script = [[NSString alloc] initWithBytes:bytes length:length encoding:encoding];
+ [scripts addObject:script];
+ [script release];
+ }
+
+ return scripts;
+}
+
+void addWebPDFDocumentExtras(Class pdfDocumentClass)
+{
+#ifndef BUILDING_ON_TIGER
+ class_addMethod(pdfDocumentClass, @selector(_web_allScripts), (IMP)web_PDFDocumentAllScripts, "@@:");
+#else
+ static struct objc_method_list methodList = { 0, 1, { @selector(_web_allScripts), (char*)"@@:", (IMP)web_PDFDocumentAllScripts } };
+ class_addMethods(pdfDocumentClass, &methodList);
+#endif
+}
diff --git a/WebKit/mac/WebView/WebPDFRepresentation.h b/WebKit/mac/WebView/WebPDFRepresentation.h
index 6b60d4c..be40ae1 100644
--- a/WebKit/mac/WebView/WebPDFRepresentation.h
+++ b/WebKit/mac/WebView/WebPDFRepresentation.h
@@ -26,7 +26,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import <Foundation/Foundation.h>
+#import "WebDocument.h"
@protocol WebDocumentRepresentation;
diff --git a/WebKit/mac/WebView/WebPDFRepresentation.m b/WebKit/mac/WebView/WebPDFRepresentation.mm
index 7eae380..924bda8 100644
--- a/WebKit/mac/WebView/WebPDFRepresentation.m
+++ b/WebKit/mac/WebView/WebPDFRepresentation.mm
@@ -26,15 +26,19 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import <WebKit/WebDataSourcePrivate.h>
-#import <WebKit/WebFrame.h>
-#import <WebKit/WebFrameView.h>
-#import <WebKit/WebNSObjectExtras.h>
-#import <WebKit/WebPDFRepresentation.h>
-#import <WebKit/WebPDFView.h>
-#import <wtf/Assertions.h>
-
-#import <PDFKit/PDFDocument.h>
+#import "WebPDFRepresentation.h"
+
+#import "WebDataSourcePrivate.h"
+#import "WebFrame.h"
+#import "WebJSPDFDoc.h"
+#import "WebNSObjectExtras.h"
+#import "WebPDFDocumentExtras.h"
+#import "WebPDFView.h"
+#import "WebTypesInternal.h"
+#import <JavaScriptCore/Assertions.h>
+#import <JavaScriptCore/JSContextRef.h>
+#import <JavaScriptCore/JSStringRef.h>
+#import <JavaScriptCore/JSStringRefCF.h>
@implementation WebPDFRepresentation
@@ -66,6 +70,16 @@
return PDFDocumentClass;
}
++ (void)initialize
+{
+ if (self != [WebPDFRepresentation class])
+ return;
+
+ Class pdfDocumentClass = [self PDFDocumentClass];
+ if (pdfDocumentClass)
+ addWebPDFDocumentExtras(pdfDocumentClass);
+}
+
- (void)setDataSource:(WebDataSource *)dataSource;
{
}
@@ -121,9 +135,26 @@
WebPDFView *view = (WebPDFView *)[[[dataSource webFrame] frameView] documentView];
PDFDocument *doc = [[[[self class] PDFDocumentClass] alloc] initWithData:data];
[view setPDFDocument:doc];
+
+ NSArray *scripts = [doc _web_allScripts];
[doc release];
-}
+ doc = nil;
+
+ NSUInteger scriptCount = [scripts count];
+ if (!scriptCount)
+ return;
+
+ JSGlobalContextRef ctx = JSGlobalContextCreate(0);
+ JSObjectRef jsPDFDoc = makeJSPDFDoc(ctx, dataSource);
+ for (NSUInteger i = 0; i < scriptCount; ++i) {
+ JSStringRef script = JSStringCreateWithCFString((CFStringRef)[scripts objectAtIndex:i]);
+ JSEvaluateScript(ctx, script, jsPDFDoc, 0, 0, 0);
+ JSStringRelease(script);
+ }
+
+ JSGlobalContextRelease(ctx);
+}
- (BOOL)canProvideDocumentSource
{
diff --git a/WebKit/mac/WebView/WebPolicyDelegatePrivate.h b/WebKit/mac/WebView/WebPolicyDelegatePrivate.h
index 45f8f45..efdf007 100644
--- a/WebKit/mac/WebView/WebPolicyDelegatePrivate.h
+++ b/WebKit/mac/WebView/WebPolicyDelegatePrivate.h
@@ -49,4 +49,6 @@ typedef enum {
@interface NSObject (WebPolicyDelegatePrivate)
// Needed for <rdar://problem/3951283> can view pages from the back/forward cache that should be disallowed by Parental Controls
- (BOOL)webView:(WebView *)webView shouldGoToHistoryItem:(WebHistoryItem *)item;
+
+- (BOOL)webView:(WebView *)webView shouldLoadMediaURL:(NSURL *)url inFrame:(WebFrame *)frame;
@end
diff --git a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
index 6565c09..d6c9d3c 100644
--- a/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
+++ b/WebKit/mac/WebView/WebPreferenceKeysPrivate.h
@@ -55,6 +55,8 @@
#define WebKitPluginsEnabledPreferenceKey @"WebKitPluginsEnabled"
#define WebKitDatabasesEnabledPreferenceKey @"WebKitDatabasesEnabledPreferenceKey"
#define WebKitLocalStorageEnabledPreferenceKey @"WebKitLocalStorageEnabledPreferenceKey"
+#define WebKitExperimentalNotificationsEnabledPreferenceKey @"WebKitExperimentalNotificationsEnabledPreferenceKey"
+#define WebKitExperimentalWebSocketsEnabledPreferenceKey @"WebKitExperimentalWebSocketsEnabledPreferenceKey"
#define WebKitAllowAnimatedImagesPreferenceKey @"WebKitAllowAnimatedImagesPreferenceKey"
#define WebKitAllowAnimatedImageLoopingPreferenceKey @"WebKitAllowAnimatedImageLoopingPreferenceKey"
#define WebKitDisplayImagesKey @"WebKitDisplayImagesKey"
@@ -84,6 +86,9 @@
#define WebKitZoomsTextOnlyPreferenceKey @"WebKitZoomsTextOnly"
#define WebKitXSSAuditorEnabledPreferenceKey @"WebKitXSSAuditorEnabled"
#define WebKitAcceleratedCompositingEnabledPreferenceKey @"WebKitAcceleratedCompositingEnabled"
+#define WebKitWebGLEnabledPreferenceKey @"WebKitWebGLEnabled"
+#define WebKitPluginHalterEnabledPreferenceKey @"WebKitPluginHalterEnabled"
+#define WebKitPluginAllowedRunTimePreferenceKey @"WebKitPluginAllowedRunTime"
// These are private both because callers should be using the cover methods and because the
// cover methods themselves are private.
diff --git a/WebKit/mac/WebView/WebPreferences.mm b/WebKit/mac/WebView/WebPreferences.mm
index 378b280..2910d27 100644
--- a/WebKit/mac/WebView/WebPreferences.mm
+++ b/WebKit/mac/WebView/WebPreferences.mm
@@ -320,6 +320,8 @@ static WebCacheModel cacheModelForMainBundle(void)
[NSNumber numberWithBool:YES], WebKitPluginsEnabledPreferenceKey,
[NSNumber numberWithBool:YES], WebKitDatabasesEnabledPreferenceKey,
[NSNumber numberWithBool:YES], WebKitLocalStorageEnabledPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitExperimentalNotificationsEnabledPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitExperimentalWebSocketsEnabledPreferenceKey,
[NSNumber numberWithBool:YES], WebKitAllowAnimatedImagesPreferenceKey,
[NSNumber numberWithBool:YES], WebKitAllowAnimatedImageLoopingPreferenceKey,
[NSNumber numberWithBool:YES], WebKitDisplayImagesKey,
@@ -350,6 +352,9 @@ static WebCacheModel cacheModelForMainBundle(void)
[NSNumber numberWithBool:YES], WebKitZoomsTextOnlyPreferenceKey,
[NSNumber numberWithBool:YES], WebKitXSSAuditorEnabledPreferenceKey,
[NSNumber numberWithBool:YES], WebKitAcceleratedCompositingEnabledPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitWebGLEnabledPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitPluginHalterEnabledPreferenceKey,
+ [NSNumber numberWithUnsignedInt:4], WebKitPluginAllowedRunTimePreferenceKey,
nil];
// This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
@@ -1011,6 +1016,26 @@ static WebCacheModel cacheModelForMainBundle(void)
[self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey];
}
+- (BOOL)experimentalNotificationsEnabled
+{
+ return [self _boolValueForKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
+}
+
+- (void)setExperimentalNotificationsEnabled:(BOOL)experimentalNotificationsEnabled
+{
+ [self _setBoolValue:experimentalNotificationsEnabled forKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
+}
+
+- (BOOL)experimentalWebSocketsEnabled
+{
+ return [self _boolValueForKey:WebKitExperimentalWebSocketsEnabledPreferenceKey];
+}
+
+- (void)setExperimentalWebSocketsEnabled:(BOOL)experimentalWebSocketsEnabled
+{
+ [self _setBoolValue:experimentalWebSocketsEnabled forKey:WebKitExperimentalWebSocketsEnabledPreferenceKey];
+}
+
+ (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
{
LOG(Encoding, "requesting for %@\n", ident);
@@ -1138,6 +1163,36 @@ static NSString *classIBCreatorID = nil;
[self _setBoolValue:enabled forKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
}
+- (BOOL)webGLEnabled
+{
+ return [self _boolValueForKey:WebKitWebGLEnabledPreferenceKey];
+}
+
+- (void)setWebGLEnabled:(BOOL)enabled
+{
+ [self _setBoolValue:enabled forKey:WebKitWebGLEnabledPreferenceKey];
+}
+
+- (BOOL)pluginHalterEnabled
+{
+ return [self _boolValueForKey:WebKitPluginHalterEnabledPreferenceKey];
+}
+
+- (void)setPluginHalterEnabled:(BOOL)enabled
+{
+ [self _setBoolValue:enabled forKey:WebKitPluginHalterEnabledPreferenceKey];
+}
+
+- (unsigned)pluginAllowedRunTime
+{
+ return [self _integerValueForKey:WebKitPluginAllowedRunTimePreferenceKey];
+}
+
+- (void)setPluginAllowedRunTime:(unsigned)allowedRunTime
+{
+ return [self _setIntegerValue:allowedRunTime forKey:WebKitPluginAllowedRunTimePreferenceKey];
+}
+
- (void)didRemoveFromWebView
{
ASSERT(_private->numWebViews);
@@ -1152,6 +1207,12 @@ static NSString *classIBCreatorID = nil;
{
++_private->numWebViews;
}
+
+- (void)_setPreferenceForTestWithValue:(NSString *)value forKey:(NSString *)key
+{
+ [self _setStringValue:value forKey:key];
+}
+
@end
@implementation WebPreferences (WebInternal)
diff --git a/WebKit/mac/WebView/WebPreferencesPrivate.h b/WebKit/mac/WebView/WebPreferencesPrivate.h
index d571869..6a25921 100644
--- a/WebKit/mac/WebView/WebPreferencesPrivate.h
+++ b/WebKit/mac/WebView/WebPreferencesPrivate.h
@@ -107,6 +107,18 @@ extern NSString *WebPreferencesRemovedNotification;
- (BOOL)isXSSAuditorEnabled;
- (void)setXSSAuditorEnabled:(BOOL)flag;
+- (BOOL)experimentalNotificationsEnabled;
+- (void)setExperimentalNotificationsEnabled:(BOOL)notificationsEnabled;
+
+- (BOOL)experimentalWebSocketsEnabled;
+- (void)setExperimentalWebSocketsEnabled:(BOOL)websocketsEnabled;
+
+- (BOOL)pluginHalterEnabled;
+- (void)setPluginHalterEnabled:(BOOL)enabled;
+
+- (unsigned)pluginAllowedRunTime;
+- (void)setPluginAllowedRunTime:(unsigned)allowedRunTime;
+
// zero means do AutoScale
- (float)PDFScaleFactor;
- (void)setPDFScaleFactor:(float)scale;
@@ -117,6 +129,10 @@ extern NSString *WebPreferencesRemovedNotification;
- (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior;
- (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior;
+// Used to set preference specified in the test via LayoutTestController.overridePreference(..).
+// For use with DumpRenderTree only.
+- (void)_setPreferenceForTestWithValue:(NSString *)value forKey:(NSString *)key;
+
// If site-specific spoofing is enabled, some pages that do inappropriate user-agent string checks will be
// passed a nonstandard user-agent string to get them to work correctly. This method might be removed in
// the future when there's no more need for it.
@@ -139,6 +155,9 @@ extern NSString *WebPreferencesRemovedNotification;
- (BOOL)acceleratedCompositingEnabled;
- (void)setAcceleratedCompositingEnabled:(BOOL)enabled;
+- (BOOL)webGLEnabled;
+- (void)setWebGLEnabled:(BOOL)enabled;
+
// Other private methods
- (void)_postPreferencesChangesNotification;
+ (WebPreferences *)_getInstanceForIdentifier:(NSString *)identifier;
diff --git a/WebKit/mac/WebView/WebScriptDebugger.mm b/WebKit/mac/WebView/WebScriptDebugger.mm
index 76bdf58..8deccff 100644
--- a/WebKit/mac/WebView/WebScriptDebugger.mm
+++ b/WebKit/mac/WebView/WebScriptDebugger.mm
@@ -32,13 +32,14 @@
#import "WebFrameInternal.h"
#import "WebScriptDebugDelegate.h"
#import "WebViewInternal.h"
+#import <JavaScriptCore/DebuggerCallFrame.h>
+#import <JavaScriptCore/JSGlobalObject.h>
+#import <JavaScriptCore/SourceCode.h>
#import <WebCore/DOMWindow.h>
#import <WebCore/Frame.h>
#import <WebCore/JSDOMWindow.h>
#import <WebCore/KURL.h>
#import <WebCore/ScriptController.h>
-#import <debugger/DebuggerCallFrame.h>
-#import <runtime/JSGlobalObject.h>
using namespace JSC;
using namespace WebCore;
@@ -68,7 +69,7 @@ static NSURL *toNSURL(const UString& s)
{
if (s.isEmpty())
return nil;
- return KURL(s);
+ return KURL(ParsedURLString, s);
}
static WebFrame *toWebFrame(JSGlobalObject* globalObject)
diff --git a/WebKit/mac/WebView/WebTextCompletionController.mm b/WebKit/mac/WebView/WebTextCompletionController.mm
index f7c172f..6c37b98 100644
--- a/WebKit/mac/WebView/WebTextCompletionController.mm
+++ b/WebKit/mac/WebView/WebTextCompletionController.mm
@@ -39,6 +39,7 @@
@end
using namespace WebCore;
+using namespace std;
// This class handles the complete: operation.
// It counts on its host view to call endRevertingChange: whenever the current completion needs to be aborted.
@@ -131,7 +132,7 @@ using namespace WebCore;
windowFrame.size.height = numberToShow * [_tableView rowHeight] + (numberToShow + 1) * [_tableView intercellSpacing].height;
windowFrame.origin.y -= windowFrame.size.height;
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont systemFontOfSize:12.0f], NSFontAttributeName, nil];
- float maxWidth = 0.0f;
+ CGFloat maxWidth = 0;
int maxIndex = -1;
int i;
for (i = 0; i < numberToShow; i++) {
@@ -146,8 +147,8 @@ using namespace WebCore;
maxWidth = ceilf([NSScrollView frameSizeForContentSize:NSMakeSize(maxWidth, 100.0f) hasHorizontalScroller:NO hasVerticalScroller:YES borderType:NSNoBorder].width);
maxWidth = ceilf([NSWindow frameRectForContentRect:NSMakeRect(0.0f, 0.0f, maxWidth, 100.0f) styleMask:NSBorderlessWindowMask].size.width);
maxWidth += 5.0f;
- windowFrame.size.width = MAX(maxWidth, windowFrame.size.width);
- maxWidth = MIN(400.0f, windowFrame.size.width);
+ windowFrame.size.width = max(maxWidth, windowFrame.size.width);
+ maxWidth = min<CGFloat>(400, windowFrame.size.width);
}
[_popupWindow setFrame:windowFrame display:NO];
diff --git a/WebKit/mac/WebView/WebUIDelegatePrivate.h b/WebKit/mac/WebView/WebUIDelegatePrivate.h
index 717cf01..0715475 100644
--- a/WebKit/mac/WebView/WebUIDelegatePrivate.h
+++ b/WebKit/mac/WebView/WebUIDelegatePrivate.h
@@ -109,7 +109,7 @@ enum {
- (void)webView:(WebView *)sender willPopupMenu:(NSMenu *)menu;
- (void)webView:(WebView *)sender contextMenuItemSelected:(NSMenuItem *)item forElement:(NSDictionary *)element;
- (void)webView:(WebView *)sender saveFrameView:(WebFrameView *)frameView showingPanel:(BOOL)showingPanel;
-
+- (BOOL)webView:(WebView *)sender shouldHaltPlugin:(DOMNode *)pluginNode;
/*!
@method webView:frame:exceededDatabaseQuotaForSecurityOrigin:database:
@param sender The WebView sending the delegate method.
@@ -127,8 +127,8 @@ enum {
- (BOOL)webView:(WebView *)sender frame:(WebFrame *)frame requestGeolocationPermission:(WebGeolocation *)geolocation securityOrigin:(WebSecurityOrigin *)origin;
- (void)webView:(WebView *)sender formStateDidChangeForNode:(DOMNode *)node;
-- (void)webView:(WebView *)sender formStateDidFocusNode:(DOMNode *)node;
-- (void)webView:(WebView *)sender formStateDidBlurNode:(DOMNode *)node;
+- (void)webView:(WebView *)sender formDidFocusNode:(DOMNode *)node;
+- (void)webView:(WebView *)sender formDidBlurNode:(DOMNode *)node;
/*!
@method webView:printFrame:
diff --git a/WebKit/mac/WebView/WebVideoFullscreenController.h b/WebKit/mac/WebView/WebVideoFullscreenController.h
new file mode 100644
index 0000000..bb6a083
--- /dev/null
+++ b/WebKit/mac/WebView/WebVideoFullscreenController.h
@@ -0,0 +1,64 @@
+/*
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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(VIDEO)
+
+#import <Cocoa/Cocoa.h>
+#import <wtf/RefPtr.h>
+#import <WebCore/HTMLMediaElement.h>
+
+@protocol WebVideoFullscreenControllerDelegate;
+@class WebVideoFullscreenHUDWindowController;
+@class WebWindowFadeAnimation;
+
+@interface WebVideoFullscreenController : NSWindowController
+{
+@private
+ RefPtr<WebCore::HTMLMediaElement> _mediaElement; // (retain)
+ id<WebVideoFullscreenControllerDelegate> _delegate; // (assign)
+
+ NSWindow *_backgroundFullscreenWindow; // (retain)
+ WebVideoFullscreenHUDWindowController* _hudController; // (retain)
+
+ WebWindowFadeAnimation *_fadeAnimation; // (retain)
+
+ BOOL _isEndingFullscreen;
+ BOOL _isWindowLoaded;
+ BOOL _forceDisableAnimation;
+}
+
+- (id<WebVideoFullscreenControllerDelegate>)delegate;
+- (void)setDelegate:(id<WebVideoFullscreenControllerDelegate>)delegate;
+
+- (void)setMediaElement:(WebCore::HTMLMediaElement*)mediaElement;
+- (WebCore::HTMLMediaElement*)mediaElement;
+
+- (void)enterFullscreen:(NSScreen *)screen;
+- (void)exitFullscreen;
+
+@end
+
+#endif
+
diff --git a/WebKit/mac/WebView/WebVideoFullscreenController.mm b/WebKit/mac/WebView/WebVideoFullscreenController.mm
new file mode 100644
index 0000000..6592ad2
--- /dev/null
+++ b/WebKit/mac/WebView/WebVideoFullscreenController.mm
@@ -0,0 +1,444 @@
+/*
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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(VIDEO)
+
+#import <QTKit/QTKit.h>
+#import <objc/objc-runtime.h>
+#import <HIToolbox/HIToolbox.h>
+
+#import <wtf/UnusedParam.h>
+#import <WebCore/SoftLinking.h>
+#import <WebCore/IntRect.h>
+
+#import "WebVideoFullscreenController.h"
+#import "WebVideoFullscreenHUDWindowController.h"
+#import "WebKitSystemInterface.h"
+#import "WebTypesInternal.h"
+#import "WebWindowAnimation.h"
+
+SOFT_LINK_FRAMEWORK(QTKit)
+SOFT_LINK_CLASS(QTKit, QTMovieView)
+
+@interface WebVideoFullscreenWindow : NSWindow
+#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER)
+<NSAnimationDelegate>
+#endif
+{
+ SEL _controllerActionOnAnimationEnd;
+ WebWindowScaleAnimation *_fullscreenAnimation; // (retain)
+ QTMovieView *_movieView; // (retain)
+}
+- (void)animateFromRect:(NSRect)startRect toRect:(NSRect)endRect withSubAnimation:(NSAnimation *)subAnimation controllerAction:(SEL)controllerAction;
+- (QTMovieView *)movieView;
+- (void)setMovieView:(QTMovieView *)movieView;
+@end
+
+@interface WebVideoFullscreenController(HUDWindowControllerDelegate) <WebVideoFullscreenHUDWindowControllerDelegate>
+@end
+
+@implementation WebVideoFullscreenController
+- (id)init
+{
+ // Do not defer window creation, to make sure -windowNumber is created (needed by WebWindowScaleAnimation).
+ NSWindow *window = [[WebVideoFullscreenWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+ self = [super initWithWindow:window];
+ [window release];
+ if (!self)
+ return nil;
+ [self windowDidLoad];
+ return self;
+
+}
+- (void)dealloc
+{
+ ASSERT(!_backgroundFullscreenWindow);
+ ASSERT(!_fadeAnimation);
+ [super dealloc];
+}
+
+- (WebVideoFullscreenWindow *)fullscreenWindow
+{
+ return (WebVideoFullscreenWindow *)[super window];
+}
+
+- (void)windowDidLoad
+{
+ WebVideoFullscreenWindow *window = [self fullscreenWindow];
+ QTMovieView *view = [[getQTMovieViewClass() alloc] init];
+ [view setFillColor:[NSColor clearColor]];
+ [window setMovieView:view];
+ [view setControllerVisible:NO];
+ [view setPreservesAspectRatio:YES];
+ if (_mediaElement)
+ [view setMovie:_mediaElement->platformMedia().qtMovie];
+ [window setHasShadow:YES]; // This is nicer with a shadow.
+ [window setLevel:NSPopUpMenuWindowLevel-1];
+ [view release];
+}
+
+- (WebCore::HTMLMediaElement*)mediaElement;
+{
+ return _mediaElement.get();
+}
+
+- (void)setMediaElement:(WebCore::HTMLMediaElement*)mediaElement;
+{
+ _mediaElement = mediaElement;
+ if ([self isWindowLoaded]) {
+ QTMovieView *movieView = [[self fullscreenWindow] movieView];
+ [movieView setMovie:_mediaElement->platformMedia().qtMovie];
+ }
+}
+
+- (id<WebVideoFullscreenControllerDelegate>)delegate
+{
+ return _delegate;
+}
+
+- (void)setDelegate:(id<WebVideoFullscreenControllerDelegate>)delegate;
+{
+ _delegate = delegate;
+}
+
+- (CGFloat)clearFadeAnimation
+{
+ [_fadeAnimation stopAnimation];
+ CGFloat previousAlpha = [_fadeAnimation currentAlpha];
+ [_fadeAnimation setWindow:nil];
+ [_fadeAnimation release];
+ _fadeAnimation = nil;
+ return previousAlpha;
+}
+
+- (void)windowDidExitFullscreen
+{
+ [self clearFadeAnimation];
+ [[self window] close];
+ [self setWindow:nil];
+ SetSystemUIMode(kUIModeNormal, 0);
+ [_hudController setDelegate:nil];
+ [_hudController release];
+ _hudController = nil;
+ [_backgroundFullscreenWindow close];
+ [_backgroundFullscreenWindow release];
+ _backgroundFullscreenWindow = nil;
+
+ [self autorelease]; // Associated -retain is in -exitFullscreen.
+ _isEndingFullscreen = NO;
+}
+
+- (void)windowDidEnterFullscreen
+{
+ [self clearFadeAnimation];
+
+ ASSERT(!_hudController);
+ _hudController = [[WebVideoFullscreenHUDWindowController alloc] init];
+ [_hudController setDelegate:self];
+
+ SetSystemUIMode(kUIModeAllSuppressed , 0);
+ [NSCursor setHiddenUntilMouseMoves:YES];
+
+ // Give the HUD keyboard focus initially
+ [_hudController fadeWindowIn];
+}
+
+- (NSRect)mediaElementRect
+{
+ return _mediaElement->screenRect();
+}
+
+#pragma mark -
+#pragma mark Exposed Interface
+
+static void constrainFrameToRatioOfFrame(NSRect *frameToConstrain, const NSRect *frame)
+{
+ // Keep a constrained aspect ratio for the destination window
+ double originalRatio = frame->size.width / frame->size.height;
+ double newRatio = frameToConstrain->size.width / frameToConstrain->size.height;
+ if (newRatio > originalRatio) {
+ double newWidth = originalRatio * frameToConstrain->size.height;
+ double diff = frameToConstrain->size.width - newWidth;
+ frameToConstrain->size.width = newWidth;
+ frameToConstrain->origin.x += diff / 2;
+ } else {
+ double newHeight = frameToConstrain->size.width / originalRatio;
+ double diff = frameToConstrain->size.height - newHeight;
+ frameToConstrain->size.height = newHeight;
+ frameToConstrain->origin.y += diff / 2;
+ }
+}
+
+static NSWindow *createBackgroundFullscreenWindow(NSRect frame, int level)
+{
+ NSWindow *window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+ [window setOpaque:YES];
+ [window setBackgroundColor:[NSColor blackColor]];
+ [window setLevel:level];
+ [window setHidesOnDeactivate:YES];
+ [window setReleasedWhenClosed:NO];
+ return window;
+}
+
+- (void)setupFadeAnimationIfNeededAndFadeIn:(BOOL)fadeIn
+{
+ CGFloat initialAlpha = fadeIn ? 0 : 1;
+ if (_fadeAnimation) {
+ // Make sure we support queuing animation if the previous one isn't over yet
+ initialAlpha = [self clearFadeAnimation];
+ }
+ if (!_forceDisableAnimation)
+ _fadeAnimation = [[WebWindowFadeAnimation alloc] initWithDuration:0.2 window:_backgroundFullscreenWindow initialAlpha:initialAlpha finalAlpha:fadeIn ? 1 : 0];
+}
+
+- (void)enterFullscreen:(NSScreen *)screen;
+{
+ if (!screen)
+ screen = [NSScreen mainScreen];
+
+ NSRect frame = [self mediaElementRect];
+ NSRect endFrame = [screen frame];
+ constrainFrameToRatioOfFrame(&endFrame, &frame);
+
+ // Create a black window if needed
+ if (!_backgroundFullscreenWindow)
+ _backgroundFullscreenWindow = createBackgroundFullscreenWindow([screen frame], [[self window] level]-1);
+ else
+ [_backgroundFullscreenWindow setFrame:[screen frame] display:NO];
+
+ [self setupFadeAnimationIfNeededAndFadeIn:YES];
+ if (_forceDisableAnimation) {
+ // This will disable scale animation
+ frame = NSZeroRect;
+ }
+ [[self fullscreenWindow] animateFromRect:frame toRect:endFrame withSubAnimation:_fadeAnimation controllerAction:@selector(windowDidEnterFullscreen)];
+
+ [_backgroundFullscreenWindow orderWindow:NSWindowBelow relativeTo:[[self fullscreenWindow] windowNumber]];
+}
+
+- (void)exitFullscreen
+{
+ if (_isEndingFullscreen)
+ return;
+ _isEndingFullscreen = YES;
+ [_hudController closeWindow];
+
+ NSRect endFrame = [self mediaElementRect];
+
+ [self setupFadeAnimationIfNeededAndFadeIn:NO];
+ if (_forceDisableAnimation) {
+ // This will disable scale animation
+ endFrame = NSZeroRect;
+ }
+
+ // 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];
+
+ [[self fullscreenWindow] animateFromRect:[[self window] frame] toRect:endFrame withSubAnimation:_fadeAnimation controllerAction:@selector(windowDidExitFullscreen)];
+}
+
+#pragma mark -
+#pragma mark Window callback
+
+- (void)requestExitFullscreenWithAnimation:(BOOL)animation
+{
+ if (_isEndingFullscreen)
+ return;
+
+ _forceDisableAnimation = !animation;
+ _mediaElement->exitFullscreen();
+ _forceDisableAnimation = NO;
+}
+
+- (void)requestExitFullscreen
+{
+ [self requestExitFullscreenWithAnimation:YES];
+}
+
+- (void)fadeHUDIn
+{
+ [_hudController fadeWindowIn];
+}
+@end
+
+@implementation WebVideoFullscreenWindow
+
+- (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 setHidesOnDeactivate:YES];
+ [self setIgnoresMouseEvents:NO];
+ [self setAcceptsMouseMovedEvents:YES];
+ return self;
+}
+
+- (void)dealloc
+{
+ ASSERT(!_fullscreenAnimation);
+ [super dealloc];
+}
+
+- (QTMovieView *)movieView
+{
+ return _movieView;
+}
+
+- (void)setMovieView:(QTMovieView *)movieView
+{
+ if (_movieView == movieView)
+ return;
+ [_movieView release];
+ _movieView = [movieView retain];
+ [self setContentView:_movieView];
+}
+
+- (BOOL)resignFirstResponder
+{
+ return NO;
+}
+
+- (BOOL)canBecomeKeyWindow
+{
+ return NO;
+}
+
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ UNUSED_PARAM(theEvent);
+}
+
+- (void)cancelOperation:(id)sender
+{
+ UNUSED_PARAM(sender);
+ [[self windowController] requestExitFullscreen];
+}
+
+- (void)animatedResizeDidEnd
+{
+ // Call our windowController.
+ if (_controllerActionOnAnimationEnd)
+ [[self windowController] performSelector:_controllerActionOnAnimationEnd];
+ _controllerActionOnAnimationEnd = NULL;
+}
+
+//
+// This function will animate a change of frame rectangle
+// We support queuing animation, that means that we'll correctly
+// interrupt the running animation, and queue the next one.
+//
+- (void)animateFromRect:(NSRect)startRect toRect:(NSRect)endRect withSubAnimation:(NSAnimation *)subAnimation controllerAction:(SEL)controllerAction
+{
+ _controllerActionOnAnimationEnd = controllerAction;
+
+ BOOL wasAnimating = NO;
+ if (_fullscreenAnimation) {
+ wasAnimating = YES;
+
+ // Interrupt any running animation.
+ [_fullscreenAnimation stopAnimation];
+
+ // Save the current rect to ensure a smooth transition.
+ startRect = [_fullscreenAnimation currentFrame];
+ [_fullscreenAnimation release];
+ _fullscreenAnimation = nil;
+ }
+
+ if (NSIsEmptyRect(startRect) || NSIsEmptyRect(endRect)) {
+ // Fakely end the subanimation.
+ [subAnimation setCurrentProgress:1.0];
+ // And remove the weak link to the window.
+ [subAnimation stopAnimation];
+
+ [self setFrame:endRect display:NO];
+ [self makeKeyAndOrderFront:self];
+ [self animatedResizeDidEnd];
+ return;
+ }
+
+ if (!wasAnimating) {
+ // We'll downscale the window during the animation based on the higher resolution rect
+ BOOL higherResolutionIsEndRect = startRect.size.width < endRect.size.width && startRect.size.height < endRect.size.height;
+ [self setFrame:higherResolutionIsEndRect ? endRect : startRect display:NO];
+ }
+
+ ASSERT(!_fullscreenAnimation);
+ _fullscreenAnimation = [[WebWindowScaleAnimation alloc] initWithHintedDuration:0.2 window:self initalFrame:startRect finalFrame:endRect];
+ [_fullscreenAnimation setSubAnimation:subAnimation];
+ [_fullscreenAnimation setDelegate:self];
+
+ // Make sure the animation has scaled the window before showing it.
+ [_fullscreenAnimation setCurrentProgress:0];
+ [self makeKeyAndOrderFront:self];
+
+ [_fullscreenAnimation startAnimation];
+}
+
+- (void)animationDidEnd:(NSAnimation *)animation
+{
+#if !defined(BUILDING_ON_TIGER) // Animations are never threaded on Tiger.
+ if (![NSThread isMainThread]) {
+ [self performSelectorOnMainThread:@selector(animationDidEnd:) withObject:animation waitUntilDone:NO];
+ return;
+ }
+#endif
+ if (animation != _fullscreenAnimation)
+ return;
+
+ // The animation is not really over and was interrupted
+ // Don't send completion events.
+ if ([animation currentProgress] < 1.0)
+ return;
+
+ // Ensure that animation (and subanimation) don't keep
+ // the weak reference to the window ivar that may be destroyed from
+ // now on.
+ [_fullscreenAnimation setWindow:nil];
+
+ [_fullscreenAnimation autorelease];
+ _fullscreenAnimation = nil;
+
+ [self animatedResizeDidEnd];
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ [[self windowController] fadeHUDIn];
+}
+
+- (void)resignKeyWindow
+{
+ [super resignKeyWindow];
+ [[self windowController] requestExitFullscreenWithAnimation:NO];
+}
+@end
+
+#endif /* ENABLE(VIDEO) */
diff --git a/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.h b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.h
new file mode 100644
index 0000000..8b06c1c
--- /dev/null
+++ b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.h
@@ -0,0 +1,61 @@
+/*
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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(VIDEO)
+
+#import <Cocoa/Cocoa.h>
+#import <WebCore/HTMLMediaElement.h>
+
+@protocol WebVideoFullscreenHUDWindowControllerDelegate;
+
+@interface WebVideoFullscreenHUDWindowController : NSWindowController {
+@private
+ id<WebVideoFullscreenHUDWindowControllerDelegate> _delegate;
+ NSTimer *_timelineUpdateTimer;
+#if !defined(BUILDING_ON_TIGER)
+ NSTrackingArea *_area;
+#endif
+ BOOL _mouseIsInHUD;
+
+ NSControl *_timeline;
+ NSTextField *_remainingTimeText;
+ NSTextField *_elapsedTimeText;
+ NSControl *_volumeSlider;
+ NSControl *_playButton;
+}
+- (id<WebVideoFullscreenHUDWindowControllerDelegate>)delegate;
+- (void)setDelegate:(id<WebVideoFullscreenHUDWindowControllerDelegate>)delegate;
+- (void)fadeWindowIn;
+- (void)fadeWindowOut;
+- (void)closeWindow;
+
+@end
+
+@protocol WebVideoFullscreenHUDWindowControllerDelegate <NSObject>
+- (void)requestExitFullscreen;
+- (WebCore::HTMLMediaElement*)mediaElement;
+@end
+
+#endif
diff --git a/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm
new file mode 100644
index 0000000..2edfccc
--- /dev/null
+++ b/WebKit/mac/WebView/WebVideoFullscreenHUDWindowController.mm
@@ -0,0 +1,583 @@
+/*
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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(VIDEO)
+
+#import "WebVideoFullscreenHUDWindowController.h"
+
+#import <QTKit/QTKit.h>
+#import "WebKitSystemInterface.h"
+#import "WebTypesInternal.h"
+#import <wtf/RetainPtr.h>
+
+#define HAVE_MEDIA_CONTROL (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD))
+
+@interface WebVideoFullscreenHUDWindowController (Private) <NSWindowDelegate>
+
+- (void)updateTime;
+- (void)timelinePositionChanged:(id)sender;
+- (float)currentTime;
+- (void)setCurrentTime:(float)currentTime;
+- (double)duration;
+
+- (double)maxVolume;
+- (void)volumeChanged:(id)sender;
+- (double)volume;
+- (void)setVolume:(double)volume;
+
+- (void)playingChanged:(id)sender;
+- (BOOL)playing;
+- (void)setPlaying:(BOOL)playing;
+
+- (void)rewind:(id)sender;
+- (void)fastForward:(id)sender;
+
+- (NSString *)remainingTimeText;
+- (NSString *)elapsedTimeText;
+
+- (void)exitFullscreen:(id)sender;
+@end
+
+
+//
+// HUD Window
+//
+
+@interface WebVideoFullscreenHUDWindow : NSWindow
+@end
+
+@implementation WebVideoFullscreenHUDWindow
+
+- (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 setLevel:NSPopUpMenuWindowLevel];
+ [self setAcceptsMouseMovedEvents:YES];
+ [self setIgnoresMouseEvents:NO];
+ [self setMovableByWindowBackground:YES];
+ [self setHidesOnDeactivate:YES];
+
+ return self;
+}
+
+- (BOOL)canBecomeKeyWindow
+{
+ return YES;
+}
+
+- (void)cancelOperation:(id)sender
+{
+ [[self windowController] exitFullscreen:self];
+}
+
+- (void)center
+{
+ NSRect hudFrame = [self frame];
+ NSRect screenFrame = [[NSScreen mainScreen] frame];
+ [self setFrameTopLeftPoint:NSMakePoint(screenFrame.origin.x + (screenFrame.size.width - hudFrame.size.width) / 2,
+ screenFrame.origin.y + (screenFrame.size.height - hudFrame.size.height) / 6)];
+}
+
+- (void)keyDown:(NSEvent *)event
+{
+ [super keyDown:event];
+ [[self windowController] fadeWindowIn];
+}
+
+@end
+
+//
+// HUD Window Controller
+//
+
+static const CGFloat windowHeight = 59;
+static const CGFloat windowWidth = 438;
+
+static const NSTimeInterval HUDWindowFadeOutDelay = 3;
+
+@implementation WebVideoFullscreenHUDWindowController
+
+- (id)init
+{
+ NSWindow* window = [[WebVideoFullscreenHUDWindow alloc] initWithContentRect:NSMakeRect(0, 0, windowWidth, windowHeight)
+ styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
+ self = [super initWithWindow:window];
+ [window setDelegate:self];
+ [window release];
+ if (!self)
+ return nil;
+ [self windowDidLoad];
+ return self;
+}
+
+- (void)dealloc
+{
+ ASSERT(!_timelineUpdateTimer);
+#if !defined(BUILDING_ON_TIGER)
+ ASSERT(!_area);
+#endif
+ [_timeline release];
+ [_remainingTimeText release];
+ [_elapsedTimeText release];
+ [_volumeSlider release];
+ [_playButton release];
+ [super dealloc];
+}
+
+#if !defined(BUILDING_ON_TIGER)
+- (void)setArea:(NSTrackingArea *)area
+{
+ if (area == _area)
+ return;
+ [_area release];
+ _area = [area retain];
+}
+#endif
+
+- (id<WebVideoFullscreenHUDWindowControllerDelegate>)delegate
+{
+ return _delegate;
+}
+
+- (void)setDelegate:(id<WebVideoFullscreenHUDWindowControllerDelegate>)delegate
+{
+ _delegate = delegate;
+}
+
+- (void)scheduleTimeUpdate
+{
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(unscheduleTimeUpdate) object:self];
+
+ // First, update right away, then schedule future update
+ [self updateTime];
+
+ [_timelineUpdateTimer invalidate];
+ [_timelineUpdateTimer release];
+
+ // Note that this creates a retain cycle between the window and us.
+ _timelineUpdateTimer = [[NSTimer timerWithTimeInterval:0.25 target:self selector:@selector(updateTime) userInfo:nil repeats:YES] retain];
+#if defined(BUILDING_ON_TIGER)
+ [[NSRunLoop currentRunLoop] addTimer:_timelineUpdateTimer forMode:(NSString*)kCFRunLoopCommonModes];
+#else
+ [[NSRunLoop currentRunLoop] addTimer:_timelineUpdateTimer forMode:NSRunLoopCommonModes];
+#endif
+}
+
+- (void)unscheduleTimeUpdate
+{
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(unscheduleTimeUpdate) object:nil];
+
+ [_timelineUpdateTimer invalidate];
+ [_timelineUpdateTimer release];
+ _timelineUpdateTimer = nil;
+}
+
+- (void)fadeWindowIn
+{
+ NSWindow *window = [self window];
+ if (![window isVisible])
+ [window setAlphaValue:0];
+
+ [window makeKeyAndOrderFront:self];
+#if defined(BUILDING_ON_TIGER)
+ [window setAlphaValue:1];
+#else
+ [[window animator] setAlphaValue:1];
+#endif
+ [self scheduleTimeUpdate];
+
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(fadeWindowOut) object:nil];
+ if (!_mouseIsInHUD && [self playing]) // Don't fade out when paused.
+ [self performSelector:@selector(fadeWindowOut) withObject:nil afterDelay:HUDWindowFadeOutDelay];
+}
+
+- (void)fadeWindowOut
+{
+ [NSCursor setHiddenUntilMouseMoves:YES];
+#if defined(BUILDING_ON_TIGER)
+ [[self window] setAlphaValue:0];
+#else
+ [[[self window] animator] setAlphaValue:0];
+#endif
+ [self performSelector:@selector(unscheduleTimeUpdate) withObject:nil afterDelay:1];
+}
+
+- (void)closeWindow
+{
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(fadeWindowOut) object:nil];
+ [self unscheduleTimeUpdate];
+ NSWindow *window = [self window];
+#if !defined(BUILDING_ON_TIGER)
+ [[window contentView] removeTrackingArea:_area];
+ [self setArea:nil];
+#endif
+ [window close];
+ [window setDelegate:nil];
+ [self setWindow:nil];
+}
+
+#ifndef HAVE_MEDIA_CONTROL
+enum {
+ WKMediaUIControlPlayPauseButton,
+ WKMediaUIControlRewindButton,
+ WKMediaUIControlFastForwardButton,
+ WKMediaUIControlExitFullscreenButton,
+ WKMediaUIControlVolumeDownButton,
+ WKMediaUIControlSlider,
+ WKMediaUIControlVolumeUpButton,
+ WKMediaUIControlTimeline
+};
+#endif
+
+static NSControl *createControlWithMediaUIControlType(int controlType, NSRect frame)
+{
+#ifdef HAVE_MEDIA_CONTROL
+ NSControl *control = WKCreateMediaUIControl(controlType);
+ [control setFrame:frame];
+ return control;
+#else
+ if (controlType == WKMediaUIControlSlider)
+ return [[NSSlider alloc] initWithFrame:frame];
+ return [[NSControl alloc] initWithFrame:frame];
+#endif
+}
+
+static NSTextField *createTimeTextField(NSRect frame)
+{
+ NSTextField *textField = [[NSTextField alloc] initWithFrame:frame];
+ [textField setTextColor:[NSColor whiteColor]];
+ [textField setBordered:NO];
+ [textField setFont:[NSFont systemFontOfSize:10]];
+ [textField setDrawsBackground:NO];
+ [textField setBezeled:NO];
+ [textField setEditable:NO];
+ [textField setSelectable:NO];
+ return textField;
+}
+
+- (void)windowDidLoad
+{
+ static const CGFloat kMargin = 9;
+ static const CGFloat kMarginTop = 9;
+ static const CGFloat kButtonSize = 25;
+ static const CGFloat kButtonMiniSize = 16;
+
+ NSWindow *window = [self window];
+ ASSERT(window);
+
+#ifdef HAVE_MEDIA_CONTROL
+ NSView *background = WKCreateMediaUIBackgroundView();
+#else
+ NSView *background = [[NSView alloc] init];
+#endif
+ [window setContentView:background];
+#if !defined(BUILDING_ON_TIGER)
+ _area = [[NSTrackingArea alloc] initWithRect:[background bounds] options:NSTrackingMouseEnteredAndExited|NSTrackingActiveAlways owner:self userInfo:nil];
+ [background addTrackingArea:_area];
+#endif
+ [background release];
+
+ NSView *contentView = [[self window] contentView];
+
+ CGFloat top = windowHeight - kMarginTop;
+ CGFloat center = (windowWidth - kButtonSize) / 2;
+ _playButton = createControlWithMediaUIControlType(WKMediaUIControlPlayPauseButton, NSMakeRect(center, top - kButtonSize, kButtonSize, kButtonSize));
+ [_playButton setTarget:self];
+ [_playButton setAction:@selector(playingChanged:)];
+ [contentView addSubview:_playButton];
+
+ CGFloat closeToRight = windowWidth - 2 * kMargin - kButtonMiniSize;
+ NSControl *exitFullscreenButton = createControlWithMediaUIControlType(WKMediaUIControlExitFullscreenButton, NSMakeRect(closeToRight, top - kButtonSize / 2 - kButtonMiniSize / 2, kButtonMiniSize, kButtonMiniSize));
+ [exitFullscreenButton setAction:@selector(exitFullscreen:)];
+ [exitFullscreenButton setTarget:self];
+ [contentView addSubview:exitFullscreenButton];
+ [exitFullscreenButton release];
+
+ CGFloat left = kMargin;
+ NSControl *volumeDownButton = createControlWithMediaUIControlType(WKMediaUIControlVolumeDownButton, NSMakeRect(left, top - kButtonSize / 2 - kButtonMiniSize / 2, kButtonMiniSize, kButtonMiniSize));
+ [contentView addSubview:volumeDownButton];
+ [volumeDownButton release];
+
+ static const int volumeSliderWidth = 50;
+
+ left = kMargin + kButtonMiniSize;
+ _volumeSlider = createControlWithMediaUIControlType(WKMediaUIControlSlider, NSMakeRect(left, top - kButtonSize / 2 - kButtonMiniSize / 2, volumeSliderWidth, kButtonMiniSize));
+ [_volumeSlider setValue:[NSNumber numberWithDouble:[self maxVolume]] forKey:@"maxValue"];
+ [_volumeSlider setTarget:self];
+ [_volumeSlider setAction:@selector(volumeChanged:)];
+ [contentView addSubview:_volumeSlider];
+
+ left = kMargin + kButtonMiniSize + volumeSliderWidth + kButtonMiniSize / 2;
+ NSControl *button = createControlWithMediaUIControlType(WKMediaUIControlVolumeUpButton, NSMakeRect(left, top - kButtonSize / 2 - kButtonMiniSize / 2, kButtonMiniSize, kButtonMiniSize));
+ [contentView addSubview:button];
+ [button release];
+
+ static const int timeTextWidth = 50;
+ static const int sliderHeight = 13;
+ static const int sliderMarginFixup = 4;
+
+#ifdef HAVE_MEDIA_CONTROL
+ _timeline = WKCreateMediaUIControl(WKMediaUIControlTimeline);
+#else
+ _timeline = [[NSSlider alloc] init];
+#endif
+ [_timeline setTarget:self];
+ [_timeline setAction:@selector(timelinePositionChanged:)];
+ [_timeline setFrame:NSMakeRect(kMargin + timeTextWidth + kMargin/2, kMargin - sliderMarginFixup, windowWidth - 2 * (kMargin - sliderMarginFixup) - kMargin * 2 - 2 * timeTextWidth, sliderHeight)];
+ [contentView addSubview:_timeline];
+
+ static const int timeTextHeight = 11;
+
+ _elapsedTimeText = createTimeTextField(NSMakeRect(kMargin, kMargin, timeTextWidth, timeTextHeight));
+ [contentView addSubview:_elapsedTimeText];
+
+ _remainingTimeText = createTimeTextField(NSMakeRect(windowWidth - kMargin - timeTextWidth, kMargin, timeTextWidth, timeTextHeight));
+ [contentView addSubview:_remainingTimeText];
+
+ [window recalculateKeyViewLoop];
+ [window setInitialFirstResponder:_playButton];
+ [window center];
+}
+
+/*
+ * Bindings
+ *
+ */
+
+- (void)updateVolume
+{
+ [_volumeSlider setDoubleValue:[self volume]];
+}
+
+- (void)updateTime
+{
+ [self updateVolume];
+
+ [_timeline setFloatValue:[self currentTime]];
+ [(NSSlider*)_timeline setMaxValue:[self duration]];
+
+ [_remainingTimeText setStringValue:[self remainingTimeText]];
+ [_elapsedTimeText setStringValue:[self elapsedTimeText]];
+}
+
+- (void)fastForward
+{
+}
+
+- (void)timelinePositionChanged:(id)sender
+{
+ [self setCurrentTime:[_timeline floatValue]];
+}
+
+- (float)currentTime
+{
+ return [_delegate mediaElement] ? [_delegate mediaElement]->currentTime() : 0;
+}
+
+- (void)setCurrentTime:(float)currentTime
+{
+ if (![_delegate mediaElement])
+ return;
+ WebCore::ExceptionCode e;
+ [_delegate mediaElement]->setCurrentTime(currentTime, e);
+}
+
+- (double)duration
+{
+ return [_delegate mediaElement] ? [_delegate mediaElement]->duration() : 0;
+}
+
+- (double)maxVolume
+{
+ // Set the volume slider resolution
+ return 100;
+}
+
+- (void)volumeChanged:(id)sender
+{
+ [self setVolume:[_volumeSlider doubleValue]];
+}
+
+- (double)volume
+{
+ return [_delegate mediaElement] ? [_delegate mediaElement]->volume() * [self maxVolume] : 0;
+}
+
+- (void)setVolume:(double)volume
+{
+ if (![_delegate mediaElement])
+ return;
+ WebCore::ExceptionCode e;
+ [_delegate mediaElement]->setVolume(volume / [self maxVolume], e);
+}
+
+- (void)playingChanged:(id)sender
+{
+ [self setPlaying:![self playing]];
+
+ // Keep HUD visible when paused
+ if (![self playing])
+ [self fadeWindowIn];
+ else if (!_mouseIsInHUD) {
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(fadeWindowOut) object:nil];
+ [self performSelector:@selector(fadeWindowOut) withObject:nil afterDelay:HUDWindowFadeOutDelay];
+ }
+}
+
+- (BOOL)playing
+{
+ if (![_delegate mediaElement])
+ return false;
+ return ![_delegate mediaElement]->canPlay();
+}
+
+- (void)setPlaying:(BOOL)playing
+{
+ if (![_delegate mediaElement])
+ return;
+
+ if (playing)
+ [_delegate mediaElement]->play();
+ else
+ [_delegate mediaElement]->pause();
+}
+
+static NSString *timeToString(double time)
+{
+ if (!isfinite(time))
+ time = 0;
+ int seconds = (int)fabsf(time);
+ int hours = seconds / (60 * 60);
+ int minutes = (seconds / 60) % 60;
+ seconds %= 60;
+ if (hours) {
+ if (hours > 9)
+ return [NSString stringWithFormat:@"%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds];
+ else
+ return [NSString stringWithFormat:@"%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds];
+ }
+ else
+ return [NSString stringWithFormat:@"%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds];
+
+}
+
+static NSString *stringToTimeTextAttributed(NSString *string, NSTextAlignment align)
+{
+ NSShadow *blackShadow = [[NSShadow alloc] init];
+ [blackShadow setShadowColor:[NSColor blackColor]];
+ [blackShadow setShadowBlurRadius:0];
+ [blackShadow setShadowOffset:NSMakeSize(0, -1)];
+ NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
+ [style setAlignment:align];
+ NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:blackShadow, NSShadowAttributeName, style, NSParagraphStyleAttributeName, nil];
+ [style release];
+ [blackShadow release];
+
+ NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:string attributes:dict];
+ return [attrString autorelease];
+}
+
+- (NSString *)remainingTimeText
+{
+ if (![_delegate mediaElement])
+ return @"";
+
+ // Negative number
+ return stringToTimeTextAttributed(timeToString([_delegate mediaElement]->currentTime() - [_delegate mediaElement]->duration()), NSLeftTextAlignment);
+}
+
+- (NSString *)elapsedTimeText
+{
+ if (![_delegate mediaElement])
+ return @"";
+
+ return stringToTimeTextAttributed(timeToString([_delegate mediaElement]->currentTime()), NSRightTextAlignment);
+}
+
+/*
+ * Tracking area callbacks
+ *
+ */
+
+- (void)mouseEntered:(NSEvent *)theEvent
+{
+ // Make sure the HUD won't be hidden from now
+ _mouseIsInHUD = YES;
+ [self fadeWindowIn];
+}
+
+- (void)mouseExited:(NSEvent *)theEvent
+{
+ _mouseIsInHUD = NO;
+ [self fadeWindowIn];
+}
+
+/*
+ * Other Interface callbacks
+ *
+ */
+
+- (void)rewind:(id)sender
+{
+ if (![_delegate mediaElement])
+ return;
+ [_delegate mediaElement]->rewind(30);
+}
+
+- (void)fastForward:(id)sender
+{
+ if (![_delegate mediaElement])
+ return;
+}
+
+- (void)exitFullscreen:(id)sender
+{
+ [_delegate requestExitFullscreen];
+}
+
+/*
+ * Window callback
+ *
+ */
+
+- (void)windowDidExpose:(NSNotification *)notification
+{
+ [self scheduleTimeUpdate];
+}
+
+- (void)windowDidClose:(NSNotification *)notification
+{
+ [self unscheduleTimeUpdate];
+}
+
+@end
+
+#endif
diff --git a/WebKit/mac/WebView/WebView.mm b/WebKit/mac/WebView/WebView.mm
index 20f2712..83c7e20 100644
--- a/WebKit/mac/WebView/WebView.mm
+++ b/WebKit/mac/WebView/WebView.mm
@@ -84,6 +84,7 @@
#import "WebPanelAuthenticationHandler.h"
#import "WebPasteboardHelper.h"
#import "WebPluginDatabase.h"
+#import "WebPluginHalterClient.h"
#import "WebPolicyDelegate.h"
#import "WebPreferenceKeysPrivate.h"
#import "WebPreferencesPrivate.h"
@@ -93,6 +94,7 @@
#import "WebTextIterator.h"
#import "WebUIDelegate.h"
#import "WebUIDelegatePrivate.h"
+#import "WebVideoFullscreenController.h"
#import <CoreFoundation/CFSet.h>
#import <Foundation/NSURLConnection.h>
#import <WebCore/ApplicationCacheStorage.h>
@@ -619,7 +621,7 @@ static bool runningTigerMail()
didOneTimeInitialization = true;
}
- _private->page = new Page(new WebChromeClient(self), new WebContextMenuClient(self), new WebEditorClient(self), new WebDragClient(self), new WebInspectorClient(self));
+ _private->page = new Page(new WebChromeClient(self), new WebContextMenuClient(self), new WebEditorClient(self), new WebDragClient(self), new WebInspectorClient(self), new WebPluginHalterClient(self));
_private->page->settings()->setLocalStorageDatabasePath([[self preferences] _localStorageDatabasePath]);
@@ -661,11 +663,11 @@ static bool runningTigerMail()
if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_LOCAL_RESOURCE_SECURITY_RESTRICTION)) {
// Originally, we allowed all local loads.
- FrameLoader::setLocalLoadPolicy(FrameLoader::AllowLocalLoadsForAll);
+ SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForAll);
} else if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_MORE_STRICT_LOCAL_RESOURCE_SECURITY_RESTRICTION)) {
// Later, we allowed local loads for local URLs and documents loaded
// with substitute data.
- FrameLoader::setLocalLoadPolicy(FrameLoader::AllowLocalLoadsForLocalAndSubstituteData);
+ SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForLocalAndSubstituteData);
}
if (!WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_CONTENT_SNIFFING_FOR_FILE_URLS))
@@ -997,6 +999,8 @@ static bool fastDocumentTeardownEnabled()
return;
}
+ [self _exitFullscreen];
+
if (Frame* mainFrame = [self _mainCoreFrame])
mainFrame->loader()->detachFromParent();
@@ -1277,6 +1281,8 @@ static bool fastDocumentTeardownEnabled()
settings->setPluginsEnabled([preferences arePlugInsEnabled]);
settings->setDatabasesEnabled([preferences databasesEnabled]);
settings->setLocalStorageEnabled([preferences localStorageEnabled]);
+ settings->setExperimentalNotificationsEnabled([preferences experimentalNotificationsEnabled]);
+ settings->setExperimentalWebSocketsEnabled([preferences experimentalWebSocketsEnabled]);
settings->setPrivateBrowsingEnabled([preferences privateBrowsingEnabled]);
settings->setSansSerifFontFamily([preferences sansSerifFontFamily]);
settings->setSerifFontFamily([preferences serifFontFamily]);
@@ -1311,6 +1317,9 @@ static bool fastDocumentTeardownEnabled()
settings->setXSSAuditorEnabled([preferences isXSSAuditorEnabled]);
settings->setEnforceCSSMIMETypeInStrictMode(!WKAppVersionCheckLessThan(@"com.apple.iWeb", -1, 2.1));
settings->setAcceleratedCompositingEnabled([preferences acceleratedCompositingEnabled]);
+ settings->setPluginHalterEnabled([preferences pluginHalterEnabled]);
+ settings->setPluginAllowedRunTime([preferences pluginAllowedRunTime]);
+ settings->setWebGLEnabled([preferences webGLEnabled]);
}
static inline IMP getMethod(id o, SEL s)
@@ -1371,6 +1380,8 @@ static inline IMP getMethod(id o, SEL s)
cache->willCloseFrameFunc = getMethod(delegate, @selector(webView:willCloseFrame:));
cache->willPerformClientRedirectToURLDelayFireDateForFrameFunc = getMethod(delegate, @selector(webView:willPerformClientRedirectToURL:delay:fireDate:forFrame:));
cache->windowScriptObjectAvailableFunc = getMethod(delegate, @selector(webView:windowScriptObjectAvailable:));
+ cache->didDisplayInsecureContentFunc = getMethod(delegate, @selector(webViewDidDisplayInsecureContent:));
+ cache->didRunInsecureContentFunc = getMethod(delegate, @selector(webView:didRunInsecureContent:));
}
- (void)_cacheScriptDebugDelegateImplementations
@@ -1396,6 +1407,22 @@ static inline IMP getMethod(id o, SEL s)
cache->exceptionWasRaisedFunc = getMethod(delegate, @selector(webView:exceptionWasRaised:sourceId:line:forWebFrame:));
}
+- (void)_cacheHistoryDelegateImplementations
+{
+ WebHistoryDelegateImplementationCache *cache = &_private->historyDelegateImplementations;
+ id delegate = _private->historyDelegate;
+
+ if (!delegate) {
+ bzero(cache, sizeof(WebHistoryDelegateImplementationCache));
+ return;
+ }
+
+ cache->navigatedFunc = getMethod(delegate, @selector(webView:didNavigateWithNavigationData:inFrame:));
+ cache->clientRedirectFunc = getMethod(delegate, @selector(webView:didPerformClientRedirectFromURL:toURL:inFrame:));
+ cache->serverRedirectFunc = getMethod(delegate, @selector(webView:didPerformServerRedirectFromURL:toURL:inFrame:));
+ cache->setTitleFunc = getMethod(delegate, @selector(webView:updateHistoryTitle:forURL:));
+}
+
- (id)_policyDelegateForwarder
{
if (!_private->policyDelegateForwarder)
@@ -2092,6 +2119,15 @@ static inline IMP getMethod(id o, SEL s)
return _private ? _private->insertionPasteboard : nil;
}
++ (void)_whiteListAccessFromOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains
+{
+ SecurityOrigin::whiteListAccessFromOrigin(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
+}
+
++(void)_resetOriginAccessWhiteLists
+{
+ SecurityOrigin::resetOriginAccessWhiteLists();
+}
- (void)_updateActiveState
{
@@ -2099,6 +2135,108 @@ static inline IMP getMethod(id o, SEL s)
_private->page->focusController()->setActive([[self window] isKeyWindow]);
}
+static PassOwnPtr<Vector<String> > toStringVector(NSArray* patterns)
+{
+ // Convert the patterns into Vectors.
+ NSUInteger count = [patterns count];
+ if (count == 0)
+ return 0;
+ Vector<String>* patternsVector = new Vector<String>;
+ for (NSUInteger i = 0; i < count; ++i) {
+ id entry = [patterns objectAtIndex:i];
+ if ([entry isKindOfClass:[NSString class]])
+ patternsVector->append(String((NSString*)entry));
+ }
+ return patternsVector;
+}
+
++ (void)_addUserScriptToGroup:(NSString *)groupName source:(NSString *)source url:(NSURL *)url worldID:(unsigned)worldID
+ whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist injectionTime:(WebUserScriptInjectionTime)injectionTime
+{
+ String group(groupName);
+ if (group.isEmpty() || worldID == UINT_MAX)
+ return;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ if (!pageGroup)
+ return;
+
+ pageGroup->addUserScript(source, url, toStringVector(whitelist), toStringVector(blacklist), worldID,
+ injectionTime == WebInjectAtDocumentStart ? InjectAtDocumentStart : InjectAtDocumentEnd);
+}
+
++ (void)_addUserStyleSheetToGroup:(NSString *)groupName source:(NSString *)source url:(NSURL *)url worldID:(unsigned)worldID
+ whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist
+{
+ String group(groupName);
+ if (group.isEmpty() || worldID == UINT_MAX)
+ return;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ if (!pageGroup)
+ return;
+
+ pageGroup->addUserStyleSheet(source, url, toStringVector(whitelist), toStringVector(blacklist), worldID);
+}
+
++ (void)_removeUserContentFromGroup:(NSString *)groupName url:(NSURL *)url worldID:(unsigned)worldID
+{
+ String group(groupName);
+ if (group.isEmpty())
+ return;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ if (!pageGroup)
+ return;
+
+ pageGroup->removeUserContentWithURLForWorld(url, worldID);
+}
+
++ (void)_removeUserContentFromGroup:(NSString *)groupName worldID:(unsigned)worldID
+{
+ String group(groupName);
+ if (group.isEmpty())
+ return;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ if (!pageGroup)
+ return;
+
+ pageGroup->removeUserContentForWorld(worldID);
+}
+
++ (void)_removeAllUserContentFromGroup:(NSString *)groupName
+{
+ String group(groupName);
+ if (group.isEmpty())
+ return;
+
+ PageGroup* pageGroup = PageGroup::pageGroup(group);
+ if (!pageGroup)
+ return;
+
+ pageGroup->removeAllUserContent();
+}
+
+- (BOOL)cssAnimationsSuspended
+{
+ return _private->cssAnimationsSuspended;
+}
+
+- (void)setCSSAnimationsSuspended:(BOOL)suspended
+{
+ if (suspended == _private->cssAnimationsSuspended)
+ return;
+
+ _private->cssAnimationsSuspended = suspended;
+
+ Frame* frame = core([self mainFrame]);
+ if (suspended)
+ frame->animation()->suspendAnimations(frame->document());
+ else
+ frame->animation()->resumeAnimations(frame->document());
+}
+
@end
@implementation _WebSafeForwarder
@@ -3875,6 +4013,17 @@ done:
{
return _private->scriptDebugDelegate;
}
+
+- (void)setHistoryDelegate:(id)delegate
+{
+ _private->historyDelegate = delegate;
+ [self _cacheHistoryDelegateImplementations];
+}
+
+- (id)historyDelegate
+{
+ return _private->historyDelegate;
+}
- (BOOL)shouldClose
{
@@ -5091,13 +5240,16 @@ static WebFrameView *containingFrameView(NSView *view)
id documentView = [[[self selectedFrame] frameView] documentView];
if (![documentView conformsToProtocol:@protocol(WebDocumentText)])
return;
-
+
NSString *selectedString = [(id <WebDocumentText>)documentView selectedString];
- if ([selectedString length] == 0) {
+ if (![selectedString length])
return;
- }
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ [[NSWorkspace sharedWorkspace] showSearchResultsForQueryString:selectedString];
+#else
(void)HISearchWindowShow((CFStringRef)selectedString, kNilOptions);
+#endif
}
#if USE(ACCELERATED_COMPOSITING)
@@ -5469,6 +5621,45 @@ static void layerSyncRunLoopObserverCallBack(CFRunLoopObserverRef, CFRunLoopActi
#endif
+#if ENABLE(VIDEO)
+
+- (void)_enterFullscreenForNode:(WebCore::Node*)node
+{
+ ASSERT(node->hasTagName(WebCore::HTMLNames::videoTag));
+ HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(node);
+
+ if (_private->fullscreenController) {
+ if ([_private->fullscreenController mediaElement] == videoElement) {
+ // The backend may just warn us that the underlaying plaftormMovie()
+ // has changed. Just force an update.
+ [_private->fullscreenController setMediaElement:videoElement];
+ return; // No more to do.
+ }
+
+ // First exit Fullscreen for the old mediaElement.
+ [_private->fullscreenController mediaElement]->exitFullscreen();
+ // This previous call has to trigger _exitFullscreen,
+ // which has to clear _private->fullscreenController.
+ ASSERT(!_private->fullscreenController);
+ }
+ if (!_private->fullscreenController) {
+ _private->fullscreenController = [[WebVideoFullscreenController alloc] init];
+ [_private->fullscreenController setMediaElement:videoElement];
+ [_private->fullscreenController enterFullscreen:[[self window] screen]];
+ }
+ else
+ [_private->fullscreenController setMediaElement:videoElement];
+}
+
+- (void)_exitFullscreen
+{
+ [_private->fullscreenController exitFullscreen];
+ [_private->fullscreenController release];
+ _private->fullscreenController = nil;
+}
+
+#endif
+
@end
#ifdef BUILDING_ON_LEOPARD
diff --git a/WebKit/mac/WebView/WebViewData.h b/WebKit/mac/WebView/WebViewData.h
index 91d83a7..6ec94a7 100644
--- a/WebKit/mac/WebView/WebViewData.h
+++ b/WebKit/mac/WebView/WebViewData.h
@@ -43,6 +43,9 @@ namespace WebCore {
@class WebPreferences;
@class WebTextCompletionController;
@protocol WebFormDelegate;
+#if ENABLE(VIDEO)
+@class WebVideoFullscreenController;
+#endif
extern BOOL applicationIsTerminating;
extern int pluginDatabaseClientCount;
@@ -64,6 +67,7 @@ extern int pluginDatabaseClientCount;
id editingDelegate;
id editingDelegateForwarder;
id scriptDebugDelegate;
+ id historyDelegate;
WebInspector *inspector;
WebNodeHighlight *currentNodeHighlight;
@@ -86,6 +90,7 @@ extern int pluginDatabaseClientCount;
WebResourceDelegateImplementationCache resourceLoadDelegateImplementations;
WebFrameLoadDelegateImplementationCache frameLoadDelegateImplementations;
WebScriptDebugDelegateImplementationCache scriptDebugDelegateImplementations;
+ WebHistoryDelegateImplementationCache historyDelegateImplementations;
void *observationInfo;
@@ -100,6 +105,7 @@ extern int pluginDatabaseClientCount;
BOOL hoverFeedbackSuspended;
BOOL usesPageCache;
BOOL catchesDelegateExceptions;
+ BOOL cssAnimationsSuspended;
NSColor *backgroundColor;
@@ -157,5 +163,8 @@ extern int pluginDatabaseClientCount;
NSEvent *autoscrollTriggerEvent;
CFRunLoopTimerRef updateMouseoverTimer;
+#if ENABLE(VIDEO)
+ WebVideoFullscreenController *fullscreenController;
+#endif
}
@end
diff --git a/WebKit/mac/WebView/WebViewData.mm b/WebKit/mac/WebView/WebViewData.mm
index 48e7f6c..835f46e 100644
--- a/WebKit/mac/WebView/WebViewData.mm
+++ b/WebKit/mac/WebView/WebViewData.mm
@@ -57,6 +57,7 @@ int pluginDatabaseClientCount = 0;
allowsUndo = YES;
usesPageCache = YES;
shouldUpdateWhileOffscreen = YES;
+ cssAnimationsSuspended = NO;
zoomMultiplier = 1;
@@ -80,6 +81,7 @@ int pluginDatabaseClientCount = 0;
ASSERT(applicationIsTerminating || !page);
ASSERT(applicationIsTerminating || !preferences);
ASSERT(!insertionPasteboard);
+ ASSERT(!fullscreenController);
[applicationNameForUserAgent release];
[backgroundColor release];
@@ -99,6 +101,7 @@ int pluginDatabaseClientCount = 0;
{
ASSERT_MAIN_THREAD();
ASSERT(!insertionPasteboard);
+ ASSERT(!fullscreenController);
[super finalize];
}
diff --git a/WebKit/mac/WebView/WebViewInternal.h b/WebKit/mac/WebView/WebViewInternal.h
index b8266c5..521aeee 100644
--- a/WebKit/mac/WebView/WebViewInternal.h
+++ b/WebKit/mac/WebView/WebViewInternal.h
@@ -41,6 +41,7 @@ namespace WebCore {
class KURL;
class KeyboardEvent;
class Page;
+ class Node;
}
#endif
@@ -110,10 +111,6 @@ namespace WebCore {
- (id)_policyDelegateForwarder;
- (void)_pushPerformingProgrammaticFocus;
- (void)_popPerformingProgrammaticFocus;
-- (void)_incrementProgressForIdentifier:(id)identifier response:(NSURLResponse *)response;
-- (void)_incrementProgressForIdentifier:(id)identifier length:(int)length;
-- (void)_completeProgressForIdentifier:(id)identifer;
-- (void)_progressStarted:(WebFrame *)frame;
- (void)_didStartProvisionalLoadForFrame:(WebFrame *)frame;
+ (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType;
- (BOOL)_viewClass:(Class *)vClass andRepresentationClass:(Class *)rClass forMIMEType:(NSString *)MIMEType;
@@ -138,7 +135,6 @@ namespace WebCore {
- (void)_didChangeValueForKey:(NSString *)key;
- (WebBasePluginPackage *)_pluginForMIMEType:(NSString *)MIMEType;
- (WebBasePluginPackage *)_pluginForExtension:(NSString *)extension;
-- (BOOL)_isMIMETypeRegisteredAsPlugin:(NSString *)MIMEType;
- (void)setCurrentNodeHighlight:(WebNodeHighlight *)nodeHighlight;
- (WebNodeHighlight *)currentNodeHighlight;
@@ -168,4 +164,9 @@ namespace WebCore {
- (void)_setInsertionPasteboard:(NSPasteboard *)pasteboard;
+#if ENABLE(VIDEO) && defined(__cplusplus)
+- (void)_enterFullscreenForNode:(WebCore::Node*)node;
+- (void)_exitFullscreen;
+#endif
+
@end
diff --git a/WebKit/mac/WebView/WebViewPrivate.h b/WebKit/mac/WebView/WebViewPrivate.h
index 362b2e6..fa5d28c 100644
--- a/WebKit/mac/WebView/WebViewPrivate.h
+++ b/WebKit/mac/WebView/WebViewPrivate.h
@@ -76,6 +76,11 @@ typedef enum {
} WebDashboardBehavior;
#endif
+typedef enum {
+ WebInjectAtDocumentStart,
+ WebInjectAtDocumentEnd,
+} WebUserScriptInjectionTime;
+
@interface WebController : NSTreeController {
IBOutlet WebView *webView;
}
@@ -134,6 +139,20 @@ typedef enum {
*/
- (id)scriptDebugDelegate;
+/*!
+ @method setHistoryDelegate:
+ @abstract Set the WebView's WebHistoryDelegate delegate.
+ @param delegate The WebHistoryDelegate to set as the delegate.
+*/
+- (void)setHistoryDelegate:(id)delegate;
+
+/*!
+ @method historyDelegate
+ @abstract Return the WebView's WebHistoryDelegate delegate.
+ @result The WebView's WebHistoryDelegate delegate.
+*/
+- (id)historyDelegate;
+
- (BOOL)shouldClose;
/*!
@@ -443,6 +462,35 @@ Could be worth adding to the API.
// Which pasteboard text is coming from in editing delegate methods such as shouldInsertNode.
- (NSPasteboard *)_insertionPasteboard;
+// Whitelists access from an origin (sourceOrigin) to a set of one or more origins described by the parameters:
+// - destinationProtocol: The protocol to grant access to.
+// - destinationHost: The host to grant access to.
+// - allowDestinationSubdomains: If host is a domain, setting this to YES will whitelist host and all its subdomains, recursively.
++ (void)_whiteListAccessFromOrigin:(NSString *)sourceOrigin destinationProtocol:(NSString *)destinationProtocol destinationHost:(NSString *)destinationHost allowDestinationSubdomains:(BOOL)allowDestinationSubdomains;
+
+// Removes all white list entries created with _whiteListAccessFromOrigin.
++ (void)_resetOriginAccessWhiteLists;
+
++ (void)_addUserScriptToGroup:(NSString *)groupName source:(NSString *)source url:(NSURL *)url worldID:(unsigned)worldID whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist injectionTime:(WebUserScriptInjectionTime)injectionTime;
++ (void)_addUserStyleSheetToGroup:(NSString *)groupName source:(NSString *)source url:(NSURL *)url worldID:(unsigned)worldID whitelist:(NSArray *)whitelist blacklist:(NSArray *)blacklist;
++ (void)_removeUserContentFromGroup:(NSString *)groupName url:(NSURL *)url worldID:(unsigned)worldID;
++ (void)_removeUserContentFromGroup:(NSString *)groupName worldID:(unsigned)worldID;
++ (void)_removeAllUserContentFromGroup:(NSString *)groupName;
+
+/*!
+ @method cssAnimationsSuspended
+ @abstract Returns whether or not CSS Animations are suspended.
+ @result YES if CSS Animations are suspended.
+*/
+- (BOOL)cssAnimationsSuspended;
+
+/*!
+ @method setCSSAnimationsSuspended
+ @param paused YES to suspend animations, NO to resume animations.
+ @discussion Suspends or resumes all running animations and transitions in the page.
+*/
+- (void)setCSSAnimationsSuspended:(BOOL)suspended;
+
@end
@interface WebView (WebViewPrintingPrivate)
diff --git a/WebKit/mac/WebView/WebWindowAnimation.h b/WebKit/mac/WebView/WebWindowAnimation.h
new file mode 100644
index 0000000..c73dcce
--- /dev/null
+++ b/WebKit/mac/WebView/WebWindowAnimation.h
@@ -0,0 +1,59 @@
+/*
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 <Cocoa/Cocoa.h>
+
+@interface WebWindowScaleAnimation : NSAnimation {
+@private
+ NSRect _initialFrame, _finalFrame, _realFrame;
+ NSWindow *_window; // (assign)
+ NSAnimation *_subAnimation; // (retain)
+ NSTimeInterval _hintedDuration;
+}
+- (id)initWithHintedDuration:(NSTimeInterval)duration window:(NSWindow *)window initalFrame:(NSRect)initialFrame finalFrame:(NSRect)finalFrame;
+
+- (void)setSubAnimation:(NSAnimation *)animation;
+
+- (NSRect)currentFrame;
+
+// Be sure to call setWindow:nil to clear the weak link _window when appropriate
+- (void)setWindow:(NSWindow *)window;
+@end
+
+
+@interface WebWindowFadeAnimation : NSAnimation {
+@private
+ CGFloat _initialAlpha, _finalAlpha;
+ NSWindow *_window; // (retain)
+ BOOL _isStopped;
+
+}
+- (id)initWithDuration:(NSTimeInterval)duration window:(NSWindow *)window initialAlpha:(CGFloat)initialAlpha finalAlpha:(CGFloat)finalAlpha;
+
+- (CGFloat)currentAlpha;
+
+// Be sure to call setWindow:nil to clear the weak link _window when appropriate
+- (void)setWindow:(NSWindow *)window;
+@end
diff --git a/WebKit/mac/WebView/WebWindowAnimation.m b/WebKit/mac/WebView/WebWindowAnimation.m
new file mode 100644
index 0000000..3ab64bf
--- /dev/null
+++ b/WebKit/mac/WebView/WebWindowAnimation.m
@@ -0,0 +1,239 @@
+/*
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 "WebWindowAnimation.h"
+#import "WebKitSystemInterface.h"
+#import <wtf/Assertions.h>
+
+static const CGFloat slowMotionFactor = 10.;
+
+static NSTimeInterval WebWindowAnimationDurationFromDuration(NSTimeInterval duration)
+{
+ return ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) ? duration * slowMotionFactor : duration;
+}
+
+static NSRect scaledRect(NSRect _initialFrame, NSRect _finalFrame, double factor)
+{
+ NSRect currentRect = _initialFrame;
+ currentRect.origin.x += (NSMinX(_finalFrame) - NSMinX(_initialFrame)) * factor;
+ currentRect.origin.y += (NSMinY(_finalFrame) - NSMinY(_initialFrame)) * factor;
+ currentRect.size.width += (NSWidth(_finalFrame) - NSWidth(_initialFrame)) * factor;
+ currentRect.size.height += (NSHeight(_finalFrame) - NSHeight(_initialFrame)) * factor;
+ return currentRect;
+}
+
+static CGFloat squaredDistance(NSPoint point1, NSPoint point2)
+{
+ CGFloat deltaX = point1.x - point2.x;
+ CGFloat deltaY = point1.y - point2.y;
+ return deltaX * deltaX + deltaY * deltaY;
+}
+
+@implementation WebWindowScaleAnimation
+
+- (id)init
+{
+ self = [super init];
+ if (!self)
+ return nil;
+#ifndef BUILDING_ON_TIGER
+ [self setAnimationBlockingMode:NSAnimationNonblockingThreaded];
+#endif
+ [self setFrameRate:60.];
+ return self;
+}
+
+- (id)initWithHintedDuration:(NSTimeInterval)duration window:(NSWindow *)window initalFrame:(NSRect)initialFrame finalFrame:(NSRect)finalFrame
+{
+ self = [self init];
+ if (!self)
+ return nil;
+ _hintedDuration = duration;
+ _window = window;
+ _initialFrame = initialFrame;
+ _finalFrame = finalFrame;
+ _realFrame = [window frame];
+ return self;
+}
+
+- (void) dealloc
+{
+ [_window release];
+ [_subAnimation release];
+ [super dealloc];
+}
+
+- (void)setDuration:(NSTimeInterval)duration
+{
+ [super setDuration:WebWindowAnimationDurationFromDuration(duration)];
+}
+
+- (void)setWindow:(NSWindow *)window
+{
+ _window = window;
+}
+
+- (float)currentValue
+{
+ return 0.5 - 0.5 * cos(M_PI * (1 - [self currentProgress]));
+}
+
+- (NSRect)currentFrame
+{
+ return scaledRect(_finalFrame, _initialFrame, [self currentValue]);
+}
+
+- (void)setCurrentProgress:(NSAnimationProgress)progress
+{
+ if (!_window)
+ return;
+
+ [super setCurrentProgress:progress];
+
+ NSRect currentRect = [self currentFrame];
+#ifndef BUILDING_ON_TIGER
+ WKWindowSetScaledFrame(_window, currentRect, _realFrame);
+#else
+ [_window setFrame:currentRect display:YES];
+#endif
+ [_subAnimation setCurrentProgress:progress];
+}
+
+- (void)setSubAnimation:(NSAnimation *)animation
+{
+ id oldAnimation = _subAnimation;
+ _subAnimation = [animation retain];
+ [oldAnimation release];
+}
+
+- (NSTimeInterval)additionalDurationNeededToReachFinalFrame
+{
+ static const CGFloat maxAdditionalDuration = 1.0;
+ static const CGFloat speedFactor = 0.0001;
+
+ CGFloat maxDist = squaredDistance(_initialFrame.origin, _finalFrame.origin);
+ CGFloat dist;
+
+ dist = squaredDistance(NSMakePoint(NSMaxX(_initialFrame), NSMinY(_initialFrame)), NSMakePoint(NSMaxX(_finalFrame), NSMinY(_finalFrame)));
+ if (dist > maxDist)
+ maxDist = dist;
+
+ dist = squaredDistance(NSMakePoint(NSMaxX(_initialFrame), NSMaxY(_initialFrame)), NSMakePoint(NSMaxX(_finalFrame), NSMaxY(_finalFrame)));
+ if (dist > maxDist)
+ maxDist = dist;
+
+ dist = squaredDistance(NSMakePoint(NSMinX(_initialFrame), NSMinY(_initialFrame)), NSMakePoint(NSMinX(_finalFrame), NSMinY(_finalFrame)));
+ if (dist > maxDist)
+ maxDist = dist;
+
+ return MIN(sqrt(maxDist) * speedFactor, maxAdditionalDuration);
+}
+
+- (void)startAnimation
+{
+ // Compute extra time
+ if (_hintedDuration)
+ [self setDuration:_hintedDuration + [self additionalDurationNeededToReachFinalFrame]];
+ [super startAnimation];
+}
+
+- (void)stopAnimation
+{
+ _window = nil;
+ [super stopAnimation];
+ [_subAnimation stopAnimation];
+}
+
+@end
+
+@implementation WebWindowFadeAnimation
+
+- (id)init
+{
+ self = [super init];
+ if (!self)
+ return nil;
+#ifndef BUILDING_ON_TIGER
+ [self setAnimationBlockingMode:NSAnimationNonblockingThreaded];
+#endif
+ [self setFrameRate:60];
+ [self setAnimationCurve:NSAnimationEaseInOut];
+ return self;
+}
+
+- (id)initWithDuration:(NSTimeInterval)duration window:(NSWindow *)window initialAlpha:(CGFloat)initialAlpha finalAlpha:(CGFloat)finalAlpha
+{
+ self = [self init];
+ if (!self)
+ return nil;
+ _window = window;
+ _initialAlpha = initialAlpha;
+ _finalAlpha = finalAlpha;
+ return self;
+}
+
+- (void)setDuration:(NSTimeInterval)duration
+{
+ [super setDuration:WebWindowAnimationDurationFromDuration(duration)];
+}
+
+- (CGFloat)currentAlpha
+{
+ return MAX(0.0, MIN(1.0, _initialAlpha + [self currentValue] * (_finalAlpha - _initialAlpha)));
+}
+
+- (void)setCurrentProgress:(NSAnimationProgress)progress
+{
+ if (_isStopped)
+ return;
+
+ ASSERT(_window);
+ [super setCurrentProgress:progress];
+
+#ifndef BUILDING_ON_TIGER
+ WKWindowSetAlpha(_window, [self currentAlpha]);
+#else
+ [_window setAlphaValue:[self currentAlpha]];
+#endif
+}
+
+- (void)setWindow:(NSWindow*)window
+{
+ _window = window;
+}
+
+- (void)stopAnimation
+{
+ // This is relevant when we are a sub animation of a scale animation.
+ // In this case we are hosted in the animated thread of the parent
+ // and even after [super stopAnimation], the parent might call
+ // setCurrrentProgress.
+ _isStopped = YES;
+
+ [super stopAnimation];
+}
+
+@end
+