|
1 /* |
|
2 * Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved. |
|
3 * (C) 2007 Graham Dennis (graham.dennis@gmail.com) |
|
4 * (C) 2007 Eric Seidel <eric@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 |