OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ights reserved. |
3 * Copyright (C) 2010 Google Inc. All rights reserved. | 3 * Copyright (C) 2010 Google Inc. All rights reserved. |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 30 matching lines...) Expand all Loading... |
41 #include "platform/text/PlatformLocale.h" | 41 #include "platform/text/PlatformLocale.h" |
42 #include "wtf/PassOwnPtr.h" | 42 #include "wtf/PassOwnPtr.h" |
43 #include "wtf/text/StringBuilder.h" | 43 #include "wtf/text/StringBuilder.h" |
44 #include "wtf/text/WTFString.h" | 44 #include "wtf/text/WTFString.h" |
45 | 45 |
46 namespace WebCore { | 46 namespace WebCore { |
47 | 47 |
48 using WebKit::WebLocalizedString; | 48 using WebKit::WebLocalizedString; |
49 using namespace HTMLNames; | 49 using namespace HTMLNames; |
50 | 50 |
51 inline FileInputType::FileInputType(HTMLInputElement* element) | 51 inline FileInputType::FileInputType(HTMLInputElement& element) |
52 : BaseClickableWithKeyInputType(element) | 52 : BaseClickableWithKeyInputType(element) |
53 , m_fileList(FileList::create()) | 53 , m_fileList(FileList::create()) |
54 { | 54 { |
55 } | 55 } |
56 | 56 |
57 PassRefPtr<InputType> FileInputType::create(HTMLInputElement* element) | 57 PassRefPtr<InputType> FileInputType::create(HTMLInputElement& element) |
58 { | 58 { |
59 return adoptRef(new FileInputType(element)); | 59 return adoptRef(new FileInputType(element)); |
60 } | 60 } |
61 | 61 |
62 Vector<FileChooserFileInfo> FileInputType::filesFromFormControlState(const FormC
ontrolState& state) | 62 Vector<FileChooserFileInfo> FileInputType::filesFromFormControlState(const FormC
ontrolState& state) |
63 { | 63 { |
64 Vector<FileChooserFileInfo> files; | 64 Vector<FileChooserFileInfo> files; |
65 for (size_t i = 0; i < state.valueSize(); i += 2) { | 65 for (size_t i = 0; i < state.valueSize(); i += 2) { |
66 if (!state[i + 1].isEmpty()) | 66 if (!state[i + 1].isEmpty()) |
67 files.append(FileChooserFileInfo(state[i], state[i + 1])); | 67 files.append(FileChooserFileInfo(state[i], state[i + 1])); |
(...skipping 23 matching lines...) Expand all Loading... |
91 | 91 |
92 void FileInputType::restoreFormControlState(const FormControlState& state) | 92 void FileInputType::restoreFormControlState(const FormControlState& state) |
93 { | 93 { |
94 if (state.valueSize() % 2) | 94 if (state.valueSize() % 2) |
95 return; | 95 return; |
96 filesChosen(filesFromFormControlState(state)); | 96 filesChosen(filesFromFormControlState(state)); |
97 } | 97 } |
98 | 98 |
99 bool FileInputType::appendFormData(FormDataList& encoding, bool multipart) const | 99 bool FileInputType::appendFormData(FormDataList& encoding, bool multipart) const |
100 { | 100 { |
101 FileList* fileList = element()->files(); | 101 FileList* fileList = element().files(); |
102 unsigned numFiles = fileList->length(); | 102 unsigned numFiles = fileList->length(); |
103 if (!multipart) { | 103 if (!multipart) { |
104 // Send only the basenames. | 104 // Send only the basenames. |
105 // 4.10.16.4 and 4.10.16.6 sections in HTML5. | 105 // 4.10.16.4 and 4.10.16.6 sections in HTML5. |
106 | 106 |
107 // Unlike the multipart case, we have no special handling for the empty | 107 // Unlike the multipart case, we have no special handling for the empty |
108 // fileList because Netscape doesn't support for non-multipart | 108 // fileList because Netscape doesn't support for non-multipart |
109 // submission of file inputs, and Firefox doesn't add "name=" query | 109 // submission of file inputs, and Firefox doesn't add "name=" query |
110 // parameter. | 110 // parameter. |
111 for (unsigned i = 0; i < numFiles; ++i) | 111 for (unsigned i = 0; i < numFiles; ++i) |
112 encoding.appendData(element()->name(), fileList->item(i)->name()); | 112 encoding.appendData(element().name(), fileList->item(i)->name()); |
113 return true; | 113 return true; |
114 } | 114 } |
115 | 115 |
116 // If no filename at all is entered, return successful but empty. | 116 // If no filename at all is entered, return successful but empty. |
117 // Null would be more logical, but Netscape posts an empty file. Argh. | 117 // Null would be more logical, but Netscape posts an empty file. Argh. |
118 if (!numFiles) { | 118 if (!numFiles) { |
119 encoding.appendBlob(element()->name(), File::create("")); | 119 encoding.appendBlob(element().name(), File::create("")); |
120 return true; | 120 return true; |
121 } | 121 } |
122 | 122 |
123 for (unsigned i = 0; i < numFiles; ++i) | 123 for (unsigned i = 0; i < numFiles; ++i) |
124 encoding.appendBlob(element()->name(), fileList->item(i)); | 124 encoding.appendBlob(element().name(), fileList->item(i)); |
125 return true; | 125 return true; |
126 } | 126 } |
127 | 127 |
128 bool FileInputType::valueMissing(const String& value) const | 128 bool FileInputType::valueMissing(const String& value) const |
129 { | 129 { |
130 return element()->isRequired() && value.isEmpty(); | 130 return element().isRequired() && value.isEmpty(); |
131 } | 131 } |
132 | 132 |
133 String FileInputType::valueMissingText() const | 133 String FileInputType::valueMissingText() const |
134 { | 134 { |
135 return locale().queryString(element()->multiple() ? WebLocalizedString::Vali
dationValueMissingForMultipleFile : WebLocalizedString::ValidationValueMissingFo
rFile); | 135 return locale().queryString(element().multiple() ? WebLocalizedString::Valid
ationValueMissingForMultipleFile : WebLocalizedString::ValidationValueMissingFor
File); |
136 } | 136 } |
137 | 137 |
138 void FileInputType::handleDOMActivateEvent(Event* event) | 138 void FileInputType::handleDOMActivateEvent(Event* event) |
139 { | 139 { |
140 if (element()->isDisabledFormControl()) | 140 if (element().isDisabledFormControl()) |
141 return; | 141 return; |
142 | 142 |
143 if (!UserGestureIndicator::processingUserGesture()) | 143 if (!UserGestureIndicator::processingUserGesture()) |
144 return; | 144 return; |
145 | 145 |
146 if (Chrome* chrome = this->chrome()) { | 146 if (Chrome* chrome = this->chrome()) { |
147 FileChooserSettings settings; | 147 FileChooserSettings settings; |
148 HTMLInputElement* input = element(); | 148 HTMLInputElement& input = element(); |
149 settings.allowsDirectoryUpload = RuntimeEnabledFeatures::directoryUpload
Enabled() && input->fastHasAttribute(webkitdirectoryAttr); | 149 settings.allowsDirectoryUpload = RuntimeEnabledFeatures::directoryUpload
Enabled() && input.fastHasAttribute(webkitdirectoryAttr); |
150 settings.allowsMultipleFiles = settings.allowsDirectoryUpload || input->
fastHasAttribute(multipleAttr); | 150 settings.allowsMultipleFiles = settings.allowsDirectoryUpload || input.f
astHasAttribute(multipleAttr); |
151 settings.acceptMIMETypes = input->acceptMIMETypes(); | 151 settings.acceptMIMETypes = input.acceptMIMETypes(); |
152 settings.acceptFileExtensions = input->acceptFileExtensions(); | 152 settings.acceptFileExtensions = input.acceptFileExtensions(); |
153 settings.selectedFiles = m_fileList->paths(); | 153 settings.selectedFiles = m_fileList->paths(); |
154 #if ENABLE(MEDIA_CAPTURE) | 154 #if ENABLE(MEDIA_CAPTURE) |
155 settings.useMediaCapture = input->capture(); | 155 settings.useMediaCapture = input.capture(); |
156 #endif | 156 #endif |
157 chrome->runOpenPanel(input->document().frame(), newFileChooser(settings)
); | 157 chrome->runOpenPanel(input.document().frame(), newFileChooser(settings))
; |
158 } | 158 } |
159 event->setDefaultHandled(); | 159 event->setDefaultHandled(); |
160 } | 160 } |
161 | 161 |
162 RenderObject* FileInputType::createRenderer(RenderStyle*) const | 162 RenderObject* FileInputType::createRenderer(RenderStyle*) const |
163 { | 163 { |
164 return new RenderFileUploadControl(element()); | 164 return new RenderFileUploadControl(&element()); |
165 } | 165 } |
166 | 166 |
167 bool FileInputType::canSetStringValue() const | 167 bool FileInputType::canSetStringValue() const |
168 { | 168 { |
169 return false; | 169 return false; |
170 } | 170 } |
171 | 171 |
172 FileList* FileInputType::files() | 172 FileList* FileInputType::files() |
173 { | 173 { |
174 return m_fileList.get(); | 174 return m_fileList.get(); |
(...skipping 21 matching lines...) Expand all Loading... |
196 // decided to try to parse the value by looking for backslashes | 196 // decided to try to parse the value by looking for backslashes |
197 // (because that's what Windows file paths use). To be compatible | 197 // (because that's what Windows file paths use). To be compatible |
198 // with that code, we make up a fake path for the file. | 198 // with that code, we make up a fake path for the file. |
199 value = "C:\\fakepath\\" + m_fileList->item(0)->name(); | 199 value = "C:\\fakepath\\" + m_fileList->item(0)->name(); |
200 return true; | 200 return true; |
201 } | 201 } |
202 | 202 |
203 void FileInputType::setValue(const String&, bool, TextFieldEventBehavior) | 203 void FileInputType::setValue(const String&, bool, TextFieldEventBehavior) |
204 { | 204 { |
205 m_fileList->clear(); | 205 m_fileList->clear(); |
206 element()->setNeedsStyleRecalc(); | 206 element().setNeedsStyleRecalc(); |
207 } | 207 } |
208 | 208 |
209 PassRefPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileI
nfo>& files) const | 209 PassRefPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileI
nfo>& files) const |
210 { | 210 { |
211 RefPtr<FileList> fileList(FileList::create()); | 211 RefPtr<FileList> fileList(FileList::create()); |
212 size_t size = files.size(); | 212 size_t size = files.size(); |
213 | 213 |
214 // If a directory is being selected, the UI allows a directory to be chosen | 214 // If a directory is being selected, the UI allows a directory to be chosen |
215 // and the paths provided here share a root directory somewhere up the tree; | 215 // and the paths provided here share a root directory somewhere up the tree; |
216 // we want to store only the relative paths from that point. | 216 // we want to store only the relative paths from that point. |
217 if (size && element()->fastHasAttribute(webkitdirectoryAttr) && RuntimeEnabl
edFeatures::directoryUploadEnabled()) { | 217 if (size && element().fastHasAttribute(webkitdirectoryAttr) && RuntimeEnable
dFeatures::directoryUploadEnabled()) { |
218 // Find the common root path. | 218 // Find the common root path. |
219 String rootPath = directoryName(files[0].path); | 219 String rootPath = directoryName(files[0].path); |
220 for (size_t i = 1; i < size; i++) { | 220 for (size_t i = 1; i < size; i++) { |
221 while (!files[i].path.startsWith(rootPath)) | 221 while (!files[i].path.startsWith(rootPath)) |
222 rootPath = directoryName(rootPath); | 222 rootPath = directoryName(rootPath); |
223 } | 223 } |
224 rootPath = directoryName(rootPath); | 224 rootPath = directoryName(rootPath); |
225 ASSERT(rootPath.length()); | 225 ASSERT(rootPath.length()); |
226 int rootLength = rootPath.length(); | 226 int rootLength = rootPath.length(); |
227 if (rootPath[rootLength - 1] != '\\' && rootPath[rootLength - 1] != '/') | 227 if (rootPath[rootLength - 1] != '\\' && rootPath[rootLength - 1] != '/') |
(...skipping 11 matching lines...) Expand all Loading... |
239 return fileList; | 239 return fileList; |
240 } | 240 } |
241 | 241 |
242 bool FileInputType::isFileUpload() const | 242 bool FileInputType::isFileUpload() const |
243 { | 243 { |
244 return true; | 244 return true; |
245 } | 245 } |
246 | 246 |
247 void FileInputType::createShadowSubtree() | 247 void FileInputType::createShadowSubtree() |
248 { | 248 { |
249 ASSERT(element()->shadow()); | 249 ASSERT(element().shadow()); |
250 RefPtr<HTMLInputElement> button = HTMLInputElement::create(inputTag, element
()->document(), 0, false); | 250 RefPtr<HTMLInputElement> button = HTMLInputElement::create(inputTag, element
().document(), 0, false); |
251 button->setType(InputTypeNames::button()); | 251 button->setType(InputTypeNames::button()); |
252 button->setAttribute(valueAttr, locale().queryString(element()->multiple() ?
WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::Fi
leButtonChooseFileLabel)); | 252 button->setAttribute(valueAttr, locale().queryString(element().multiple() ?
WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::Fil
eButtonChooseFileLabel)); |
253 button->setPart(AtomicString("-webkit-file-upload-button", AtomicString::Con
structFromLiteral)); | 253 button->setPart(AtomicString("-webkit-file-upload-button", AtomicString::Con
structFromLiteral)); |
254 element()->userAgentShadowRoot()->appendChild(button.release()); | 254 element().userAgentShadowRoot()->appendChild(button.release()); |
255 } | 255 } |
256 | 256 |
257 void FileInputType::disabledAttributeChanged() | 257 void FileInputType::disabledAttributeChanged() |
258 { | 258 { |
259 ASSERT(element()->shadow()); | 259 ASSERT(element().shadow()); |
260 if (Element* button = toElement(element()->userAgentShadowRoot()->firstChild
())) | 260 if (Element* button = toElement(element().userAgentShadowRoot()->firstChild(
))) |
261 button->setBooleanAttribute(disabledAttr, element()->isDisabledFormContr
ol()); | 261 button->setBooleanAttribute(disabledAttr, element().isDisabledFormContro
l()); |
262 } | 262 } |
263 | 263 |
264 void FileInputType::multipleAttributeChanged() | 264 void FileInputType::multipleAttributeChanged() |
265 { | 265 { |
266 ASSERT(element()->shadow()); | 266 ASSERT(element().shadow()); |
267 if (Element* button = toElement(element()->userAgentShadowRoot()->firstChild
())) | 267 if (Element* button = toElement(element().userAgentShadowRoot()->firstChild(
))) |
268 button->setAttribute(valueAttr, locale().queryString(element()->multiple
() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString
::FileButtonChooseFileLabel)); | 268 button->setAttribute(valueAttr, locale().queryString(element().multiple(
) ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString:
:FileButtonChooseFileLabel)); |
269 } | 269 } |
270 | 270 |
271 void FileInputType::setFiles(PassRefPtr<FileList> files) | 271 void FileInputType::setFiles(PassRefPtr<FileList> files) |
272 { | 272 { |
273 if (!files) | 273 if (!files) |
274 return; | 274 return; |
275 | 275 |
276 RefPtr<HTMLInputElement> input = element(); | 276 RefPtr<HTMLInputElement> input(element()); |
277 | 277 |
278 bool pathsChanged = false; | 278 bool pathsChanged = false; |
279 if (files->length() != m_fileList->length()) { | 279 if (files->length() != m_fileList->length()) { |
280 pathsChanged = true; | 280 pathsChanged = true; |
281 } else { | 281 } else { |
282 for (unsigned i = 0; i < files->length(); ++i) { | 282 for (unsigned i = 0; i < files->length(); ++i) { |
283 if (files->item(i)->path() != m_fileList->item(i)->path()) { | 283 if (files->item(i)->path() != m_fileList->item(i)->path()) { |
284 pathsChanged = true; | 284 pathsChanged = true; |
285 break; | 285 break; |
286 } | 286 } |
(...skipping 23 matching lines...) Expand all Loading... |
310 | 310 |
311 void FileInputType::filesChosen(const Vector<FileChooserFileInfo>& files) | 311 void FileInputType::filesChosen(const Vector<FileChooserFileInfo>& files) |
312 { | 312 { |
313 setFiles(createFileList(files)); | 313 setFiles(createFileList(files)); |
314 } | 314 } |
315 | 315 |
316 void FileInputType::receiveDropForDirectoryUpload(const Vector<String>& paths) | 316 void FileInputType::receiveDropForDirectoryUpload(const Vector<String>& paths) |
317 { | 317 { |
318 if (Chrome* chrome = this->chrome()) { | 318 if (Chrome* chrome = this->chrome()) { |
319 FileChooserSettings settings; | 319 FileChooserSettings settings; |
320 HTMLInputElement* input = element(); | 320 HTMLInputElement& input = element(); |
321 settings.allowsDirectoryUpload = true; | 321 settings.allowsDirectoryUpload = true; |
322 settings.allowsMultipleFiles = true; | 322 settings.allowsMultipleFiles = true; |
323 settings.selectedFiles.append(paths[0]); | 323 settings.selectedFiles.append(paths[0]); |
324 settings.acceptMIMETypes = input->acceptMIMETypes(); | 324 settings.acceptMIMETypes = input.acceptMIMETypes(); |
325 settings.acceptFileExtensions = input->acceptFileExtensions(); | 325 settings.acceptFileExtensions = input.acceptFileExtensions(); |
326 chrome->enumerateChosenDirectory(newFileChooser(settings)); | 326 chrome->enumerateChosenDirectory(newFileChooser(settings)); |
327 } | 327 } |
328 } | 328 } |
329 | 329 |
330 bool FileInputType::receiveDroppedFiles(const DragData* dragData) | 330 bool FileInputType::receiveDroppedFiles(const DragData* dragData) |
331 { | 331 { |
332 Vector<String> paths; | 332 Vector<String> paths; |
333 dragData->asFilenames(paths); | 333 dragData->asFilenames(paths); |
334 if (paths.isEmpty()) | 334 if (paths.isEmpty()) |
335 return false; | 335 return false; |
336 | 336 |
337 HTMLInputElement* input = element(); | 337 HTMLInputElement& input = element(); |
338 if (input->fastHasAttribute(webkitdirectoryAttr) && RuntimeEnabledFeatures::
directoryUploadEnabled()) { | 338 if (input.fastHasAttribute(webkitdirectoryAttr) && RuntimeEnabledFeatures::d
irectoryUploadEnabled()) { |
339 receiveDropForDirectoryUpload(paths); | 339 receiveDropForDirectoryUpload(paths); |
340 return true; | 340 return true; |
341 } | 341 } |
342 | 342 |
343 m_droppedFileSystemId = dragData->droppedFileSystemId(); | 343 m_droppedFileSystemId = dragData->droppedFileSystemId(); |
344 | 344 |
345 Vector<FileChooserFileInfo> files; | 345 Vector<FileChooserFileInfo> files; |
346 for (unsigned i = 0; i < paths.size(); ++i) | 346 for (unsigned i = 0; i < paths.size(); ++i) |
347 files.append(FileChooserFileInfo(paths[i])); | 347 files.append(FileChooserFileInfo(paths[i])); |
348 | 348 |
349 if (input->fastHasAttribute(multipleAttr)) { | 349 if (input.fastHasAttribute(multipleAttr)) { |
350 filesChosen(files); | 350 filesChosen(files); |
351 } else { | 351 } else { |
352 Vector<FileChooserFileInfo> firstFileOnly; | 352 Vector<FileChooserFileInfo> firstFileOnly; |
353 firstFileOnly.append(files[0]); | 353 firstFileOnly.append(files[0]); |
354 filesChosen(firstFileOnly); | 354 filesChosen(firstFileOnly); |
355 } | 355 } |
356 return true; | 356 return true; |
357 } | 357 } |
358 | 358 |
359 String FileInputType::droppedFileSystemId() | 359 String FileInputType::droppedFileSystemId() |
(...skipping 12 matching lines...) Expand all Loading... |
372 StringBuilder names; | 372 StringBuilder names; |
373 for (size_t i = 0; i < listSize; ++i) { | 373 for (size_t i = 0; i < listSize; ++i) { |
374 names.append(fileList->item(i)->name()); | 374 names.append(fileList->item(i)->name()); |
375 if (i != listSize - 1) | 375 if (i != listSize - 1) |
376 names.append('\n'); | 376 names.append('\n'); |
377 } | 377 } |
378 return names.toString(); | 378 return names.toString(); |
379 } | 379 } |
380 | 380 |
381 } // namespace WebCore | 381 } // namespace WebCore |
OLD | NEW |