mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
feat: display file chosen for input file (#35789)
Signed-off-by: DK Liao <dklassic@gmail.com>
This commit is contained in:
parent
34047f8da8
commit
ce4ba30992
3 changed files with 53 additions and 5 deletions
|
@ -6,6 +6,7 @@ use std::slice::Iter;
|
|||
|
||||
use dom_struct::dom_struct;
|
||||
|
||||
use super::bindings::root::{LayoutDom, ToLayout};
|
||||
use crate::dom::bindings::codegen::Bindings::FileListBinding::FileListMethods;
|
||||
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
|
@ -69,3 +70,23 @@ impl FileListMethods<crate::DomTypeHolder> for FileList {
|
|||
self.Item(index)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait LayoutFileListHelpers<'dom> {
|
||||
fn file_for_layout(&self, index: u32) -> Option<&File>;
|
||||
fn len(&self) -> usize;
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
impl<'dom> LayoutFileListHelpers<'dom> for LayoutDom<'dom, FileList> {
|
||||
fn len(&self) -> usize {
|
||||
self.unsafe_get().list.len()
|
||||
}
|
||||
fn file_for_layout(&self, index: u32) -> Option<&File> {
|
||||
let list = &self.unsafe_get().list;
|
||||
if (index as usize) < list.len() {
|
||||
Some(unsafe { list[index as usize].to_layout().unsafe_get() })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers};
|
|||
use crate::dom::event::{Event, EventBubbles, EventCancelable};
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::file::File;
|
||||
use crate::dom::filelist::FileList;
|
||||
use crate::dom::filelist::{FileList, LayoutFileListHelpers};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::htmldatalistelement::HTMLDataListElement;
|
||||
use crate::dom::htmlelement::HTMLElement;
|
||||
|
@ -90,6 +90,7 @@ use crate::textinput::{
|
|||
const DEFAULT_SUBMIT_VALUE: &str = "Submit";
|
||||
const DEFAULT_RESET_VALUE: &str = "Reset";
|
||||
const PASSWORD_REPLACEMENT_CHAR: char = '●';
|
||||
const DEFAULT_FILE_INPUT_VALUE: &str = "No file chosen";
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#attr-input-type>
|
||||
#[derive(Clone, Copy, Default, JSTraceable, PartialEq)]
|
||||
|
@ -1037,6 +1038,9 @@ impl<'dom> LayoutDom<'dom, HTMLInputElement> {
|
|||
.get_content()
|
||||
}
|
||||
}
|
||||
fn get_filelist(self) -> Option<LayoutDom<'dom, FileList>> {
|
||||
unsafe { self.unsafe_get().filelist.get_inner_as_layout() }
|
||||
}
|
||||
|
||||
fn placeholder(self) -> &'dom str {
|
||||
unsafe { self.unsafe_get().placeholder.borrow_for_layout() }
|
||||
|
@ -1070,8 +1074,27 @@ impl<'dom> LayoutHTMLInputElementHelpers<'dom> for LayoutDom<'dom, HTMLInputElem
|
|||
}
|
||||
|
||||
match self.input_type() {
|
||||
InputType::Checkbox | InputType::Radio => "".into(),
|
||||
InputType::File | InputType::Image => "".into(),
|
||||
InputType::Checkbox | InputType::Radio | InputType::Image => "".into(),
|
||||
InputType::File => {
|
||||
let filelist = self.get_filelist();
|
||||
match filelist {
|
||||
Some(filelist) => {
|
||||
let length = filelist.len();
|
||||
if length == 0 {
|
||||
return DEFAULT_FILE_INPUT_VALUE.into();
|
||||
}
|
||||
if length == 1 {
|
||||
match filelist.file_for_layout(0) {
|
||||
Some(file) => return file.name().to_string().into(),
|
||||
None => return DEFAULT_FILE_INPUT_VALUE.into(),
|
||||
}
|
||||
}
|
||||
|
||||
format!("{} files", length).into()
|
||||
},
|
||||
None => DEFAULT_FILE_INPUT_VALUE.into(),
|
||||
}
|
||||
},
|
||||
InputType::Button => get_raw_attr_value(self, ""),
|
||||
InputType::Submit => get_raw_attr_value(self, DEFAULT_SUBMIT_VALUE),
|
||||
InputType::Reset => get_raw_attr_value(self, DEFAULT_RESET_VALUE),
|
||||
|
|
|
@ -74,13 +74,17 @@ input[type="radio"]:checked::before { content: "●"; line-height: 1em; }
|
|||
|
||||
input[type="file"]::before {
|
||||
content: "Choose File";
|
||||
background: lightgrey;
|
||||
border-top: solid 1px #EEEEEE;
|
||||
border-left: solid 1px #CCCCCC;
|
||||
border-right: solid 1px #999999;
|
||||
border-bottom: solid 1px #999999;
|
||||
}
|
||||
|
||||
input[type="file"] {
|
||||
background: lightgrey;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
color: black;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
select {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue