1 /* 2 * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved. 3 * (C) 2007 Graham Dennis (graham.dennis (at) gmail.com) 4 * (C) 2007 Eric Seidel <eric (at) webkit.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 16 * its contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #import "config.h" 32 #import "DumpRenderTreeMac.h" 33 #import "DumpRenderTreePasteboard.h" 34 35 #import <WebKit/WebTypesInternal.h> 36 37 @interface LocalPasteboard : NSPasteboard 38 { 39 NSMutableArray *typesArray; 40 NSMutableSet *typesSet; 41 NSMutableDictionary *dataByType; 42 NSInteger changeCount; 43 } 44 @end 45 46 static NSMutableDictionary *localPasteboards; 47 48 @implementation DumpRenderTreePasteboard 49 50 // Return a local pasteboard so we don't disturb the real pasteboards when running tests. 51 + (NSPasteboard *)_pasteboardWithName:(NSString *)name 52 { 53 static int number = 0; 54 if (!name) 55 name = [NSString stringWithFormat:@"LocalPasteboard%d", ++number]; 56 if (!localPasteboards) 57 localPasteboards = [[NSMutableDictionary alloc] init]; 58 LocalPasteboard *pasteboard = [localPasteboards objectForKey:name]; 59 if (pasteboard) 60 return pasteboard; 61 pasteboard = [[LocalPasteboard alloc] init]; 62 [localPasteboards setObject:pasteboard forKey:name]; 63 [pasteboard release]; 64 return pasteboard; 65 } 66 67 + (void)releaseLocalPasteboards 68 { 69 [localPasteboards release]; 70 localPasteboards = nil; 71 } 72 73 // Convenience method for JS so that it doesn't have to try and create a NSArray on the objc side instead 74 // of the usual WebScriptObject that is passed around 75 - (NSInteger)declareType:(NSString *)type owner:(id)newOwner 76 { 77 return [self declareTypes:[NSArray arrayWithObject:type] owner:newOwner]; 78 } 79 80 @end 81 82 @implementation LocalPasteboard 83 84 + (id)alloc 85 { 86 return NSAllocateObject(self, 0, 0); 87 } 88 89 - (id)init 90 { 91 typesArray = [[NSMutableArray alloc] init]; 92 typesSet = [[NSMutableSet alloc] init]; 93 dataByType = [[NSMutableDictionary alloc] init]; 94 return self; 95 } 96 97 - (void)dealloc 98 { 99 [typesArray release]; 100 [typesSet release]; 101 [dataByType release]; 102 [super dealloc]; 103 } 104 105 - (NSString *)name 106 { 107 return nil; 108 } 109 110 - (void)releaseGlobally 111 { 112 } 113 114 - (NSInteger)declareTypes:(NSArray *)newTypes owner:(id)newOwner 115 { 116 [typesArray removeAllObjects]; 117 [typesSet removeAllObjects]; 118 [dataByType removeAllObjects]; 119 return [self addTypes:newTypes owner:newOwner]; 120 } 121 122 - (NSInteger)addTypes:(NSArray *)newTypes owner:(id)newOwner 123 { 124 unsigned count = [newTypes count]; 125 unsigned i; 126 for (i = 0; i < count; ++i) { 127 NSString *type = [newTypes objectAtIndex:i]; 128 NSString *setType = [typesSet member:type]; 129 if (!setType) { 130 setType = [type copy]; 131 [typesArray addObject:setType]; 132 [typesSet addObject:setType]; 133 [setType release]; 134 } 135 if (newOwner && [newOwner respondsToSelector:@selector(pasteboard:provideDataForType:)]) 136 [newOwner pasteboard:self provideDataForType:setType]; 137 } 138 return ++changeCount; 139 } 140 141 - (NSInteger)changeCount 142 { 143 return changeCount; 144 } 145 146 - (NSArray *)types 147 { 148 return typesArray; 149 } 150 151 - (NSString *)availableTypeFromArray:(NSArray *)types 152 { 153 unsigned count = [types count]; 154 unsigned i; 155 for (i = 0; i < count; ++i) { 156 NSString *type = [types objectAtIndex:i]; 157 NSString *setType = [typesSet member:type]; 158 if (setType) 159 return setType; 160 } 161 return nil; 162 } 163 164 - (BOOL)setData:(NSData *)data forType:(NSString *)dataType 165 { 166 if (data == nil) 167 data = [NSData data]; 168 if (![typesSet containsObject:dataType]) 169 return NO; 170 [dataByType setObject:data forKey:dataType]; 171 ++changeCount; 172 return YES; 173 } 174 175 - (NSData *)dataForType:(NSString *)dataType 176 { 177 return [dataByType objectForKey:dataType]; 178 } 179 180 - (BOOL)setPropertyList:(id)propertyList forType:(NSString *)dataType 181 { 182 CFDataRef data = NULL; 183 if (propertyList) 184 data = CFPropertyListCreateXMLData(NULL, propertyList); 185 BOOL result = [self setData:(NSData *)data forType:dataType]; 186 if (data) 187 CFRelease(data); 188 return result; 189 } 190 191 - (BOOL)setString:(NSString *)string forType:(NSString *)dataType 192 { 193 CFDataRef data = NULL; 194 if (string) { 195 if ([string length] == 0) 196 data = CFDataCreate(NULL, NULL, 0); 197 else 198 data = CFStringCreateExternalRepresentation(NULL, (CFStringRef)string, kCFStringEncodingUTF8, 0); 199 } 200 BOOL result = [self setData:(NSData *)data forType:dataType]; 201 if (data) 202 CFRelease(data); 203 return result; 204 } 205 206 @end 207