Home | History | Annotate | Download | only in mac
      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