• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
46static 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