diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-07-09 02:02:34 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-07-09 02:02:34 -0700 |
commit | 8cb05a36bc1a20ec6373ddb23ce127c7801ba5d6 (patch) | |
tree | 85a294c6d17493671656f7f32db52c18f824ae71 /components/script/dom | |
parent | c2a22bd05e0c8282175422df26e188ef63bcc452 (diff) | |
parent | 5e051c08f69cb17d610c14b208c68fc4896c55ba (diff) | |
download | servo-8cb05a36bc1a20ec6373ddb23ce127c7801ba5d6.tar.gz servo-8cb05a36bc1a20ec6373ddb23ce127c7801ba5d6.zip |
Auto merge of #12344 - izgzhen:set-file-js, r=Manishearth
Add ability to WPT-test file uploads and fetches, fixes #12322
Using `inputElem.selectFiles(["path1", "path2"])` in JavaScript with pref `dom.htmlinputelement.select_files.enabled` = `true` will simulate the effect of `inputElem.click()`.
See #12322 for more, also related to #12343.
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/12344)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/htmlinputelement.rs | 144 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLInputElement.webidl | 5 |
2 files changed, 90 insertions, 59 deletions
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 0ee2023e44a..d8acc2dbe75 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -579,6 +579,16 @@ impl HTMLInputElementMethods for HTMLInputElement { EventCancelable::NotCancelable); self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage); } + + // Select the files based on filepaths passed in, + // enabled by dom.htmlinputelement.select_files.enabled, + // used for test purpose. + // check-tidy: no specs after this line + fn SelectFiles(&self, paths: Vec<DOMString>) { + if self.input_type.get() == InputType::InputFile { + self.select_files(Some(paths)); + } + } } @@ -731,6 +741,80 @@ impl HTMLInputElement { let el = self.upcast::<Element>(); el.set_placeholder_shown_state(has_placeholder && !has_value); } + + // https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file) + // Select files by invoking UI or by passed in argument + fn select_files(&self, opt_test_paths: Option<Vec<DOMString>>) { + let window = window_from_node(self); + let origin = window.get_url().origin().unicode_serialization(); + let filemanager = window.resource_threads().sender(); + + let mut files: Vec<Root<File>> = vec![]; + let mut error = None; + + let filter = filter_from_accept(&self.Accept()); + let target = self.upcast::<EventTarget>(); + + if self.Multiple() { + let opt_test_paths = opt_test_paths.map(|paths| paths.iter().map(|p| p.to_string()).collect()); + + let (chan, recv) = ipc::channel().expect("Error initializing channel"); + let msg = FileManagerThreadMsg::SelectFiles(filter, chan, origin, opt_test_paths); + let _ = filemanager.send(msg).unwrap(); + + match recv.recv().expect("IpcSender side error") { + Ok(selected_files) => { + for selected in selected_files { + files.push(File::new_from_selected(window.r(), selected)); + } + + target.fire_event("input", + EventBubbles::Bubbles, + EventCancelable::NotCancelable); + target.fire_event("change", + EventBubbles::Bubbles, + EventCancelable::NotCancelable); + }, + Err(err) => error = Some(err), + }; + } else { + let opt_test_path = match opt_test_paths { + Some(paths) => { + if paths.len() == 0 { + return; + } else { + Some(paths[0].to_string()) // neglect other paths + } + } + None => None, + }; + + let (chan, recv) = ipc::channel().expect("Error initializing channel"); + let msg = FileManagerThreadMsg::SelectFile(filter, chan, origin, opt_test_path); + let _ = filemanager.send(msg).unwrap(); + + match recv.recv().expect("IpcSender side error") { + Ok(selected) => { + files.push(File::new_from_selected(window.r(), selected)); + + target.fire_event("input", + EventBubbles::Bubbles, + EventCancelable::NotCancelable); + target.fire_event("change", + EventBubbles::Bubbles, + EventCancelable::NotCancelable); + }, + Err(err) => error = Some(err), + }; + } + + if let Some(err) = error { + debug!("Input file select error: {:?}", err); + } else { + let filelist = FileList::new(window.r(), files); + self.filelist.set(Some(&filelist)); + } + } } impl VirtualMethods for HTMLInputElement { @@ -1149,65 +1233,7 @@ impl Activatable for HTMLInputElement { EventBubbles::Bubbles, EventCancelable::NotCancelable); }, - InputType::InputFile => { - // https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file) - let window = window_from_node(self); - let origin = window.get_url().origin().unicode_serialization(); - let filemanager = window.resource_threads().sender(); - - let mut files: Vec<Root<File>> = vec![]; - let mut error = None; - - let filter = filter_from_accept(&self.Accept()); - let target = self.upcast::<EventTarget>(); - - if self.Multiple() { - let (chan, recv) = ipc::channel().expect("Error initializing channel"); - let msg = FileManagerThreadMsg::SelectFiles(filter, chan, origin); - let _ = filemanager.send(msg).unwrap(); - - match recv.recv().expect("IpcSender side error") { - Ok(selected_files) => { - for selected in selected_files { - files.push(File::new_from_selected(window.r(), selected)); - } - - target.fire_event("input", - EventBubbles::Bubbles, - EventCancelable::NotCancelable); - target.fire_event("change", - EventBubbles::Bubbles, - EventCancelable::NotCancelable); - }, - Err(err) => error = Some(err), - }; - } else { - let (chan, recv) = ipc::channel().expect("Error initializing channel"); - let msg = FileManagerThreadMsg::SelectFile(filter, chan, origin); - let _ = filemanager.send(msg).unwrap(); - - match recv.recv().expect("IpcSender side error") { - Ok(selected) => { - files.push(File::new_from_selected(window.r(), selected)); - - target.fire_event("input", - EventBubbles::Bubbles, - EventCancelable::NotCancelable); - target.fire_event("change", - EventBubbles::Bubbles, - EventCancelable::NotCancelable); - }, - Err(err) => error = Some(err), - }; - } - - if let Some(err) = error { - debug!("Input file select error: {:?}", err); - } else { - let filelist = FileList::new(window.r(), files); - self.filelist.set(Some(&filelist)); - } - } + InputType::InputFile => self.select_files(None), _ => () } } diff --git a/components/script/dom/webidls/HTMLInputElement.webidl b/components/script/dom/webidls/HTMLInputElement.webidl index d145e498659..1d6160b14cd 100644 --- a/components/script/dom/webidls/HTMLInputElement.webidl +++ b/components/script/dom/webidls/HTMLInputElement.webidl @@ -70,6 +70,11 @@ interface HTMLInputElement : HTMLElement { void setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); // also has obsolete members + + // Select with file-system paths for testing purpose + [Pref="dom.testing.htmlinputelement.select_files.enabled"] + void selectFiles(sequence<DOMString> path); + }; // https://html.spec.whatwg.org/multipage/#HTMLInputElement-partial |