initial import
[vuplus_webkit] / Tools / DumpRenderTree / mac / DumpRenderTreePasteboard.m
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