mirror of
https://github.com/servo/servo.git
synced 2025-07-31 03:00:29 +01:00
Implement dirname for form submit and directionality for element
This commit is contained in:
parent
6bc4a7df24
commit
ef49f2e0eb
14 changed files with 178 additions and 19 deletions
|
@ -110,6 +110,7 @@ style_traits = {path = "../style_traits"}
|
|||
swapper = "0.1"
|
||||
tendril = {version = "0.4.1", features = ["encoding_rs"]}
|
||||
time = "0.1.12"
|
||||
unicode-bidi = "0.3.4"
|
||||
unicode-segmentation = "1.1.0"
|
||||
url = "2.0"
|
||||
utf-8 = "0.7"
|
||||
|
|
|
@ -12,6 +12,7 @@ use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
|||
use crate::dom::bindings::codegen::Bindings::ElementBinding;
|
||||
use crate::dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementBinding::HTMLElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::ShadowRootBinding::ShadowRootMethods;
|
||||
|
@ -540,6 +541,69 @@ impl Element {
|
|||
}
|
||||
true // whatwg/html#5239
|
||||
}
|
||||
|
||||
/// https://html.spec.whatwg.org/#the-directionality
|
||||
pub fn directionality(&self) -> String {
|
||||
if self.is::<HTMLElement>() {
|
||||
let htmlElement = self.downcast::<HTMLElement>().unwrap();
|
||||
self.html_element_directionality(&htmlElement.Dir())
|
||||
} else {
|
||||
let node = self.upcast::<Node>();
|
||||
self.parent_directionality(node)
|
||||
}
|
||||
}
|
||||
|
||||
fn html_element_directionality(&self, element_direction: &str) -> String {
|
||||
if element_direction == "ltr" {
|
||||
return "ltr".to_owned();
|
||||
}
|
||||
|
||||
if element_direction == "rtl" {
|
||||
return "rtl".to_owned();
|
||||
}
|
||||
|
||||
if self.is::<HTMLInputElement>() {
|
||||
let input = self.downcast::<HTMLInputElement>().unwrap();
|
||||
return input.directionality(element_direction);
|
||||
}
|
||||
|
||||
if self.is::<HTMLTextAreaElement>() {
|
||||
let area = self.downcast::<HTMLTextAreaElement>().unwrap();
|
||||
return area.directionality(element_direction);
|
||||
}
|
||||
|
||||
// TODO(dmitry.klpv): Implement condition
|
||||
// If the element's dir attribute is in the auto state OR
|
||||
// If the element is a bdi element and the dir attribute is not in a defined state
|
||||
// (i.e. it is not present or has an invalid value)
|
||||
// Requires bdi element implementation (https://html.spec.whatwg.org/#the-bdi-element)
|
||||
|
||||
let node = self.upcast::<Node>();
|
||||
self.parent_directionality(node)
|
||||
}
|
||||
|
||||
fn parent_directionality(&self, node: &Node) -> String {
|
||||
if !node.has_parent() {
|
||||
return "ltr".to_owned();
|
||||
}
|
||||
|
||||
let parent = node.GetParentNode();
|
||||
match parent {
|
||||
Some(parent) => {
|
||||
if parent.is::<Document>() {
|
||||
return "ltr".to_owned();
|
||||
}
|
||||
|
||||
return if parent.is::<Element>() {
|
||||
let parentHtml = parent.downcast::<Element>().unwrap();
|
||||
parentHtml.directionality()
|
||||
} else {
|
||||
self.parent_directionality(&*parent)
|
||||
};
|
||||
},
|
||||
None => "ltr".to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
|
|
@ -170,6 +170,11 @@ impl HTMLElementMethods for HTMLElement {
|
|||
// https://html.spec.whatwg.org/multipage/#dom-hidden
|
||||
make_bool_setter!(SetHidden, "hidden");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/dom.html#the-dir-attribute
|
||||
make_getter!(Dir, "dir");
|
||||
// https://html.spec.whatwg.org/multipage/dom.html#the-dir-attribute
|
||||
make_setter!(SetDir, "dir");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#globaleventhandlers
|
||||
global_event_handlers!(NoOnload);
|
||||
|
||||
|
|
|
@ -745,6 +745,8 @@ impl HTMLFormElement {
|
|||
.map(|field| (&*field.name, field.replace_value(charset))),
|
||||
);
|
||||
|
||||
println!("New URL: {url}", url = &load_data.url);
|
||||
|
||||
self.plan_to_navigate(load_data, target);
|
||||
}
|
||||
|
||||
|
@ -952,6 +954,20 @@ impl HTMLFormElement {
|
|||
let input = child.downcast::<HTMLInputElement>().unwrap();
|
||||
|
||||
data_set.append(&mut input.form_datums(submitter, encoding));
|
||||
|
||||
// TODO: probably move to input.form_datums(...) function
|
||||
// 4.10.18.2 https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submitting-element-directionality:-the-dirname-attribute
|
||||
let dirname: DOMString = input.DirName();
|
||||
let dirname_str: &str = &*dirname;
|
||||
if !dirname_str.is_empty() {
|
||||
data_set.push(FormDatum {
|
||||
ty: input.Type(),
|
||||
name: DOMString::from_string(dirname_str.to_owned()),
|
||||
value: FormDatumValue::String(DOMString::from(
|
||||
input.directionality("auto"),
|
||||
)),
|
||||
});
|
||||
}
|
||||
},
|
||||
HTMLElementTypeId::HTMLButtonElement => {
|
||||
let button = child.downcast::<HTMLButtonElement>().unwrap();
|
||||
|
@ -983,8 +999,6 @@ impl HTMLFormElement {
|
|||
}
|
||||
}
|
||||
data_set
|
||||
// TODO: Handle `dirnames` (needs directionality support)
|
||||
// https://html.spec.whatwg.org/multipage/#the-directionality
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#constructing-the-form-data-set>
|
||||
|
|
|
@ -75,6 +75,7 @@ use std::ptr::NonNull;
|
|||
use style::attr::AttrValue;
|
||||
use style::element_state::ElementState;
|
||||
use style::str::{split_commas, str_join};
|
||||
use unicode_bidi::{bidi_class, BidiClass};
|
||||
|
||||
const DEFAULT_SUBMIT_VALUE: &'static str = "Submit";
|
||||
const DEFAULT_RESET_VALUE: &'static str = "Reset";
|
||||
|
@ -327,6 +328,41 @@ impl HTMLInputElement {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn directionality(&self, element_direction: &str) -> String {
|
||||
match self.input_type() {
|
||||
InputType::Tel => return "ltr".to_owned(),
|
||||
InputType::Text | InputType::Search | InputType::Url | InputType::Email => {
|
||||
if element_direction == "auto" {
|
||||
let value: String = self.Value().to_string();
|
||||
return HTMLInputElement::auto_directionality(&value);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
return "ltr".to_owned();
|
||||
}
|
||||
|
||||
pub fn auto_directionality(value: &str) -> String {
|
||||
if HTMLInputElement::first_strong_character_is_rtl(value) {
|
||||
"rtl".to_owned()
|
||||
} else {
|
||||
"ltr".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
fn first_strong_character_is_rtl(value: &str) -> bool {
|
||||
for ch in value.chars() {
|
||||
return match bidi_class(ch) {
|
||||
BidiClass::L => false,
|
||||
BidiClass::AL => true,
|
||||
BidiClass::R => true,
|
||||
_ => continue,
|
||||
};
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-input-value
|
||||
// https://html.spec.whatwg.org/multipage/#concept-input-apply
|
||||
fn value_mode(&self) -> ValueMode {
|
||||
|
|
|
@ -22,6 +22,7 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use crate::dom::htmlelement::HTMLElement;
|
||||
use crate::dom::htmlfieldsetelement::HTMLFieldSetElement;
|
||||
use crate::dom::htmlformelement::{FormControl, HTMLFormElement};
|
||||
use crate::dom::htmlinputelement::HTMLInputElement;
|
||||
use crate::dom::keyboardevent::KeyboardEvent;
|
||||
use crate::dom::node::{document_from_node, window_from_node};
|
||||
use crate::dom::node::{
|
||||
|
@ -173,6 +174,14 @@ impl HTMLTextAreaElement {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn directionality(&self, element_direction: &str) -> String {
|
||||
if element_direction == "auto" {
|
||||
let value: String = self.Value().to_string();
|
||||
return HTMLInputElement::auto_directionality(&value);
|
||||
}
|
||||
return "ltr".to_owned();
|
||||
}
|
||||
|
||||
fn update_placeholder_shown_state(&self) {
|
||||
let has_placeholder = !self.placeholder.borrow().is_empty();
|
||||
let has_value = !self.textinput.borrow().is_empty();
|
||||
|
|
|
@ -14,8 +14,8 @@ interface HTMLElement : Element {
|
|||
attribute DOMString lang;
|
||||
[CEReactions]
|
||||
attribute boolean translate;
|
||||
// [CEReactions]
|
||||
// attribute DOMString dir;
|
||||
[CEReactions]
|
||||
attribute DOMString dir;
|
||||
readonly attribute DOMStringMap dataset;
|
||||
|
||||
// microdata
|
||||
|
|
|
@ -2017,6 +2017,7 @@ impl Window {
|
|||
}
|
||||
// TODO: step 11, navigationType.
|
||||
// Step 12, 13
|
||||
println!("ScriptThread::navigate");
|
||||
ScriptThread::navigate(pipeline_id, load_data, replace);
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue