NSPasteboard+Utils.mm revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* ***** BEGIN LICENSE BLOCK ***** 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Version: MPL 1.1/GPL 2.0/LGPL 2.1 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The contents of this file are subject to the Mozilla Public License Version 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1.1 (the "License"); you may not use this file except in compliance with 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the License. You may obtain a copy of the License at 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.mozilla.org/MPL/ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Software distributed under the License is distributed on an "AS IS" basis, 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for the specific language governing rights and limitations under the 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * License. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Original Code is Chimera code. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The Initial Developer of the Original Code is 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Netscape Communications Corporation. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Portions created by the Initial Developer are Copyright (C) 2002 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the Initial Developer. All Rights Reserved. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Contributor(s): 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Simon Fraser <sfraser@netscape.com> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Bruce Davidson <Bruce.Davidson@ipl.com> 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Alternatively, the contents of this file may be used under the terms of 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * either the GNU General Public License Version 2 or later (the "GPL"), or 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in which case the provisions of the GPL or the LGPL are applicable instead 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of those above. If you wish to allow use of your version of this file only 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * under the terms of either the GPL or the LGPL, and not to allow others to 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * use your version of this file under the terms of the MPL, indicate your 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * decision by deleting the provisions above and replace them with the notice 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and other provisions required by the GPL or the LGPL. If you do not delete 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the provisions above, a recipient may use your version of this file under 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the terms of any one of the MPL, the GPL or the LGPL. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ***** END LICENSE BLOCK ***** */ 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import "NSPasteboard+Utils.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import "NSURL+Utils.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import "NSString+Utils.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSString* const kCorePasteboardFlavorType_url = @"CorePasteboardFlavorType 0x75726C20"; // 'url ' url 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSString* const kCorePasteboardFlavorType_urln = @"CorePasteboardFlavorType 0x75726C6E"; // 'urln' title 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSString* const kCorePasteboardFlavorType_urld = @"CorePasteboardFlavorType 0x75726C64"; // 'urld' URL description 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSString* const kCaminoBookmarkListPBoardType = @"MozBookmarkType"; // list of Camino bookmark UIDs 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NSString* const kWebURLsWithTitlesPboardType = @"WebURLsWithTitlesPboardType"; // Safari-compatible URL + title arrays 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@interface NSPasteboard(ChimeraPasteboardURLUtilsPrivate) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (NSString*)cleanedStringWithPasteboardString:(NSString*)aString; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation NSPasteboard(ChimeraPasteboardURLUtilsPrivate) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Utility method to ensure strings we're using in |containsURLData| 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and |getURLs:andTitles| are free of internal control characters 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and leading/trailing whitespace 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (NSString*)cleanedStringWithPasteboardString:(NSString*)aString 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* cleanString = [aString stringByRemovingCharactersInSet:[NSCharacterSet controlCharacterSet]]; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [cleanString stringByTrimmingWhitespace]; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation NSPasteboard(ChimeraPasteboardURLUtils) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (int)declareURLPasteboardWithAdditionalTypes:(NSArray*)additionalTypes owner:(id)newOwner 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSArray* allTypes = [additionalTypes arrayByAddingObjectsFromArray: 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [NSArray arrayWithObjects: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kWebURLsWithTitlesPboardType, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSURLPboardType, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSStringPboardType, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCorePasteboardFlavorType_url, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCorePasteboardFlavorType_urln, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nil]]; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [self declareTypes:allTypes owner:newOwner]; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copy a single URL (with an optional title) to the clipboard in all relevant 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// formats. Convenience method for clients that can only ever deal with one 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URL and shouldn't have to build up the arrays for setURLs:withTitles:. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void)setDataForURL:(NSString*)url title:(NSString*)title 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSArray* urlList = [NSArray arrayWithObject:url]; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSArray* titleList = nil; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (title) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) titleList = [NSArray arrayWithObject:title]; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self setURLs:urlList withTitles:titleList]; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copy a set of URLs, each of which may have a title, to the pasteboard 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// using all the available formats. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The title array should be nil, or must have the same length as the URL array. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void)setURLs:(NSArray*)inUrls withTitles:(NSArray*)inTitles 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int urlCount = [inUrls count]; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Best format that we know about is Safari's URL + title arrays - build these up 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!inTitles) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSMutableArray* tmpTitleArray = [NSMutableArray arrayWithCapacity:urlCount]; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < urlCount; ++i) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [tmpTitleArray addObject:[inUrls objectAtIndex:i]]; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inTitles = tmpTitleArray; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSMutableArray* filePaths = [NSMutableArray array]; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned int i = 0; i < urlCount; ++i) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSURL* url = [NSURL URLWithString:[inUrls objectAtIndex:i]]; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ([url isFileURL] && [[NSFileManager defaultManager] fileExistsAtPath:[url path]]) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [filePaths addObject:[url path]]; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ([filePaths count] > 0) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self addTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil]; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self setPropertyList:filePaths forType:NSFilenamesPboardType]; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSMutableArray* clipboardData = [NSMutableArray array]; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [clipboardData addObject:[NSArray arrayWithArray:inUrls]]; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [clipboardData addObject:inTitles]; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self setPropertyList:clipboardData forType:kWebURLsWithTitlesPboardType]; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (urlCount == 1) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* url = [inUrls objectAtIndex:0]; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* title = [inTitles objectAtIndex:0]; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [[NSURL URLWithString:url] writeToPasteboard:self]; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self setString:url forType:NSStringPboardType]; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* tempCString = [url UTF8String]; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self setData:[NSData dataWithBytes:tempCString length:strlen(tempCString)] forType:kCorePasteboardFlavorType_url]; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (inTitles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempCString = [title UTF8String]; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self setData:[NSData dataWithBytes:tempCString length:strlen(tempCString)] forType:kCorePasteboardFlavorType_urln]; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (urlCount > 1) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // With multiple URLs there aren't many other formats we can use 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Just write a string of each URL (ignoring titles) on a separate line 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self setString:[inUrls componentsJoinedByString:@"\n"] forType:NSStringPboardType]; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but we have to put something in the carbon style flavors, otherwise apps will think 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there is data there, but get nothing 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* firstURL = [inUrls objectAtIndex:0]; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* firstTitle = [inTitles objectAtIndex:0]; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* tempCString = [firstURL UTF8String]; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self setData:[NSData dataWithBytes:tempCString length:strlen(tempCString)] forType:kCorePasteboardFlavorType_url]; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tempCString = [firstTitle UTF8String]; // not i18n friendly 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [self setData:[NSData dataWithBytes:tempCString length:strlen(tempCString)] forType:kCorePasteboardFlavorType_urln]; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get the set of URLs and their corresponding titles from the pasteboard. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If there are no URLs in a format we understand on the pasteboard empty 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// arrays will be returned. The two arrays will always be the same size. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The arrays returned are on the auto release pool. If |convertFilenames| 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is YES, then the function will attempt to convert filenames in the drag 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to file URLs. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void) getURLs:(NSArray**)outUrls 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) andTitles:(NSArray**)outTitles 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) convertingFilenames:(BOOL)convertFilenames 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSArray* types = [self types]; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSURL* urlFromNSURL = nil; // Used below in getting an URL from the NSURLPboardType. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ([types containsObject:kWebURLsWithTitlesPboardType]) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSArray* urlAndTitleContainer = [self propertyListForType:kWebURLsWithTitlesPboardType]; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outUrls = [urlAndTitleContainer objectAtIndex:0]; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outTitles = [urlAndTitleContainer objectAtIndex:1]; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ([types containsObject:NSFilenamesPboardType]) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSArray *files = [self propertyListForType:NSFilenamesPboardType]; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outUrls = [NSMutableArray arrayWithCapacity:[files count]]; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outTitles = [NSMutableArray arrayWithCapacity:[files count]]; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for ( unsigned int i = 0; i < [files count]; ++i ) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString *file = [files objectAtIndex:i]; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString *ext = [[file pathExtension] lowercaseString]; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString *urlString = nil; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString *title = @""; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OSType fileType = NSHFSTypeCodeFromFileType(NSHFSTypeOfFile(file)); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check whether the file is a .webloc, a .ftploc, a .url, or some other kind of file. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ([ext isEqualToString:@"webloc"] || [ext isEqualToString:@"ftploc"] || fileType == 'ilht' || fileType == 'ilft') { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSURL* urlFromInetloc = [NSURL URLFromInetloc:file]; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (urlFromInetloc) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urlString = [urlFromInetloc absoluteString]; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title = [[file lastPathComponent] stringByDeletingPathExtension]; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ([ext isEqualToString:@"url"] || fileType == 'LINK') { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSURL* urlFromIEURLFile = [NSURL URLFromIEURLFile:file]; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (urlFromIEURLFile) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urlString = [urlFromIEURLFile absoluteString]; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title = [[file lastPathComponent] stringByDeletingPathExtension]; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!urlString) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!convertFilenames) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the filename if not a .webloc or .url file, or if either of the 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // functions returns nil. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) urlString = [[NSURL fileURLWithPath:file] absoluteString]; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title = [file lastPathComponent]; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [(NSMutableArray*) *outUrls addObject:urlString]; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [(NSMutableArray*) *outTitles addObject:title]; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ([types containsObject:NSURLPboardType] && (urlFromNSURL = [NSURL URLFromPasteboard:self])) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outUrls = [NSArray arrayWithObject:[urlFromNSURL absoluteString]]; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* title = nil; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ([types containsObject:kCorePasteboardFlavorType_urld]) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title = [self stringForType:kCorePasteboardFlavorType_urld]; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!title && [types containsObject:kCorePasteboardFlavorType_urln]) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title = [self stringForType:kCorePasteboardFlavorType_urln]; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!title && [types containsObject:NSStringPboardType]) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title = [self stringForType:NSStringPboardType]; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outTitles = [NSArray arrayWithObject:(title ? title : @"")]; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ([types containsObject:NSStringPboardType]) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* potentialURLString = [self cleanedStringWithPasteboardString:[self stringForType:NSStringPboardType]]; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ([potentialURLString isValidURI]) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outUrls = [NSArray arrayWithObject:potentialURLString]; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* title = nil; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ([types containsObject:kCorePasteboardFlavorType_urld]) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title = [self stringForType:kCorePasteboardFlavorType_urld]; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!title && [types containsObject:kCorePasteboardFlavorType_urln]) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) title = [self stringForType:kCorePasteboardFlavorType_urln]; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outTitles = [NSArray arrayWithObject:(title ? title : @"")]; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The string doesn't look like a URL - return empty arrays 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outUrls = [NSArray array]; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outTitles = [NSArray array]; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't recognise any of these formats - return empty arrays 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outUrls = [NSArray array]; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *outTitles = [NSArray array]; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Indicates if this pasteboard contains URL data that we understand 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Deals with all our URL formats. Only strings that are valid URLs count. 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If this returns YES it is safe to use getURLs:andTitles: to retrieve the data. 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NB: Does not consider our internal bookmark list format, because callers 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// usually need to deal with this separately because it can include folders etc. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (BOOL) containsURLData 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSArray* types = [self types]; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ( [types containsObject:kWebURLsWithTitlesPboardType] 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || [types containsObject:NSURLPboardType] 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || [types containsObject:NSFilenamesPboardType] ) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return YES; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ([types containsObject:NSStringPboardType]) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trim whitespace off the ends and newlines out of the middle so we don't reject otherwise-valid URLs; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we'll do another cleaning when we set the URLs and titles later, so this is safe. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSString* potentialURLString = [self cleanedStringWithPasteboardString:[self stringForType:NSStringPboardType]]; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [potentialURLString isValidURI]; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NO; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation NSPasteboard(ChromiumHTMLUtils) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert the RTF to HTML via an NSAttributedString. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (NSString*)htmlFromRtf { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (![[self types] containsObject:NSRTFPboardType]) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return @""; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSAttributedString* attributed = 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [[[NSAttributedString alloc] 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initWithRTF:[self dataForType:NSRTFPboardType] 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) documentAttributes:nil] autorelease]; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSDictionary* attributeDict = 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forKey:NSDocumentTypeDocumentAttribute]; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSData* htmlData = 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [attributed dataFromRange:NSMakeRange(0, [attributed length]) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) documentAttributes:attributeDict 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error:nil]; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // According to the docs, NSHTMLTextDocumentType is UTF8. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return [[[NSString alloc] 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initWithData:htmlData encoding:NSUTF8StringEncoding] autorelease]; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end 307