+2007-11-21 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Tim Hatcher.
+
+ Pull DumpRenderTreeWindow and DumpRenderTreePasteboard out into their own files
+
+ * DumpRenderTree/DumpRenderTree.h:
+ * DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj:
+ * DumpRenderTree/mac/DumpRenderTree.mm:
+ (dumpRenderTree):
+ (dump):
+ (runTest):
+ * DumpRenderTree/mac/DumpRenderTreePasteboard.h: Added.
+ * DumpRenderTree/mac/DumpRenderTreePasteboard.m: Added.
+ (+[DumpRenderTreePasteboard _pasteboardWithName:]):
+ (+[DumpRenderTreePasteboard releaseLocalPasteboards]):
+ (-[DumpRenderTreePasteboard declareType:owner:]):
+ (+[LocalPasteboard alloc]):
+ (-[LocalPasteboard init]):
+ (-[LocalPasteboard dealloc]):
+ (-[LocalPasteboard name]):
+ (-[LocalPasteboard releaseGlobally]):
+ (-[LocalPasteboard declareTypes:owner:]):
+ (-[LocalPasteboard addTypes:owner:]):
+ (-[LocalPasteboard changeCount]):
+ (-[LocalPasteboard types]):
+ (-[LocalPasteboard availableTypeFromArray:]):
+ (-[LocalPasteboard setData:forType:]):
+ (-[LocalPasteboard dataForType:]):
+ (-[LocalPasteboard setPropertyList:forType:]):
+ (-[LocalPasteboard setString:forType:]):
+ * DumpRenderTree/mac/DumpRenderTreeWindow.h: Added.
+ * DumpRenderTree/mac/DumpRenderTreeWindow.mm: Added.
+ (+[DumpRenderTreeWindow allWindows]):
+ (-[DumpRenderTreeWindow initWithContentRect:styleMask:backing:defer:]):
+ (-[DumpRenderTreeWindow dealloc]):
+ (-[DumpRenderTreeWindow isKeyWindow]):
+ (-[DumpRenderTreeWindow keyDown:]):
+
2007-11-20 Kevin Ollivier <kevino@theolliviers.com>
wx build fix for Windows. Don't use WebCore/move-js-headers.sh as
extern volatile bool done;
extern CFRunLoopTimerRef waitToDumpWatchdog;
+
+// FIXME: This is a bad abstraction. We should insted pass this to other controller objects which need access to it.
extern LayoutTestController* layoutTestController;
void dump();
A817090008B163EF00CCB9FB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A84F608908B136DA00E9745F /* Cocoa.framework */; };
A817090408B164D300CCB9FB /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A817090308B164D300CCB9FB /* JavaScriptCore.framework */; };
A84F608A08B136DA00E9745F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A84F608908B136DA00E9745F /* Cocoa.framework */; };
+ A8B91ADA0CF3B32F008F91FF /* DumpRenderTreePasteboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A8B91AD70CF3B32F008F91FF /* DumpRenderTreePasteboard.m */; };
+ A8B91ADC0CF3B32F008F91FF /* DumpRenderTreeWindow.mm in Sources */ = {isa = PBXBuildFile; fileRef = A8B91AD90CF3B32F008F91FF /* DumpRenderTreeWindow.mm */; };
+ A8B91AE00CF3B372008F91FF /* DumpRenderTreeWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B91ADD0CF3B372008F91FF /* DumpRenderTreeWindow.h */; };
+ A8B91AE20CF3B372008F91FF /* DumpRenderTreePasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A8B91ADF0CF3B372008F91FF /* DumpRenderTreePasteboard.h */; };
AE8259F308D22463000507AB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE8257EF08D22389000507AB /* Carbon.framework */; };
AE8259F408D22463000507AB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE8257EF08D22389000507AB /* Carbon.framework */; };
B5A752A208AF5D1F00138E45 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5A752A108AF5D1F00138E45 /* QuartzCore.framework */; };
A803FF7409CAAD08009B2A37 /* DumpRenderTree.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = DumpRenderTree.h; sourceTree = "<group>"; };
A817090308B164D300CCB9FB /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = JavaScriptCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
A84F608908B136DA00E9745F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ A8B91AD70CF3B32F008F91FF /* DumpRenderTreePasteboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DumpRenderTreePasteboard.m; path = mac/DumpRenderTreePasteboard.m; sourceTree = "<group>"; };
+ A8B91AD90CF3B32F008F91FF /* DumpRenderTreeWindow.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = DumpRenderTreeWindow.mm; path = mac/DumpRenderTreeWindow.mm; sourceTree = "<group>"; };
+ A8B91ADD0CF3B372008F91FF /* DumpRenderTreeWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreeWindow.h; path = mac/DumpRenderTreeWindow.h; sourceTree = "<group>"; };
+ A8B91ADF0CF3B372008F91FF /* DumpRenderTreePasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpRenderTreePasteboard.h; path = mac/DumpRenderTreePasteboard.h; sourceTree = "<group>"; };
AA7F10C20CB3C1030003BDC9 /* AHEM____.TTF */ = {isa = PBXFileReference; lastKnownFileType = file; name = "AHEM____.TTF"; path = "qt/fonts/AHEM____.TTF"; sourceTree = "<group>"; };
AE8257EF08D22389000507AB /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
B5A7526708AF4A4A00138E45 /* ImageDiff */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ImageDiff; sourceTree = BUILT_PRODUCTS_DIR; };
A803FF7409CAAD08009B2A37 /* DumpRenderTree.h */,
BCA18C460C9B5B9400114369 /* DumpRenderTree.mm */,
BCA18C0A0C9B59EF00114369 /* DumpRenderTreeMac.h */,
+ A8B91AD20CF3B305008F91FF /* AppKit Overrides */,
BCA18B730C9B08F100114369 /* DumpRenderTreeDraggingInfo.h */,
BCA18B740C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm */,
BCA18B750C9B08F100114369 /* ImageDiff.m */,
- BCA18B760C9B08F100114369 /* ObjCPlugin.h */,
- BCA18B770C9B08F100114369 /* ObjCPlugin.m */,
- BCA18B780C9B08F100114369 /* ObjCPluginFunction.h */,
- BCA18B790C9B08F100114369 /* ObjCPluginFunction.m */,
+ A8B91AC40CF3B170008F91FF /* ObjCPlugin */,
BC9D90210C97472D0099A4A3 /* WorkQueue.cpp */,
BC9D90220C97472E0099A4A3 /* WorkQueue.h */,
BC9D90230C97472E0099A4A3 /* WorkQueueItem.h */,
name = Frameworks;
sourceTree = "<group>";
};
+ A8B91AC40CF3B170008F91FF /* ObjCPlugin */ = {
+ isa = PBXGroup;
+ children = (
+ BCA18B760C9B08F100114369 /* ObjCPlugin.h */,
+ BCA18B770C9B08F100114369 /* ObjCPlugin.m */,
+ BCA18B780C9B08F100114369 /* ObjCPluginFunction.h */,
+ BCA18B790C9B08F100114369 /* ObjCPluginFunction.m */,
+ );
+ name = ObjCPlugin;
+ sourceTree = "<group>";
+ };
+ A8B91AD20CF3B305008F91FF /* AppKit Overrides */ = {
+ isa = PBXGroup;
+ children = (
+ A8B91ADF0CF3B372008F91FF /* DumpRenderTreePasteboard.h */,
+ A8B91AD70CF3B32F008F91FF /* DumpRenderTreePasteboard.m */,
+ A8B91ADD0CF3B372008F91FF /* DumpRenderTreeWindow.h */,
+ A8B91AD90CF3B32F008F91FF /* DumpRenderTreeWindow.mm */,
+ );
+ name = "AppKit Overrides";
+ sourceTree = "<group>";
+ };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
BCA18B690C9B08C200114369 /* UIDelegate.h in Headers */,
BC9D90250C97472E0099A4A3 /* WorkQueue.h in Headers */,
BC9D90260C97472E0099A4A3 /* WorkQueueItem.h in Headers */,
+ A8B91AE00CF3B372008F91FF /* DumpRenderTreeWindow.h in Headers */,
+ A8B91AE20CF3B372008F91FF /* DumpRenderTreePasteboard.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
BCA18B6A0C9B08C200114369 /* UIDelegate.mm in Sources */,
BC9D90240C97472E0099A4A3 /* WorkQueue.cpp in Sources */,
BCA18B260C9B015C00114369 /* WorkQueueItemMac.mm in Sources */,
+ A8B91ADA0CF3B32F008F91FF /* DumpRenderTreePasteboard.m in Sources */,
+ A8B91ADC0CF3B32F008F91FF /* DumpRenderTreeWindow.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
#import "DumpRenderTree.h"
+#import "DumpRenderTreePasteboard.h"
+#import "DumpRenderTreeWindow.h"
#import "EditingDelegate.h"
#import "EventSendingController.h"
#import "FrameLoadDelegate.h"
#define COMMON_DIGEST_FOR_OPENSSL
#import <CommonCrypto/CommonDigest.h> // for MD5 functions
-@interface DumpRenderTreeWindow : NSWindow
-@end
-
-@interface DumpRenderTreePasteboard : NSPasteboard
-- (int)declareType:(NSString *)type owner:(id)newOwner;
-@end
-
@interface DumpRenderTreeEvent : NSEvent
@end
-@interface LocalPasteboard : NSPasteboard
-{
- NSMutableArray *typesArray;
- NSMutableSet *typesSet;
- NSMutableDictionary *dataByType;
- int changeCount;
-}
-@end
-
static void runTest(const char *pathOrURL);
static NSString *md5HashStringForBitmap(CGImageRef bitmap);
WebFrame *topLoadingFrame = nil; // !nil iff a load is in progress
-CFMutableArrayRef allWindowsRef = 0;
CFMutableSetRef disallowedURLs = 0;
CFRunLoopTimerRef waitToDumpWatchdog = 0;
static BOOL printSeparators;
static NSString *currentTest = nil;
-static NSMutableDictionary *localPasteboards;
static WebHistoryItem *prevTestBFItem = nil; // current b/f item at the end of the previous test
static unsigned char* screenCaptureBuffer;
static CGColorSpaceRef sharedColorSpace;
sharedColorSpace = CGColorSpaceCreateDeviceRGB();
}
- localPasteboards = [[NSMutableDictionary alloc] init];
navigationController = [[NavigationController alloc] init];
frameLoadDelegate = [[FrameLoadDelegate alloc] init];
uiDelegate = [[UIDelegate alloc] init];
[uiDelegate release];
[policyDelegate release];
- [localPasteboards release];
- localPasteboards = nil;
+ [DumpRenderTreePasteboard releaseLocalPasteboards];
[navigationController release];
navigationController = nil;
}
if (layoutTestController->dumpBackForwardList()) {
- unsigned count = CFArrayGetCount(allWindowsRef);
+ CFArrayRef allWindows = (CFArrayRef)[DumpRenderTreeWindow allWindows];
+ unsigned count = CFArrayGetCount(allWindows);
for (unsigned i = 0; i < count; i++) {
- NSWindow *window = (NSWindow *)CFArrayGetValueAtIndex(allWindowsRef, i);
+ NSWindow *window = (NSWindow *)CFArrayGetValueAtIndex(allWindows, i);
WebView *webView = [[[window contentView] subviews] objectAtIndex:0];
dumpBackForwardListForWebView(webView);
}
WorkQueue::shared()->clear();
if (layoutTestController->closeRemainingWindowsWhenComplete()) {
- NSArray* array = [(NSArray *)allWindowsRef copy];
+ NSArray* array = [DumpRenderTreeWindow allWindows];
unsigned count = [array count];
for (unsigned i = 0; i < count; i++) {
[webView close];
[window close];
}
- [array release];
}
[pool release];
[webView unlockFocus];
}
-@implementation DumpRenderTreePasteboard
-
-// Return a local pasteboard so we don't disturb the real pasteboards when running tests.
-+ (NSPasteboard *)_pasteboardWithName:(NSString *)name
-{
- static int number = 0;
- if (!name)
- name = [NSString stringWithFormat:@"LocalPasteboard%d", ++number];
- LocalPasteboard *pasteboard = [localPasteboards objectForKey:name];
- if (pasteboard)
- return pasteboard;
- pasteboard = [[LocalPasteboard alloc] init];
- [localPasteboards setObject:pasteboard forKey:name];
- [pasteboard release];
- return pasteboard;
-}
-
-// Convenience method for JS so that it doesn't have to try and create a NSArray on the objc side instead
-// of the usual WebScriptObject that is passed around
-- (int)declareType:(NSString *)type owner:(id)newOwner
-{
- return [self declareTypes:[NSArray arrayWithObject:type] owner:newOwner];
-}
-
-@end
-
-@implementation LocalPasteboard
-
-+ (id)alloc
-{
- return NSAllocateObject(self, 0, 0);
-}
-
-- (id)init
-{
- typesArray = [[NSMutableArray alloc] init];
- typesSet = [[NSMutableSet alloc] init];
- dataByType = [[NSMutableDictionary alloc] init];
- return self;
-}
-
-- (void)dealloc
-{
- [typesArray release];
- [typesSet release];
- [dataByType release];
- [super dealloc];
-}
-
-- (NSString *)name
-{
- return nil;
-}
-
-- (void)releaseGlobally
-{
-}
-
-- (int)declareTypes:(NSArray *)newTypes owner:(id)newOwner
-{
- [typesArray removeAllObjects];
- [typesSet removeAllObjects];
- [dataByType removeAllObjects];
- return [self addTypes:newTypes owner:newOwner];
-}
-
-- (int)addTypes:(NSArray *)newTypes owner:(id)newOwner
-{
- unsigned count = [newTypes count];
- unsigned i;
- for (i = 0; i < count; ++i) {
- NSString *type = [newTypes objectAtIndex:i];
- NSString *setType = [typesSet member:type];
- if (!setType) {
- setType = [type copy];
- [typesArray addObject:setType];
- [typesSet addObject:setType];
- [setType release];
- }
- if (newOwner && [newOwner respondsToSelector:@selector(pasteboard:provideDataForType:)])
- [newOwner pasteboard:self provideDataForType:setType];
- }
- return ++changeCount;
-}
-
-- (int)changeCount
-{
- return changeCount;
-}
-
-- (NSArray *)types
-{
- return typesArray;
-}
-
-- (NSString *)availableTypeFromArray:(NSArray *)types
-{
- unsigned count = [types count];
- unsigned i;
- for (i = 0; i < count; ++i) {
- NSString *type = [types objectAtIndex:i];
- NSString *setType = [typesSet member:type];
- if (setType)
- return setType;
- }
- return nil;
-}
-
-- (BOOL)setData:(NSData *)data forType:(NSString *)dataType
-{
- if (data == nil)
- data = [NSData data];
- if (![typesSet containsObject:dataType])
- return NO;
- [dataByType setObject:data forKey:dataType];
- ++changeCount;
- return YES;
-}
-
-- (NSData *)dataForType:(NSString *)dataType
-{
- return [dataByType objectForKey:dataType];
-}
-
-- (BOOL)setPropertyList:(id)propertyList forType:(NSString *)dataType;
-{
- CFDataRef data = NULL;
- if (propertyList)
- data = CFPropertyListCreateXMLData(NULL, propertyList);
- BOOL result = [self setData:(NSData *)data forType:dataType];
- if (data)
- CFRelease(data);
- return result;
-}
-
-- (BOOL)setString:(NSString *)string forType:(NSString *)dataType
-{
- CFDataRef data = NULL;
- if (string) {
- if ([string length] == 0)
- data = CFDataCreate(NULL, NULL, 0);
- else
- data = CFStringCreateExternalRepresentation(NULL, (CFStringRef)string, kCFStringEncodingUTF8, 0);
- }
- BOOL result = [self setData:(NSData *)data forType:dataType];
- if (data)
- CFRelease(data);
- return result;
-}
-
-@end
-
-static CFArrayCallBacks NonRetainingArrayCallbacks = {
- 0,
- NULL,
- NULL,
- CFCopyDescription,
- CFEqual
-};
-
-@implementation DumpRenderTreeWindow
-
-- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
-{
- if (!allWindowsRef)
- allWindowsRef = CFArrayCreateMutable(NULL, 0, &NonRetainingArrayCallbacks);
-
- CFArrayAppendValue(allWindowsRef, self);
-
- return [super initWithContentRect:contentRect styleMask:styleMask backing:bufferingType defer:deferCreation];
-}
-
-- (void)dealloc
-{
- CFRange arrayRange = CFRangeMake(0, CFArrayGetCount(allWindowsRef));
- CFIndex i = CFArrayGetFirstIndexOfValue(allWindowsRef, arrayRange, self);
- assert(i != -1);
-
- CFArrayRemoveValueAtIndex(allWindowsRef, i);
- [super dealloc];
-}
-
-- (BOOL)isKeyWindow
-{
- return layoutTestController ? layoutTestController->windowIsKey() : YES;
-}
-
-- (void)keyDown:(id)sender
-{
- // Do nothing, avoiding the beep we'd otherwise get from NSResponder,
- // once we get to the end of the responder chain.
-}
-
-@end
-
@implementation DumpRenderTreeEvent
+ (NSPoint)mouseLocation
--- /dev/null
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ *
+ * 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 <AppKit/AppKit.h>
+
+@interface DumpRenderTreePasteboard : NSPasteboard
+- (int)declareType:(NSString *)type owner:(id)newOwner;
++ (void)releaseLocalPasteboards;
+@end
+
--- /dev/null
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ *
+ * 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 "DumpRenderTreePasteboard.h"
+
+@interface LocalPasteboard : NSPasteboard
+{
+ NSMutableArray *typesArray;
+ NSMutableSet *typesSet;
+ NSMutableDictionary *dataByType;
+ int changeCount;
+}
+@end
+
+static NSMutableDictionary *localPasteboards;
+
+@implementation DumpRenderTreePasteboard
+
+// Return a local pasteboard so we don't disturb the real pasteboards when running tests.
++ (NSPasteboard *)_pasteboardWithName:(NSString *)name
+{
+ static int number = 0;
+ if (!name)
+ name = [NSString stringWithFormat:@"LocalPasteboard%d", ++number];
+ if (!localPasteboards)
+ localPasteboards = [[NSMutableDictionary alloc] init];
+ LocalPasteboard *pasteboard = [localPasteboards objectForKey:name];
+ if (pasteboard)
+ return pasteboard;
+ pasteboard = [[LocalPasteboard alloc] init];
+ [localPasteboards setObject:pasteboard forKey:name];
+ [pasteboard release];
+ return pasteboard;
+}
+
++ (void)releaseLocalPasteboards
+{
+ [localPasteboards release];
+ localPasteboards = nil;
+}
+
+// Convenience method for JS so that it doesn't have to try and create a NSArray on the objc side instead
+// of the usual WebScriptObject that is passed around
+- (int)declareType:(NSString *)type owner:(id)newOwner
+{
+ return [self declareTypes:[NSArray arrayWithObject:type] owner:newOwner];
+}
+
+@end
+
+@implementation LocalPasteboard
+
++ (id)alloc
+{
+ return NSAllocateObject(self, 0, 0);
+}
+
+- (id)init
+{
+ typesArray = [[NSMutableArray alloc] init];
+ typesSet = [[NSMutableSet alloc] init];
+ dataByType = [[NSMutableDictionary alloc] init];
+ return self;
+}
+
+- (void)dealloc
+{
+ [typesArray release];
+ [typesSet release];
+ [dataByType release];
+ [super dealloc];
+}
+
+- (NSString *)name
+{
+ return nil;
+}
+
+- (void)releaseGlobally
+{
+}
+
+- (int)declareTypes:(NSArray *)newTypes owner:(id)newOwner
+{
+ [typesArray removeAllObjects];
+ [typesSet removeAllObjects];
+ [dataByType removeAllObjects];
+ return [self addTypes:newTypes owner:newOwner];
+}
+
+- (int)addTypes:(NSArray *)newTypes owner:(id)newOwner
+{
+ unsigned count = [newTypes count];
+ unsigned i;
+ for (i = 0; i < count; ++i) {
+ NSString *type = [newTypes objectAtIndex:i];
+ NSString *setType = [typesSet member:type];
+ if (!setType) {
+ setType = [type copy];
+ [typesArray addObject:setType];
+ [typesSet addObject:setType];
+ [setType release];
+ }
+ if (newOwner && [newOwner respondsToSelector:@selector(pasteboard:provideDataForType:)])
+ [newOwner pasteboard:self provideDataForType:setType];
+ }
+ return ++changeCount;
+}
+
+- (int)changeCount
+{
+ return changeCount;
+}
+
+- (NSArray *)types
+{
+ return typesArray;
+}
+
+- (NSString *)availableTypeFromArray:(NSArray *)types
+{
+ unsigned count = [types count];
+ unsigned i;
+ for (i = 0; i < count; ++i) {
+ NSString *type = [types objectAtIndex:i];
+ NSString *setType = [typesSet member:type];
+ if (setType)
+ return setType;
+ }
+ return nil;
+}
+
+- (BOOL)setData:(NSData *)data forType:(NSString *)dataType
+{
+ if (data == nil)
+ data = [NSData data];
+ if (![typesSet containsObject:dataType])
+ return NO;
+ [dataByType setObject:data forKey:dataType];
+ ++changeCount;
+ return YES;
+}
+
+- (NSData *)dataForType:(NSString *)dataType
+{
+ return [dataByType objectForKey:dataType];
+}
+
+- (BOOL)setPropertyList:(id)propertyList forType:(NSString *)dataType;
+{
+ CFDataRef data = NULL;
+ if (propertyList)
+ data = CFPropertyListCreateXMLData(NULL, propertyList);
+ BOOL result = [self setData:(NSData *)data forType:dataType];
+ if (data)
+ CFRelease(data);
+ return result;
+}
+
+- (BOOL)setString:(NSString *)string forType:(NSString *)dataType
+{
+ CFDataRef data = NULL;
+ if (string) {
+ if ([string length] == 0)
+ data = CFDataCreate(NULL, NULL, 0);
+ else
+ data = CFStringCreateExternalRepresentation(NULL, (CFStringRef)string, kCFStringEncodingUTF8, 0);
+ }
+ BOOL result = [self setData:(NSData *)data forType:dataType];
+ if (data)
+ CFRelease(data);
+ return result;
+}
+
+@end
--- /dev/null
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ *
+ * 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 <AppKit/AppKit.h>
+
+@interface DumpRenderTreeWindow : NSWindow
+// I'm not sure why we can't just use [NSApp windows]
++ (NSArray *)allWindows;
+@end
--- /dev/null
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
+ * (C) 2007 Graham Dennis (graham.dennis@gmail.com)
+ *
+ * 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 "DumpRenderTreeWindow.h"
+
+#import "DumpRenderTree.h"
+
+// FIXME: This file is ObjC++ only because of this include. :(
+#import "LayoutTestController.h"
+
+CFMutableArrayRef allWindowsRef = 0;
+
+static CFArrayCallBacks NonRetainingArrayCallbacks = {
+ 0,
+ NULL,
+ NULL,
+ CFCopyDescription,
+ CFEqual
+};
+
+@implementation DumpRenderTreeWindow
+
++ (NSArray *)allWindows
+{
+ return [[(NSArray *)allWindowsRef copy] autorelease];
+}
+
+- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
+{
+ if (!allWindowsRef)
+ allWindowsRef = CFArrayCreateMutable(NULL, 0, &NonRetainingArrayCallbacks);
+
+ CFArrayAppendValue(allWindowsRef, self);
+
+ return [super initWithContentRect:contentRect styleMask:styleMask backing:bufferingType defer:deferCreation];
+}
+
+- (void)dealloc
+{
+ CFRange arrayRange = CFRangeMake(0, CFArrayGetCount(allWindowsRef));
+ CFIndex i = CFArrayGetFirstIndexOfValue(allWindowsRef, arrayRange, self);
+ assert(i != -1);
+
+ CFArrayRemoveValueAtIndex(allWindowsRef, i);
+ [super dealloc];
+}
+
+- (BOOL)isKeyWindow
+{
+ return layoutTestController ? layoutTestController->windowIsKey() : YES;
+}
+
+- (void)keyDown:(id)sender
+{
+ // Do nothing, avoiding the beep we'd otherwise get from NSResponder,
+ // once we get to the end of the responder chain.
+}
+
+@end