aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlinputelement.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/htmlinputelement.rs')
-rw-r--r--components/script/dom/htmlinputelement.rs68
1 files changed, 62 insertions, 6 deletions
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index c2c76dd16e8..4eb1d4d9ba0 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -7,16 +7,19 @@ use dom::activation::{Activatable, ActivationSource, synthetic_click_activation}
use dom::attr::{Attr, AttrValue};
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
+use dom::bindings::codegen::Bindings::FileListBinding::FileListMethods;
use dom::bindings::codegen::Bindings::HTMLInputElementBinding;
use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
use dom::bindings::codegen::Bindings::KeyboardEventBinding::KeyboardEventMethods;
use dom::bindings::error::{Error, ErrorResult};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, LayoutJS, Root, RootedReference};
+use dom::bindings::js::{JS, LayoutJS, Root, RootedReference, MutNullableHeap};
use dom::document::Document;
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers, LayoutElementHelpers};
use dom::event::{Event, EventBubbles, EventCancelable};
use dom::eventtarget::EventTarget;
+use dom::file::File;
+use dom::filelist::FileList;
use dom::htmlelement::HTMLElement;
use dom::htmlfieldsetelement::HTMLFieldSetElement;
use dom::htmlformelement::{FormDatumValue, FormControl, FormDatum, FormSubmitter, HTMLFormElement};
@@ -27,7 +30,9 @@ use dom::node::{document_from_node, window_from_node};
use dom::nodelist::NodeList;
use dom::validation::Validatable;
use dom::virtualmethods::VirtualMethods;
-use ipc_channel::ipc::IpcSender;
+use ipc_channel::ipc::{self, IpcSender};
+use net_traits::IpcSend;
+use net_traits::filemanager_thread::FileManagerThreadMsg;
use script_traits::ScriptMsg as ConstellationMsg;
use std::borrow::ToOwned;
use std::cell::Cell;
@@ -81,7 +86,7 @@ pub struct HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#concept-input-value-dirty-flag
value_dirty: Cell<bool>,
- // TODO: selected files for file input
+ filelist: MutNullableHeap<JS<FileList>>,
}
#[derive(JSTraceable)]
@@ -130,6 +135,7 @@ impl HTMLInputElement {
textinput: DOMRefCell::new(TextInput::new(Single, DOMString::new(), chan, None, SelectionDirection::None)),
activation_state: DOMRefCell::new(InputActivationState::new()),
value_dirty: Cell::new(false),
+ filelist: MutNullableHeap::new(None),
}
}
@@ -354,8 +360,18 @@ impl HTMLInputElementMethods for HTMLInputElement {
|a| DOMString::from(a.summarize().value))
}
ValueMode::Filename => {
- // TODO: return C:\fakepath\<first of selected files> when a file is selected
- DOMString::from("")
+ let mut path = DOMString::from("");
+ match self.filelist.get() {
+ Some(ref fl) => match fl.Item(0) {
+ Some(ref f) => {
+ path.push_str("C:\\fakepath\\");
+ path.push_str(f.name());
+ path
+ }
+ None => path,
+ },
+ None => path,
+ }
}
}
}
@@ -373,7 +389,9 @@ impl HTMLInputElementMethods for HTMLInputElement {
}
ValueMode::Filename => {
if value.is_empty() {
- // TODO: empty list of selected files
+ let window = window_from_node(self);
+ let fl = FileList::new(window.r(), vec![]);
+ self.filelist.set(Some(&fl));
} else {
return Err(Error::InvalidState);
}
@@ -1096,6 +1114,44 @@ impl Activatable for HTMLInputElement {
EventBubbles::Bubbles,
EventCancelable::NotCancelable);
},
+ InputType::InputFile => {
+ let window = window_from_node(self);
+ let filemanager = window.resource_threads().sender();
+
+ let mut files: Vec<Root<File>> = vec![];
+ let mut error = None;
+
+ if self.Multiple() {
+ let (chan, recv) = ipc::channel().expect("Error initializing channel");
+ let msg = FileManagerThreadMsg::SelectFiles(chan);
+ 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));
+ }
+ },
+ Err(err) => error = Some(err),
+ };
+ } else {
+ let (chan, recv) = ipc::channel().expect("Error initializing channel");
+ let msg = FileManagerThreadMsg::SelectFile(chan);
+ let _ = filemanager.send(msg).unwrap();
+
+ match recv.recv().expect("IpcSender side error") {
+ Ok(selected) => files.push(File::new_from_selected(window.r(), selected)),
+ 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));
+ }
+ }
_ => ()
}
}