1/* 2 * Copyright (C) 2007 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27#import "DragData.h" 28 29#if ENABLE(DRAG_SUPPORT) 30#import "Document.h" 31#import "DocumentFragment.h" 32#import "DOMDocumentFragment.h" 33#import "DOMDocumentFragmentInternal.h" 34#import "Editor.h" 35#import "EditorClient.h" 36#import "Frame.h" 37#import "MIMETypeRegistry.h" 38#import "Pasteboard.h" 39#import "PasteboardStrategy.h" 40#import "PlatformStrategies.h" 41#import "Range.h" 42 43namespace WebCore { 44 45DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, 46 DragOperation sourceOperationMask, DragApplicationFlags flags) 47 : m_clientPosition(clientPosition) 48 , m_globalPosition(globalPosition) 49 , m_platformDragData(data) 50 , m_draggingSourceOperationMask(sourceOperationMask) 51 , m_applicationFlags(flags) 52 , m_pasteboardName([[m_platformDragData draggingPasteboard] name]) 53{ 54} 55 56DragData::DragData(const String& dragStorageName, const IntPoint& clientPosition, const IntPoint& globalPosition, 57 DragOperation sourceOperationMask, DragApplicationFlags flags) 58 : m_clientPosition(clientPosition) 59 , m_globalPosition(globalPosition) 60 , m_platformDragData(0) 61 , m_draggingSourceOperationMask(sourceOperationMask) 62 , m_applicationFlags(flags) 63 , m_pasteboardName(dragStorageName) 64{ 65} 66 67bool DragData::canSmartReplace() const 68{ 69 return Pasteboard(m_pasteboardName).canSmartReplace(); 70} 71 72bool DragData::containsColor() const 73{ 74 Vector<String> types; 75 platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName); 76 return types.contains(String(NSColorPboardType)); 77} 78 79bool DragData::containsFiles() const 80{ 81 Vector<String> types; 82 platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName); 83 return types.contains(String(NSFilenamesPboardType)); 84} 85 86unsigned DragData::numberOfFiles() const 87{ 88 Vector<String> files; 89 platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(NSFilenamesPboardType), m_pasteboardName); 90 return files.size(); 91} 92 93void DragData::asFilenames(Vector<String>& result) const 94{ 95 platformStrategies()->pasteboardStrategy()->getPathnamesForType(result, String(NSFilenamesPboardType), m_pasteboardName); 96} 97 98bool DragData::containsPlainText() const 99{ 100 Vector<String> types; 101 platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName); 102 103 return types.contains(String(NSStringPboardType)) 104 || types.contains(String(NSRTFDPboardType)) 105 || types.contains(String(NSRTFPboardType)) 106 || types.contains(String(NSFilenamesPboardType)) 107 || platformStrategies()->pasteboardStrategy()->stringForType(String(NSURLPboardType), m_pasteboardName).length(); 108} 109 110String DragData::asPlainText(Frame *frame) const 111{ 112 return frame->editor().readPlainTextFromPasteboard(*Pasteboard::create(m_pasteboardName)); 113} 114 115Color DragData::asColor() const 116{ 117 return platformStrategies()->pasteboardStrategy()->color(m_pasteboardName); 118} 119 120bool DragData::containsCompatibleContent() const 121{ 122 Vector<String> types; 123 platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName); 124 return types.contains(String(WebArchivePboardType)) 125 || types.contains(String(NSHTMLPboardType)) 126 || types.contains(String(NSFilenamesPboardType)) 127 || types.contains(String(NSTIFFPboardType)) 128 || types.contains(String(NSPDFPboardType)) 129 || types.contains(String(NSURLPboardType)) 130 || types.contains(String(NSRTFDPboardType)) 131 || types.contains(String(NSRTFPboardType)) 132 || types.contains(String(NSStringPboardType)) 133 || types.contains(String(NSColorPboardType)) 134 || types.contains(String(kUTTypePNG)); 135} 136 137bool DragData::containsURL(Frame* frame, FilenameConversionPolicy filenamePolicy) const 138{ 139 return !asURL(frame, filenamePolicy).isEmpty(); 140} 141 142String DragData::asURL(Frame* frame, FilenameConversionPolicy, String* title) const 143{ 144 // FIXME: Use filenamePolicy. 145 146 if (title) { 147 String URLTitleString = platformStrategies()->pasteboardStrategy()->stringForType(String(WebURLNamePboardType), m_pasteboardName); 148 if (!URLTitleString.isEmpty()) 149 *title = URLTitleString; 150 } 151 152 Vector<String> types; 153 platformStrategies()->pasteboardStrategy()->getTypes(types, m_pasteboardName); 154 155 // FIXME: using the editorClient to call into WebKit, for now, since 156 // calling webkit_canonicalize from WebCore involves migrating a sizable amount of 157 // helper code that should either be done in a separate patch or figured out in another way. 158 159 if (types.contains(String(NSURLPboardType))) { 160 NSURL *URLFromPasteboard = [NSURL URLWithString:platformStrategies()->pasteboardStrategy()->stringForType(String(NSURLPboardType), m_pasteboardName)]; 161 NSString *scheme = [URLFromPasteboard scheme]; 162 // Cannot drop other schemes unless <rdar://problem/10562662> and <rdar://problem/11187315> are fixed. 163 if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) 164 return [frame->editor().client()->canonicalizeURL(URLFromPasteboard) absoluteString]; 165 } 166 167 if (types.contains(String(NSStringPboardType))) { 168 NSURL *URLFromPasteboard = [NSURL URLWithString:platformStrategies()->pasteboardStrategy()->stringForType(String(NSStringPboardType), m_pasteboardName)]; 169 NSString *scheme = [URLFromPasteboard scheme]; 170 // Pasteboard content is not trusted, because JavaScript code can modify it. We can sanitize it for URLs and other typed content, but not for strings. 171 // The result of this function is used to initiate navigation, so we shouldn't allow arbitrary file URLs. 172 // FIXME: Should we allow only http family schemes, or anything non-local? 173 if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) 174 return [frame->editor().client()->canonicalizeURL(URLFromPasteboard) absoluteString]; 175 } 176 177 if (types.contains(String(NSFilenamesPboardType))) { 178 Vector<String> files; 179 platformStrategies()->pasteboardStrategy()->getPathnamesForType(files, String(NSFilenamesPboardType), m_pasteboardName); 180 if (files.size() == 1) { 181 BOOL isDirectory; 182 if ([[NSFileManager defaultManager] fileExistsAtPath:files[0] isDirectory:&isDirectory] && isDirectory) 183 return String(); 184 return [frame->editor().client()->canonicalizeURL([NSURL fileURLWithPath:files[0]]) absoluteString]; 185 } 186 } 187 188 return String(); 189} 190 191PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, Range& range, bool allowPlainText, bool& chosePlainText) const 192{ 193 Pasteboard pasteboard(m_pasteboardName); 194 return frame->editor().webContentFromPasteboard(pasteboard, range, allowPlainText, chosePlainText); 195} 196 197} // namespace WebCore 198 199#endif // ENABLE(DRAG_SUPPORT) 200