00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import <Foundation/CPObject.j>
00024 @import <Foundation/CPArray.j>
00025 @import <Foundation/CPDictionary.j>
00026 @import <Foundation/CPPropertyListSerialization.j>
00027
00028 #include "Platform/Platform.h"
00029
00030
00031 CPGeneralPboard = @"CPGeneralPboard";
00032 CPFontPboard = @"CPFontPboard";
00033 CPRulerPboard = @"CPRulerPboard";
00034 CPFindPboard = @"CPFindPboard";
00035 CPDragPboard = @"CPDragPboard";
00036
00037 CPColorPboardType = @"CPColorPboardType";
00038 CPFilenamesPboardType = @"CPFilenamesPboardType";
00039 CPFontPboardType = @"CPFontPboardType";
00040 CPHTMLPboardType = @"CPHTMLPboardType";
00041 CPStringPboardType = @"CPStringPboardType";
00042 CPURLPboardType = @"CPURLPboardType";
00043 CPImagesPboardType = @"CPImagesPboardType";
00044 CPVideosPboardType = @"CPVideosPboardType";
00045
00046 UTF8PboardType = @"public.utf8-plain-text";
00047
00048
00049 CPImagePboardType = @"CPImagePboardType";
00050
00051
00052 var CPPasteboards = nil,
00053 supportsNativePasteboard = NO;
00054
00061 @implementation CPPasteboard : CPObject
00062 {
00063 CPArray _types;
00064 CPDictionary _owners;
00065 CPDictionary _provided;
00066
00067 unsigned _changeCount;
00068 CPString _stateUID;
00069
00070 WebScriptObject _nativePasteboard;
00071 }
00072
00073
00074
00075
00076 + (void)initialize
00077 {
00078 if (self != [CPPasteboard class])
00079 return;
00080
00081 [self setVersion:1.0];
00082
00083 CPPasteboards = [CPDictionary dictionary];
00084
00085 if (typeof window.cpPasteboardWithName !== "undefined")
00086 supportsNativePasteboard = YES;
00087 }
00088
00092 + (id)generalPasteboard
00093 {
00094 return [CPPasteboard pasteboardWithName:CPGeneralPboard];
00095 }
00096
00102 + (id)pasteboardWithName:(CPString)aName
00103 {
00104 var pasteboard = [CPPasteboards objectForKey:aName];
00105
00106 if (pasteboard)
00107 return pasteboard;
00108
00109 pasteboard = [[CPPasteboard alloc] _initWithName:aName];
00110 [CPPasteboards setObject:pasteboard forKey:aName];
00111
00112 return pasteboard;
00113 }
00114
00115
00116 - (id)_initWithName:(CPString)aName
00117 {
00118 self = [super init];
00119
00120 if (self)
00121 {
00122 _name = aName;
00123 _types = [];
00124
00125 _owners = [CPDictionary dictionary];
00126 _provided = [CPDictionary dictionary];
00127
00128 _changeCount = 0;
00129
00130 if (supportsNativePasteboard)
00131 {
00132 _nativePasteboard = window.cpPasteboardWithName(aName);
00133 [self _synchronizePasteboard];
00134 }
00135 }
00136
00137 return self;
00138 }
00139
00146 - (unsigned)addTypes:(CPArray)types owner:(id)anOwner
00147 {
00148 var i = 0,
00149 count = types.length;
00150
00151 for (; i < count; ++i)
00152 {
00153 var type = types[i];
00154
00155 if(![_owners objectForKey:type])
00156 {
00157 [_types addObject:type];
00158 [_provided removeObjectForKey:type];
00159 }
00160
00161 [_owners setObject:anOwner forKey:type];
00162 }
00163
00164 if (_nativePasteboard)
00165 {
00166 var nativeTypes = [types copy];
00167 if ([types containsObject:CPStringPboardType])
00168 nativeTypes.push(UTF8PboardType);
00169
00170 _nativePasteboard.addTypes_(nativeTypes);
00171 }
00172
00173 return ++_changeCount;
00174 }
00175
00182 - (unsigned)declareTypes:(CPArray)types owner:(id)anOwner
00183 {
00184 [self _declareTypes:types owner:anOwner updateNativePasteboard:YES];
00185 }
00186
00188 - (unsigned)_declareTypes:(CPArray)types owner:(id)anOwner updateNativePasteboard:(BOOL)shouldUpdate
00189 {
00190 [_types setArray:types];
00191
00192 _owners = [CPDictionary dictionary];
00193 _provided = [CPDictionary dictionary];
00194
00195 var count = _types.length;
00196
00197 while (count--)
00198 [_owners setObject:anOwner forKey:_types[count]];
00199
00200 if (_nativePasteboard && shouldUpdate)
00201 {
00202 var nativeTypes = [types copy];
00203 if ([types containsObject:CPStringPboardType])
00204 nativeTypes.push(UTF8PboardType);
00205
00206 _nativePasteboard.declareTypes_(nativeTypes);
00207 _changeCount = _nativePasteboard.changeCount();
00208 }
00209 return ++_changeCount;
00210 }
00211
00218 - (BOOL)setData:(CPData)aData forType:(CPString)aType
00219 {
00220 [_provided setObject:aData forKey:aType];
00221
00222 if (aType === CPStringPboardType)
00223 [self setData:aData forType:UTF8PboardType];
00224
00225 return YES;
00226 }
00227
00234 - (BOOL)setPropertyList:(id)aPropertyList forType:(CPString)aType
00235 {
00236 return [self setData:[CPPropertyListSerialization dataFromPropertyList:aPropertyList format:CPPropertyList280NorthFormat_v1_0] forType:aType];
00237 }
00238
00245 - (void)setString:(CPString)aString forType:(CPString)aType
00246 {
00247 [self setPropertyList:aString forType:aType];
00248 }
00249
00250
00257 - (CPString)availableTypeFromArray:(CPArray)anArray
00258 {
00259 return [[self types] firstObjectCommonWithArray:anArray];
00260 }
00261
00265 - (CPArray)types
00266 {
00267 [self _synchronizePasteboard];
00268 return _types;
00269 }
00270
00271
00275 - (unsigned)changeCount
00276 {
00277 return _changeCount;
00278 }
00279
00285 - (CPData)dataForType:(CPString)aType
00286 {
00287 var data = [_provided objectForKey:aType];
00288
00289 if (data)
00290 return data;
00291
00292 var owner = [_owners objectForKey:aType];
00293
00294 if (owner)
00295 {
00296 [owner pasteboard:self provideDataForType:aType];
00297 return [_provided objectForKey:aType];
00298 }
00299
00300 if (aType === CPStringPboardType)
00301 return [self dataForType:UTF8PboardType];
00302
00303 return nil;
00304 }
00305
00306 - (void)_synchronizePasteboard
00307 {
00308 if (_nativePasteboard && _nativePasteboard.changeCount() > _changeCount)
00309 {
00310 var nativeTypes = [_nativePasteboard.types() copy];
00311 if ([nativeTypes containsObject:UTF8PboardType])
00312 nativeTypes.push(CPStringPboardType);
00313
00314 [self _declareTypes:nativeTypes owner:self updateNativePasteboard:NO];
00315
00316 _changeCount = _nativePasteboard.changeCount();
00317 }
00318 }
00319
00323 - (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
00324 {
00325 if (aType === CPStringPboardType)
00326 {
00327 var string = _nativePasteboard.stringForType_(UTF8PboardType);
00328
00329 [self setString:string forType:CPStringPboardType];
00330 [self setString:string forType:UTF8PboardType];
00331 }
00332 else
00333 [self setString:_nativePasteboard.stringForType_(aType) forType:aType];
00334 }
00335
00341 - (id)propertyListForType:(CPString)aType
00342 {
00343 var data = [self dataForType:aType];
00344
00345 if (data)
00346 return [CPPropertyListSerialization propertyListFromData:data format:CPPropertyList280NorthFormat_v1_0];
00347
00348 return nil;
00349 }
00350
00356 - (CPString)stringForType:(CPString)aType
00357 {
00358 return [self propertyListForType:aType];
00359 }
00360
00361
00362 - (CPString)_generateStateUID
00363 {
00364 var bits = 32;
00365
00366 _stateUID = @"";
00367
00368 while (bits--)
00369 _stateUID += FLOOR(RAND() * 16.0).toString(16).toUpperCase();
00370
00371 return _stateUID;
00372 }
00373
00374
00375 - (CPString)_stateUID
00376 {
00377 return _stateUID;
00378 }
00379
00380 @end
00381
00382 #if PLATFORM(DOM)
00383
00384 var DOMDataTransferPasteboard = nil;
00385
00386 @implementation _CPDOMDataTransferPasteboard : CPPasteboard
00387 {
00388 DataTransfer _dataTransfer;
00389 }
00390
00391 + (_CPDOMDataTransferPasteboard)DOMDataTransferPasteboard
00392 {
00393 if (!DOMDataTransferPasteboard)
00394 DOMDataTransferPasteboard = [[_CPDOMDataTransferPasteboard alloc] init];
00395
00396 return DOMDataTransferPasteboard;
00397 }
00398
00399 - (void)_setDataTransfer:(DataTransfer)aDataTransfer
00400 {
00401 _dataTransfer = aDataTransfer;
00402 }
00403
00404 - (void)_setPasteboard:(CPPasteboard)aPasteboard
00405 {
00406 _dataTransfer.clearData();
00407
00408 var types = [aPasteboard types],
00409 count = types.length;
00410
00411 while (count--)
00412 {
00413 var type = types[count];
00414
00415 if (type === CPStringPboardType)
00416 _dataTransfer.setData(type, [aPasteboard stringForType:type]);
00417 else
00418 _dataTransfer.setData(type, [[aPasteboard dataForType:type] rawString]);
00419 }
00420 }
00421
00422 - (CPArray)types
00423 {
00424 return Array.prototype.slice.apply(_dataTransfer.types);
00425 }
00426
00427 - (CPData)dataForType:(CPString)aType
00428 {
00429 var dataString = _dataTransfer.getData(aType);
00430
00431 if (aType === CPStringPboardType)
00432 return [CPData dataFromPropertyList:dataString format:kCFPropertyList280NorthFormat_v1_0];
00433
00434 return [CPData dataWithRawString:dataString];
00435 }
00436
00437 - (id)propertyListForType:(CPString)aType
00438 {
00439 if (aType === CPStringPboardType)
00440 return _dataTransfer.getData(aType);
00441
00442 return [CPPropertyListSerialization propertyListFromData:[self dataForType:aType] format:CPPropertyListUnknownFormat];
00443 }
00444
00445 @end
00446
00447 #endif