summaryrefslogtreecommitdiffstats
path: root/WebKitTools/DumpRenderTree/mac
diff options
context:
space:
mode:
Diffstat (limited to 'WebKitTools/DumpRenderTree/mac')
-rw-r--r--WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm6
-rw-r--r--WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm162
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig32
-rw-r--r--WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig4
-rw-r--r--WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm69
-rw-r--r--WebKitTools/DumpRenderTree/mac/EventSendingController.mm105
-rw-r--r--WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm160
-rw-r--r--WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm18
8 files changed, 478 insertions, 78 deletions
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
index 4d2da6e..9d7edef 100644
--- a/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityControllerMac.mm
@@ -40,6 +40,12 @@ AccessibilityController::~AccessibilityController()
{
}
+AccessibilityUIElement AccessibilityController::elementAtPoint(int x, int y)
+{
+ id accessibilityObject = [[[mainFrame frameView] documentView] accessibilityHitTest:NSMakePoint(x, y)];
+ return AccessibilityUIElement(accessibilityObject);
+}
+
AccessibilityUIElement AccessibilityController::focusedElement()
{
// FIXME: we could do some caching here.
diff --git a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
index e9361f2..a39dabb 100644
--- a/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/AccessibilityUIElementMac.mm
@@ -57,32 +57,11 @@ typedef void (*AXPostedNotificationCallback)(id element, NSString* notification,
@interface NSObject (WebKitAccessibilityAdditions)
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
-- (void)accessibilitySetPostedNotificationCallback:(AXPostedNotificationCallback)function withContext:(void*)context;
+- (void)accessibilitySetShouldRepostNotifications:(BOOL)repost;
- (NSUInteger)accessibilityIndexOfChild:(id)child;
+- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute;
@end
-AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
- : m_element(element)
- , m_notificationFunctionCallback(0)
-{
- [m_element retain];
-}
-
-AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
- : m_element(other.m_element)
- , m_notificationFunctionCallback(0)
-{
- [m_element retain];
-}
-
-AccessibilityUIElement::~AccessibilityUIElement()
-{
- // Make sure that our notification callback does not stick around.
- if (m_notificationFunctionCallback)
- [m_element accessibilitySetPostedNotificationCallback:0 withContext:0];
- [m_element release];
-}
-
@interface NSString (JSStringRefAdditions)
+ (NSString *)stringWithJSStringRef:(JSStringRef)jsStringRef;
- (JSStringRef)createJSStringRef;
@@ -106,6 +85,88 @@ AccessibilityUIElement::~AccessibilityUIElement()
@end
+@interface AccessibilityNotificationHandler : NSObject
+{
+ id m_platformElement;
+ JSObjectRef m_notificationFunctionCallback;
+}
+
+@end
+
+@implementation AccessibilityNotificationHandler
+
+- (id)initWithPlatformElement:(id)platformElement
+{
+ self = [super init];
+
+ m_platformElement = platformElement;
+
+ // Once an object starts requesting notifications, it's on for the duration of the program.
+ // This is to avoid any race conditions between tests turning this flag on and off. Instead
+ // AccessibilityNotificationHandler can just listen when they want to.
+ [m_platformElement accessibilitySetShouldRepostNotifications:YES];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_notificationReceived:) name:@"AXDRTNotification" object:nil];
+
+ return self;
+}
+
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback);
+ m_notificationFunctionCallback = 0;
+
+ [super dealloc];
+}
+
+- (void)_notificationReceived:(NSNotification *)notification
+{
+ NSString *notificationName = [[notification userInfo] objectForKey:@"notificationName"];
+ if (!notificationName)
+ return;
+
+ JSRetainPtr<JSStringRef> jsNotification(Adopt, [notificationName createJSStringRef]);
+ JSValueRef argument = JSValueMakeString([mainFrame globalContext], jsNotification.get());
+ JSObjectCallAsFunction([mainFrame globalContext], m_notificationFunctionCallback, 0, 1, &argument, 0);
+}
+
+- (void)setCallback:(JSObjectRef)callback
+{
+ if (!callback)
+ return;
+
+ // Release the old callback.
+ if (m_notificationFunctionCallback)
+ JSValueUnprotect([mainFrame globalContext], m_notificationFunctionCallback);
+
+ m_notificationFunctionCallback = callback;
+ JSValueProtect([mainFrame globalContext], m_notificationFunctionCallback);
+}
+
+@end
+
+AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element)
+ : m_element(element)
+ , m_notificationHandler(0)
+{
+ // FIXME: ap@webkit.org says ObjC objects need to be CFRetained/CFRelease to be GC-compliant on the mac.
+ [m_element retain];
+}
+
+AccessibilityUIElement::AccessibilityUIElement(const AccessibilityUIElement& other)
+ : m_element(other.m_element)
+ , m_notificationHandler(0)
+{
+ [m_element retain];
+}
+
+AccessibilityUIElement::~AccessibilityUIElement()
+{
+ // The notification handler should be nil because removeNotificationListener() should have been called in the test.
+ ASSERT(!m_notificationHandler);
+ [m_element release];
+}
+
static NSString* descriptionOfValue(id valueObject, id focusedAccessibilityObject)
{
if (!valueObject)
@@ -439,6 +500,12 @@ JSStringRef AccessibilityUIElement::language()
return concatenateAttributeAndValue(@"AXLanguage", description);
}
+JSStringRef AccessibilityUIElement::helpText() const
+{
+ id description = descriptionOfValue([m_element accessibilityAttributeValue:NSAccessibilityHelpAttribute], m_element);
+ return concatenateAttributeAndValue(@"AXHelp", description);
+}
+
double AccessibilityUIElement::x()
{
NSValue* positionValue = [m_element accessibilityAttributeValue:NSAccessibilityPositionAttribute];
@@ -676,6 +743,16 @@ JSStringRef AccessibilityUIElement::attributesOfHeader()
return descriptionOfElements(headerVector);
}
+int AccessibilityUIElement::rowCount()
+{
+ return [m_element accessibilityArrayAttributeCount:NSAccessibilityRowsAttribute];
+}
+
+int AccessibilityUIElement::columnCount()
+{
+ return [m_element accessibilityArrayAttributeCount:NSAccessibilityColumnsAttribute];
+}
+
int AccessibilityUIElement::indexInTable()
{
NSNumber* indexNumber = [m_element accessibilityAttributeValue:NSAccessibilityIndexAttribute];
@@ -736,6 +813,11 @@ void AccessibilityUIElement::showMenu()
[m_element accessibilityPerformAction:NSAccessibilityShowMenuAction];
}
+void AccessibilityUIElement::press()
+{
+ [m_element accessibilityPerformAction:NSAccessibilityPressAction];
+}
+
JSStringRef AccessibilityUIElement::accessibilityValue() const
{
// FIXME: implement
@@ -758,28 +840,30 @@ JSStringRef AccessibilityUIElement::url()
return [[url absoluteString] createJSStringRef];
}
-static void _accessibilityNotificationCallback(id element, NSString* notification, void* context)
-{
- if (!context)
- return;
-
- JSObjectRef functionCallback = static_cast<JSObjectRef>(context);
-
- JSRetainPtr<JSStringRef> jsNotification(Adopt, [notification createJSStringRef]);
- JSValueRef argument = JSValueMakeString([mainFrame globalContext], jsNotification.get());
- JSObjectCallAsFunction([mainFrame globalContext], functionCallback, NULL, 1, &argument, NULL);
-}
-
bool AccessibilityUIElement::addNotificationListener(JSObjectRef functionCallback)
{
if (!functionCallback)
return false;
- m_notificationFunctionCallback = functionCallback;
- [platformUIElement() accessibilitySetPostedNotificationCallback:_accessibilityNotificationCallback withContext:reinterpret_cast<void*>(m_notificationFunctionCallback)];
+ // Mac programmers should not be adding more than one notification listener per element.
+ // Other platforms may be different.
+ if (m_notificationHandler)
+ return false;
+ m_notificationHandler = [[AccessibilityNotificationHandler alloc] initWithPlatformElement:platformUIElement()];
+ [m_notificationHandler setCallback:functionCallback];
+
return true;
}
+void AccessibilityUIElement::removeNotificationListener()
+{
+ // Mac programmers should not be trying to remove a listener that's already removed.
+ ASSERT(m_notificationHandler);
+
+ [m_notificationHandler release];
+ m_notificationHandler = nil;
+}
+
bool AccessibilityUIElement::isSelectable() const
{
// FIXME: implement
@@ -812,7 +896,9 @@ bool AccessibilityUIElement::isCollapsed() const
bool AccessibilityUIElement::hasPopup() const
{
- // FIXME: implement
+ id value = [m_element accessibilityAttributeValue:@"AXHasPopup"];
+ if ([value isKindOfClass:[NSNumber class]])
+ return [value boolValue];
return false;
}
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
index a72dd7d..5f989e0 100644
--- a/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/Base.xcconfig
@@ -34,3 +34,35 @@ GCC_WARN_UNUSED_VARIABLE = YES
GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO
WARNING_CFLAGS = -Wall -W -Wno-unused-parameter
LINKER_DISPLAYS_MANGLED_NAMES = YES;
+
+
+TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR);
+
+
+// Use GCC 4.2 with Xcode 3.1, which includes GCC 4.2 but defaults to GCC 4.0.
+// Note that Xcode versions as new as 3.1.2 use XCODE_VERSION_ACTUAL for the minor version
+// number. Newer versions of Xcode use XCODE_VERSION_MINOR for the minor version, and
+// XCODE_VERSION_ACTUAL for the full version number.
+TARGET_GCC_VERSION = $(TARGET_GCC_VERSION_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+TARGET_GCC_VERSION_ = $(TARGET_GCC_VERSION_1040);
+TARGET_GCC_VERSION_1040 = GCC_40;
+TARGET_GCC_VERSION_1050 = $(TARGET_GCC_VERSION_1050_$(XCODE_VERSION_MINOR));
+TARGET_GCC_VERSION_1050_ = $(TARGET_GCC_VERSION_1050_$(XCODE_VERSION_ACTUAL));
+TARGET_GCC_VERSION_1050_0310 = GCC_42;
+TARGET_GCC_VERSION_1050_0320 = GCC_42;
+TARGET_GCC_VERSION_1060 = GCC_42;
+TARGET_GCC_VERSION_1070 = LLVM_GCC_42;
+
+GCC_VERSION = $(GCC_VERSION_$(TARGET_GCC_VERSION));
+GCC_VERSION_GCC_40 = 4.0;
+GCC_VERSION_GCC_42 = 4.2;
+GCC_VERSION_LLVM_GCC_42 = com.apple.compilers.llvmgcc42;
+
+// If the target Mac OS X version does not match the current Mac OS X version then we'll want to build using the target version's SDK.
+SDKROOT = $(SDKROOT_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+SDKROOT_1050_1040 = macosx10.4;
+SDKROOT_1060_1040 = macosx10.4;
+SDKROOT_1060_1050 = macosx10.5;
+SDKROOT_1070_1040 = macosx10.4;
+SDKROOT_1070_1050 = macosx10.5;
+SDKROOT_1070_1060 = macosx10.6;
diff --git a/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig b/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
index 96a39a9..ab3278e 100644
--- a/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
+++ b/WebKitTools/DumpRenderTree/mac/Configurations/DebugRelease.xcconfig
@@ -23,7 +23,7 @@
#include "Base.xcconfig"
-ARCHS = $(ARCHS_$(MAC_OS_X_VERSION_MAJOR));
+ARCHS = $(ARCHS_$(TARGET_MAC_OS_X_VERSION_MAJOR));
ARCHS_ = $(ARCHS_1040);
ARCHS_1040 = $(NATIVE_ARCH);
ARCHS_1050 = $(NATIVE_ARCH);
@@ -32,7 +32,7 @@ ARCHS_1070 = $(ARCHS_STANDARD_32_64_BIT);
ONLY_ACTIVE_ARCH = YES;
-MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(MAC_OS_X_VERSION_MAJOR))
+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(TARGET_MAC_OS_X_VERSION_MAJOR))
MACOSX_DEPLOYMENT_TARGET_ = 10.4;
MACOSX_DEPLOYMENT_TARGET_1040 = 10.4;
MACOSX_DEPLOYMENT_TARGET_1050 = 10.5;
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
index c7ddf21..0210cf0 100644
--- a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
@@ -76,15 +76,21 @@
#import <WebKit/WebTypesInternal.h>
#import <WebKit/WebViewPrivate.h>
#import <getopt.h>
-#import <mach-o/getsect.h>
#import <objc/objc-runtime.h>
#import <wtf/Assertions.h>
#import <wtf/RetainPtr.h>
#import <wtf/Threading.h>
#import <wtf/OwnPtr.h>
+extern "C" {
+#import <mach-o/getsect.h>
+}
+
using namespace std;
+@interface DumpRenderTreeApplication : NSApplication
+@end
+
@interface DumpRenderTreeEvent : NSEvent
@end
@@ -246,6 +252,7 @@ static void activateFonts()
static const char* fontFileNames[] = {
"AHEM____.TTF",
+ "ColorBits.ttf",
"WebKitWeightWatcher100.ttf",
"WebKitWeightWatcher200.ttf",
"WebKitWeightWatcher300.ttf",
@@ -355,7 +362,14 @@ void testStringByEvaluatingJavaScriptFromString()
static NSString *libraryPathForDumpRenderTree()
{
- return [@"~/Library/Application Support/DumpRenderTree" stringByExpandingTildeInPath];
+ //FIXME: This may not be sufficient to prevent interactions/crashes
+ //when running more than one copy of DumpRenderTree.
+ //See https://bugs.webkit.org/show_bug.cgi?id=10906
+ char* dumpRenderTreeTemp = getenv("DUMPRENDERTREE_TEMP");
+ if (dumpRenderTreeTemp)
+ return [[NSFileManager defaultManager] stringWithFileSystemRepresentation:dumpRenderTreeTemp length:strlen(dumpRenderTreeTemp)];
+ else
+ return [@"~/Library/Application Support/DumpRenderTree" stringByExpandingTildeInPath];
}
// Called before each test.
@@ -420,7 +434,7 @@ static void resetDefaultsToConsistentValues()
[preferences setOfflineWebApplicationCacheEnabled:YES];
[preferences setDeveloperExtrasEnabled:NO];
[preferences setLoadsImagesAutomatically:YES];
- [preferences setFrameSetFlatteningEnabled:NO];
+ [preferences setFrameFlatteningEnabled:NO];
if (persistentUserStyleSheetLocation) {
[preferences setUserStyleSheetLocation:[NSURL URLWithString:(NSString *)(persistentUserStyleSheetLocation.get())]];
[preferences setUserStyleSheetEnabled:YES];
@@ -430,20 +444,8 @@ static void resetDefaultsToConsistentValues()
// The back/forward cache is causing problems due to layouts during transition from one page to another.
// So, turn it off for now, but we might want to turn it back on some day.
[preferences setUsesPageCache:NO];
-
-#if defined(BUILDING_ON_LEOPARD)
- // Disable hardware composititing to avoid timeouts and crashes from buggy CoreVideo teardown code.
- // https://bugs.webkit.org/show_bug.cgi?id=28845 and rdar://problem/7228836
- SInt32 qtVersion;
- OSErr err = Gestalt(gestaltQuickTimeVersion, &qtVersion);
- assert(err == noErr);
- // Bug 7228836 exists in at least 7.6.3 through 7.6.4, hopefully it will be fixed in 7.6.5.
- // FIXME: Once we know the exact versions of QuickTime affected, we can update this check.
- if (qtVersion <= 0x07648000) // 7.6.4, final release (0x8). See http://developer.apple.com/mac/library/techn
- [preferences setAcceleratedCompositingEnabled:NO];
- else
-#endif
- [preferences setAcceleratedCompositingEnabled:YES];
+ [preferences setAcceleratedCompositingEnabled:YES];
+ [preferences setWebGLEnabled:NO];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain];
@@ -686,7 +688,7 @@ void dumpRenderTree(int argc, const char *argv[])
int main(int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- [NSApplication sharedApplication]; // Force AppKit to init itself
+ [DumpRenderTreeApplication sharedApplication]; // Force AppKit to init itself
dumpRenderTree(argc, argv);
[WebCoreStatistics garbageCollectJavaScriptObjects];
[WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts
@@ -1139,9 +1141,15 @@ static bool shouldOpenWebInspector(const char* pathOrURL)
return strstr(pathOrURL, "inspector/");
}
+static bool shouldEnableDeveloperExtras(const char* pathOrURL)
+{
+ return shouldOpenWebInspector(pathOrURL) || strstr(pathOrURL, "inspector-enabled/");
+}
+
static void resetWebViewToConsistentStateBeforeTesting()
{
WebView *webView = [mainFrame webView];
+ [webView setEditable:NO];
[(EditingDelegate *)[webView editingDelegate] setAcceptsEditing:YES];
[webView makeTextStandardSize:nil];
[webView resetPageZoom:nil];
@@ -1162,7 +1170,7 @@ static void resetWebViewToConsistentStateBeforeTesting()
[[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:NO];
[WebView _setUsesTestModeFocusRingColor:YES];
- [WebView _resetOriginAccessWhiteLists];
+ [WebView _resetOriginAccessWhitelists];
}
static void runTest(const string& testPathOrURL)
@@ -1217,8 +1225,11 @@ static void runTest(const string& testPathOrURL)
else
[[mainFrame webView] setHistoryDelegate:nil];
- if (shouldOpenWebInspector(pathOrURL.c_str()))
- gLayoutTestController->showWebInspector();
+ if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
+ gLayoutTestController->setDeveloperExtrasEnabled(true);
+ if (shouldOpenWebInspector(pathOrURL.c_str()))
+ gLayoutTestController->showWebInspector();
+ }
if ([WebHistory optionalSharedHistory])
[WebHistory setOptionalSharedHistory:nil];
@@ -1238,9 +1249,10 @@ static void runTest(const string& testPathOrURL)
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[mainFrame loadRequest:[NSURLRequest requestWithURL:url]];
[pool release];
+
while (!done) {
pool = [[NSAutoreleasePool alloc] init];
- [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
+ [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
[pool release];
}
@@ -1268,7 +1280,8 @@ static void runTest(const string& testPathOrURL)
}
}
- if (shouldOpenWebInspector(pathOrURL.c_str()))
+ // If developer extras enabled Web Inspector may have been open by the test.
+ if (shouldEnableDeveloperExtras(pathOrURL.c_str()))
gLayoutTestController->closeWebInspector();
resetWebViewToConsistentStateBeforeTesting();
@@ -1307,3 +1320,13 @@ void displayWebView()
}
@end
+
+@implementation DumpRenderTreeApplication
+
+- (BOOL)isRunning
+{
+ // <rdar://problem/7686123> Java plug-in freezes unless NSApplication is running
+ return YES;
+}
+
+@end
diff --git a/WebKitTools/DumpRenderTree/mac/EventSendingController.mm b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
index feaeddc..8c5cebf 100644
--- a/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
+++ b/WebKitTools/DumpRenderTree/mac/EventSendingController.mm
@@ -134,7 +134,9 @@ BOOL replayingSavedEvents;
|| aSelector == @selector(textZoomIn)
|| aSelector == @selector(textZoomOut)
|| aSelector == @selector(zoomPageIn)
- || aSelector == @selector(zoomPageOut))
+ || aSelector == @selector(zoomPageOut)
+ || aSelector == @selector(mouseScrollByX:andY:)
+ || aSelector == @selector(continuousMouseScrollByX:andY:))
return NO;
return YES;
}
@@ -166,6 +168,10 @@ BOOL replayingSavedEvents;
return @"mouseMoveTo";
if (aSelector == @selector(setDragMode:))
return @"setDragMode";
+ if (aSelector == @selector(mouseScrollByX:andY:))
+ return @"mouseScrollBy";
+ if (aSelector == @selector(continuousMouseScrollByX:andY:))
+ return @"continuousMouseScrollBy";
return nil;
}
@@ -453,6 +459,39 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
}
}
+- (void)mouseScrollByX:(int)x andY:(int)y continuously:(BOOL)c
+{
+ // CGEventCreateScrollWheelEvent() was introduced in 10.5
+#if !defined(BUILDING_ON_TIGER)
+ CGScrollEventUnit unit = c?kCGScrollEventUnitPixel:kCGScrollEventUnitLine;
+ CGEventRef cgScrollEvent = CGEventCreateScrollWheelEvent(NULL, unit, 2, y, x);
+
+ // CGEvent locations are in global display coordinates.
+ CGPoint lastGlobalMousePosition = {
+ lastMousePosition.x,
+ [[NSScreen mainScreen] frame].size.height - lastMousePosition.y
+ };
+ CGEventSetLocation(cgScrollEvent, lastGlobalMousePosition);
+
+ NSEvent *scrollEvent = [NSEvent eventWithCGEvent:cgScrollEvent];
+ CFRelease(cgScrollEvent);
+
+ NSView *subView = [[mainFrame webView] hitTest:[scrollEvent locationInWindow]];
+ if (subView)
+ [subView scrollWheel:scrollEvent];
+#endif
+}
+
+- (void)continuousMouseScrollByX:(int)x andY:(int)y
+{
+ [self mouseScrollByX:x andY:y continuously:YES];
+}
+
+- (void)mouseScrollByX:(int)x andY:(int)y
+{
+ [self mouseScrollByX:x andY:y continuously:NO];
+}
+
- (void)contextClick
{
[[[mainFrame frameView] documentView] layout];
@@ -507,33 +546,43 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
- (void)keyDown:(NSString *)character withModifiers:(WebScriptObject *)modifiers withLocation:(unsigned long)keyLocation
{
NSString *eventCharacter = character;
+ unsigned short keyCode = 0;
if ([character isEqualToString:@"leftArrow"]) {
const unichar ch = NSLeftArrowFunctionKey;
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ keyCode = 0x7B;
} else if ([character isEqualToString:@"rightArrow"]) {
const unichar ch = NSRightArrowFunctionKey;
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ keyCode = 0x7C;
} else if ([character isEqualToString:@"upArrow"]) {
const unichar ch = NSUpArrowFunctionKey;
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ keyCode = 0x7E;
} else if ([character isEqualToString:@"downArrow"]) {
const unichar ch = NSDownArrowFunctionKey;
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ keyCode = 0x7D;
} else if ([character isEqualToString:@"pageUp"]) {
const unichar ch = NSPageUpFunctionKey;
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ keyCode = 0x74;
} else if ([character isEqualToString:@"pageDown"]) {
const unichar ch = NSPageDownFunctionKey;
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ keyCode = 0x79;
} else if ([character isEqualToString:@"home"]) {
const unichar ch = NSHomeFunctionKey;
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ keyCode = 0x73;
} else if ([character isEqualToString:@"end"]) {
const unichar ch = NSEndFunctionKey;
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ keyCode = 0x77;
} else if ([character isEqualToString:@"delete"]) {
const unichar ch = 0x7f;
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ keyCode = 0x75;
}
// Compare the input string with the function-key names defined by the DOM spec (i.e. "F1",...,"F24").
@@ -542,9 +591,59 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
if ([character isEqualToString:[NSString stringWithFormat:@"F%u", i]]) {
const unichar ch = NSF1FunctionKey + (i - 1);
eventCharacter = [NSString stringWithCharacters:&ch length:1];
+ switch (i) {
+ case 1: keyCode = 0x7A; break;
+ case 2: keyCode = 0x78; break;
+ case 3: keyCode = 0x63; break;
+ case 4: keyCode = 0x76; break;
+ case 5: keyCode = 0x60; break;
+ case 6: keyCode = 0x61; break;
+ case 7: keyCode = 0x62; break;
+ case 8: keyCode = 0x64; break;
+ case 9: keyCode = 0x65; break;
+ case 10: keyCode = 0x6D; break;
+ case 11: keyCode = 0x67; break;
+ case 12: keyCode = 0x6F; break;
+ case 13: keyCode = 0x69; break;
+ case 14: keyCode = 0x6B; break;
+ case 15: keyCode = 0x71; break;
+ case 16: keyCode = 0x6A; break;
+ case 17: keyCode = 0x40; break;
+ case 18: keyCode = 0x4F; break;
+ case 19: keyCode = 0x50; break;
+ case 20: keyCode = 0x5A; break;
+ }
}
}
+ // FIXME: No keyCode is set for most keys.
+ if ([character isEqualToString:@"\t"])
+ keyCode = 0x30;
+ else if ([character isEqualToString:@" "])
+ keyCode = 0x31;
+ else if ([character isEqualToString:@"\r"])
+ keyCode = 0x24;
+ else if ([character isEqualToString:@"\n"])
+ keyCode = 0x4C;
+ else if ([character isEqualToString:@"\x8"])
+ keyCode = 0x33;
+ else if ([character isEqualToString:@"7"])
+ keyCode = 0x1A;
+ else if ([character isEqualToString:@"5"])
+ keyCode = 0x17;
+ else if ([character isEqualToString:@"9"])
+ keyCode = 0x19;
+ else if ([character isEqualToString:@"0"])
+ keyCode = 0x1D;
+ else if ([character isEqualToString:@"a"])
+ keyCode = 0x00;
+ else if ([character isEqualToString:@"b"])
+ keyCode = 0x0B;
+ else if ([character isEqualToString:@"d"])
+ keyCode = 0x02;
+ else if ([character isEqualToString:@"e"])
+ keyCode = 0x0E;
+
NSString *charactersIgnoringModifiers = eventCharacter;
int modifierFlags = 0;
@@ -570,7 +669,7 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
characters:eventCharacter
charactersIgnoringModifiers:charactersIgnoringModifiers
isARepeat:NO
- keyCode:0];
+ keyCode:keyCode];
[[[[mainFrame webView] window] firstResponder] keyDown:event];
@@ -583,7 +682,7 @@ static int buildModifierFlags(const WebScriptObject* modifiers)
characters:eventCharacter
charactersIgnoringModifiers:charactersIgnoringModifiers
isARepeat:NO
- keyCode:0];
+ keyCode:keyCode];
[[[[mainFrame webView] window] firstResponder] keyUp:event];
}
diff --git a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
index 66ba5f0..e62e411 100644
--- a/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
+++ b/WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
@@ -115,6 +115,11 @@ void LayoutTestController::addDisallowedURL(JSStringRef url)
CFSetAddValue(disallowedURLs, [request URL]);
}
+bool LayoutTestController::callShouldCloseOnWebView()
+{
+ return [[mainFrame webView] shouldClose];
+}
+
void LayoutTestController::clearAllDatabases()
{
[[WebDatabaseManager sharedWebDatabaseManager] deleteAllDatabases];
@@ -176,6 +181,23 @@ void LayoutTestController::keepWebHistory()
}
}
+JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
+{
+ return [[mainFrame webView] _computedStyleIncludingVisitedInfo:context forElement:value];
+}
+
+JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
+{
+ JSRetainPtr<JSStringRef> string(Adopt, JSStringCreateWithCFString((CFStringRef)[mainFrame _layerTreeAsText]));
+ return string;
+}
+
+JSRetainPtr<JSStringRef> LayoutTestController::markerTextForListItem(JSContextRef context, JSValueRef nodeObject) const
+{
+ // FIXME: Implement me.
+ return JSRetainPtr<JSStringRef>();
+}
+
int LayoutTestController::pageNumberForElementById(JSStringRef id, float pageWidthInPixels, float pageHeightInPixels)
{
RetainPtr<CFStringRef> idCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, id));
@@ -302,7 +324,7 @@ void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled)
void LayoutTestController::setJavaScriptProfilingEnabled(bool profilingEnabled)
{
- [[[mainFrame webView] preferences] setDeveloperExtrasEnabled:profilingEnabled];
+ setDeveloperExtrasEnabled(profilingEnabled);
[[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:profilingEnabled];
}
@@ -324,9 +346,14 @@ void LayoutTestController::setXSSAuditorEnabled(bool enabled)
[[[mainFrame webView] preferences] setXSSAuditorEnabled:enabled];
}
-void LayoutTestController::setFrameSetFlatteningEnabled(bool enabled)
+void LayoutTestController::setFrameFlatteningEnabled(bool enabled)
{
- [[[mainFrame webView] preferences] setFrameSetFlatteningEnabled:enabled];
+ [[[mainFrame webView] preferences] setFrameFlatteningEnabled:enabled];
+}
+
+void LayoutTestController::setSpatialNavigationEnabled(bool enabled)
+{
+ // FIXME: Implement for SpatialNavigation layout tests.
}
void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled)
@@ -424,7 +451,7 @@ void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag)
[[mainFrame webView] setSelectTrailingWhitespaceEnabled:flag];
}
-static const CFTimeInterval waitToDumpWatchdogInterval = 15.0;
+static const CFTimeInterval waitToDumpWatchdogInterval = 30.0;
static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
{
@@ -541,7 +568,7 @@ void LayoutTestController::waitForPolicyDelegate()
[[mainFrame webView] setPolicyDelegate:policyDelegate];
}
-void LayoutTestController::whiteListAccessFromOrigin(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
+void LayoutTestController::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
{
RetainPtr<CFStringRef> sourceOriginCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, sourceOrigin));
NSString *sourceOriginNS = (NSString *)sourceOriginCF.get();
@@ -549,7 +576,23 @@ void LayoutTestController::whiteListAccessFromOrigin(JSStringRef sourceOrigin, J
NSString *destinationProtocolNS = (NSString *)protocolCF.get();
RetainPtr<CFStringRef> hostCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, destinationHost));
NSString *destinationHostNS = (NSString *)hostCF.get();
- [WebView _whiteListAccessFromOrigin:sourceOriginNS destinationProtocol:destinationProtocolNS destinationHost:destinationHostNS allowDestinationSubdomains:allowDestinationSubdomains];
+ [WebView _addOriginAccessWhitelistEntryWithSourceOrigin:sourceOriginNS destinationProtocol:destinationProtocolNS destinationHost:destinationHostNS allowDestinationSubdomains:allowDestinationSubdomains];
+}
+
+void LayoutTestController::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
+{
+ RetainPtr<CFStringRef> sourceOriginCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, sourceOrigin));
+ NSString *sourceOriginNS = (NSString *)sourceOriginCF.get();
+ RetainPtr<CFStringRef> protocolCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, destinationProtocol));
+ NSString *destinationProtocolNS = (NSString *)protocolCF.get();
+ RetainPtr<CFStringRef> hostCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, destinationHost));
+ NSString *destinationHostNS = (NSString *)hostCF.get();
+ [WebView _removeOriginAccessWhitelistEntryWithSourceOrigin:sourceOriginNS destinationProtocol:destinationProtocolNS destinationHost:destinationHostNS allowDestinationSubdomains:allowDestinationSubdomains];
+}
+
+void LayoutTestController::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy)
+{
+ // FIXME: implement
}
void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart)
@@ -566,16 +609,19 @@ void LayoutTestController::addUserStyleSheet(JSStringRef source)
[WebView _addUserStyleSheetToGroup:@"org.webkit.DumpRenderTree" world:[WebScriptWorld world] source:sourceNS url:nil whitelist:nil blacklist:nil];
}
+void LayoutTestController::setDeveloperExtrasEnabled(bool enabled)
+{
+ [[[mainFrame webView] preferences] setDeveloperExtrasEnabled:enabled];
+}
+
void LayoutTestController::showWebInspector()
{
- [[[mainFrame webView] preferences] setDeveloperExtrasEnabled:true];
[[[mainFrame webView] inspector] show:nil];
}
void LayoutTestController::closeWebInspector()
{
[[[mainFrame webView] inspector] close:nil];
- [[[mainFrame webView] preferences] setDeveloperExtrasEnabled:false];
}
void LayoutTestController::evaluateInWebInspector(long callId, JSStringRef script)
@@ -686,3 +732,101 @@ void LayoutTestController::apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data,
[delegate release];
[pool release];
}
+
+void LayoutTestController::apiTestGoToCurrentBackForwardItem()
+{
+ WebView *view = [mainFrame webView];
+ [view goToBackForwardItem:[[view backForwardList] currentItem]];
+}
+
+void LayoutTestController::setWebViewEditable(bool editable)
+{
+ WebView *view = [mainFrame webView];
+ [view setEditable:editable];
+}
+
+#ifndef BUILDING_ON_TIGER
+static NSString *SynchronousLoaderRunLoopMode = @"DumpRenderTreeSynchronousLoaderRunLoopMode";
+
+@interface SynchronousLoader : NSObject
+{
+ NSString *m_username;
+ NSString *m_password;
+ BOOL m_isDone;
+}
++ (void)makeRequest:(NSURLRequest *)request withUsername:(NSString *)username password:(NSString *)password;
+@end
+
+@implementation SynchronousLoader : NSObject
+- (void)dealloc
+{
+ [m_username release];
+ [m_password release];
+
+ [super dealloc];
+}
+
+- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
+{
+ return YES;
+}
+
+- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
+{
+ if ([challenge previousFailureCount] == 0) {
+ NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:m_username password:m_password persistence:NSURLCredentialPersistenceForSession];
+ [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
+ return;
+ }
+ [[challenge sender] cancelAuthenticationChallenge:challenge];
+}
+
+- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
+{
+ printf("SynchronousLoader failed: %s\n", [[error description] UTF8String]);
+ m_isDone = YES;
+}
+
+- (void)connectionDidFinishLoading:(NSURLConnection *)connection
+{
+ m_isDone = YES;
+}
+
++ (void)makeRequest:(NSURLRequest *)request withUsername:(NSString *)username password:(NSString *)password
+{
+ ASSERT(![[request URL] user]);
+ ASSERT(![[request URL] password]);
+
+ SynchronousLoader *delegate = [[SynchronousLoader alloc] init];
+ delegate->m_username = [username copy];
+ delegate->m_password = [password copy];
+
+ NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate startImmediately:NO];
+ [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:SynchronousLoaderRunLoopMode];
+ [connection start];
+
+ while (!delegate->m_isDone)
+ [[NSRunLoop currentRunLoop] runMode:SynchronousLoaderRunLoopMode beforeDate:[NSDate distantFuture]];
+
+ [connection cancel];
+
+ [connection release];
+ [delegate release];
+}
+
+@end
+#endif
+
+void LayoutTestController::authenticateSession(JSStringRef url, JSStringRef username, JSStringRef password)
+{
+ // See <rdar://problem/7880699>.
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+ RetainPtr<CFStringRef> urlStringCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
+ RetainPtr<CFStringRef> usernameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, username));
+ RetainPtr<CFStringRef> passwordCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, password));
+
+ NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:(NSString *)urlStringCF.get()]];
+
+ [SynchronousLoader makeRequest:request withUsername:(NSString *)usernameCF.get() password:(NSString *)passwordCF.get()];
+#endif
+}
diff --git a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
index 6f82e01..9244110 100644
--- a/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
+++ b/WebKitTools/DumpRenderTree/mac/ResourceLoadDelegate.mm
@@ -35,6 +35,8 @@
#import <WebKit/WebTypesInternal.h>
#import <wtf/Assertions.h>
+using namespace std;
+
@interface NSURL (DRTExtras)
- (NSString *)_drt_descriptionSuitableForTestResult;
@end
@@ -121,10 +123,10 @@
return @"<unknown>";
}
--(NSURLRequest *)webView: (WebView *)wv resource:identifier willSendRequest: (NSURLRequest *)newRequest redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
+-(NSURLRequest *)webView: (WebView *)wv resource:identifier willSendRequest: (NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
{
if (!done && gLayoutTestController->dumpResourceLoadCallbacks()) {
- NSString *string = [NSString stringWithFormat:@"%@ - willSendRequest %@ redirectResponse %@", identifier, [newRequest _drt_descriptionSuitableForTestResult],
+ NSString *string = [NSString stringWithFormat:@"%@ - willSendRequest %@ redirectResponse %@", identifier, [request _drt_descriptionSuitableForTestResult],
[redirectResponse _drt_descriptionSuitableForTestResult]];
printf("%s\n", [string UTF8String]);
}
@@ -137,7 +139,7 @@
return nil;
}
- NSURL *url = [newRequest URL];
+ NSURL *url = [request URL];
NSString *host = [url host];
if (host
&& (NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"http"] || NSOrderedSame == [[url scheme] caseInsensitiveCompare:@"https"])
@@ -151,7 +153,15 @@
if (disallowedURLs && CFSetContainsValue(disallowedURLs, url))
return nil;
- return newRequest;
+ NSMutableURLRequest *newRequest = [request mutableCopy];
+ const set<string>& clearHeaders = gLayoutTestController->willSendRequestClearHeaders();
+ for (set<string>::const_iterator header = clearHeaders.begin(); header != clearHeaders.end(); ++header) {
+ NSString *nsHeader = [[NSString alloc] initWithUTF8String:header->c_str()];
+ [newRequest setValue:nil forHTTPHeaderField:nsHeader];
+ [nsHeader release];
+ }
+
+ return [newRequest autorelease];
}
- (void)webView:(WebView *)wv resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)dataSource