diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index bb51ee432fd..0d9beb8bf29 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -12,7 +12,6 @@ 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; @@ -542,66 +541,13 @@ impl Element { true // whatwg/html#5239 } - /// https://html.spec.whatwg.org/#the-directionality + // https://html.spec.whatwg.org/multipage/#the-directionality pub fn directionality(&self) -> String { - if self.is::() { - let htmlElement = self.downcast::().unwrap(); - self.html_element_directionality(&htmlElement.Dir()) + if let Some(html_element) = self.downcast::() { + html_element.directionality() } else { let node = self.upcast::(); - 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::() { - let input = self.downcast::().unwrap(); - return input.directionality(element_direction); - } - - if self.is::() { - let area = self.downcast::().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::(); - 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::() { - return "ltr".to_owned(); - } - - return if parent.is::() { - let parentHtml = parent.downcast::().unwrap(); - parentHtml.directionality() - } else { - self.parent_directionality(&*parent) - }; - }, - None => "ltr".to_owned(), + node.parent_directionality() } } } diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs index 48401acc3fd..81f3f823711 100644 --- a/components/script/dom/htmlelement.rs +++ b/components/script/dom/htmlelement.rs @@ -27,6 +27,7 @@ use crate::dom::htmlframesetelement::HTMLFrameSetElement; use crate::dom::htmlhtmlelement::HTMLHtmlElement; use crate::dom::htmlinputelement::{HTMLInputElement, InputType}; use crate::dom::htmllabelelement::HTMLLabelElement; +use crate::dom::htmltextareaelement::HTMLTextAreaElement; use crate::dom::node::{document_from_node, window_from_node}; use crate::dom::node::{BindContext, Node, NodeFlags, ShadowIncluding}; use crate::dom::text::Text; @@ -170,9 +171,9 @@ 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 + // https://html.spec.whatwg.org/multipage/#the-dir-attribute make_getter!(Dir, "dir"); - // https://html.spec.whatwg.org/multipage/dom.html#the-dir-attribute + // https://html.spec.whatwg.org/multipage/#the-dir-attribute make_setter!(SetDir, "dir"); // https://html.spec.whatwg.org/multipage/#globaleventhandlers @@ -772,6 +773,39 @@ impl HTMLElement { }) .count() as u32 } + + pub fn directionality(&self) -> String { + println!("HTMLElement#directionality"); + let element_direction: &str = &self.Dir(); + println!("HTMLElement#element_direction={}", element_direction); + + if element_direction == "ltr" { + return "ltr".to_owned(); + } + + if element_direction == "rtl" { + return "rtl".to_owned(); + } + + if element_direction == "auto" { + if let Some(directionality) = self.downcast::().and_then(|input| input.auto_directionality()) { + return directionality; + } + + if let Some(area) = self.downcast::() { + return area.auto_directionality(); + } + } + + // TODO(NeverHappened): 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/multipage/#the-bdi-element) + + let node = self.upcast::(); + node.parent_directionality() + } } impl VirtualMethods for HTMLElement { diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 6f4d788fa6b..b603ec70527 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -951,6 +951,18 @@ impl HTMLFormElement { HTMLElementTypeId::HTMLInputElement => { let input = child.downcast::().unwrap(); data_set.append(&mut input.form_datums(submitter, encoding)); + + let input_html_element = child.downcast::().unwrap(); + let dirname: DOMString = input.DirName(); + if !dirname.is_empty() { + let directionality = + DOMString::from(input_html_element.directionality()); + data_set.push(FormDatum { + ty: input.Type().clone(), + name: dirname.clone(), + value: FormDatumValue::String(directionality), + }); + } }, HTMLElementTypeId::HTMLButtonElement => { let button = child.downcast::().unwrap(); @@ -976,6 +988,18 @@ impl HTMLFormElement { value: FormDatumValue::String(textarea.Value()), }); } + + let area_html_element = child.downcast::().unwrap(); + let dirname: DOMString = textarea.DirName(); + if !dirname.is_empty() { + let directionality = + DOMString::from(area_html_element.directionality()); + data_set.push(FormDatum { + ty: textarea.Type().clone(), + name: dirname.clone(), + value: FormDatumValue::String(directionality), + }); + } }, _ => (), } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 7141f9a4537..bc503fd1fda 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -328,22 +328,18 @@ impl HTMLInputElement { ) } - pub fn directionality(&self, element_direction: &str) -> String { + pub fn auto_directionality(&self) -> Option { match self.input_type() { - InputType::Tel => return "ltr".to_owned(), + InputType::Tel => return Some("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); - } + let value: String = self.Value().to_string(); + Some(HTMLInputElement::directionality_from_value(&value)) }, - _ => {}, + _ => None, } - - return "ltr".to_owned(); } - pub fn auto_directionality(value: &str) -> String { + pub fn directionality_from_value(value: &str) -> String { if HTMLInputElement::first_strong_character_is_rtl(value) { "rtl".to_owned() } else { @@ -1473,25 +1469,11 @@ impl HTMLInputElement { } // Step 5.12 - let mut result = vec![FormDatum { + vec![FormDatum { ty: ty.clone(), name: name, value: FormDatumValue::String(self.Value()), - }]; - - // 4.10.18.2 - // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submitting-element-directionality:-the-dirname-attribute - let dirname: DOMString = self.DirName(); - let directionality = DOMString::from(self.directionality("auto")); - if !dirname.is_empty() { - result.push(FormDatum { - ty: ty.clone(), - name: dirname.clone(), - value: FormDatumValue::String(directionality), - }); - } - - result + }] } // https://html.spec.whatwg.org/multipage/#radio-button-group diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index 0cc174cc3c1..d077d9eec8f 100755 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -174,12 +174,9 @@ 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(); + pub fn auto_directionality(&self) -> String { + let value: String = self.Value().to_string(); + return HTMLInputElement::directionality_from_value(&value); } fn update_placeholder_shown_state(&self) { @@ -214,6 +211,12 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement { // https://html.spec.whatwg.org/multipage/#dom-textarea-cols make_limited_uint_setter!(SetCols, "cols", DEFAULT_COLS); + // https://html.spec.whatwg.org/multipage/#dom-input-dirName + make_getter!(DirName, "dirname"); + + // https://html.spec.whatwg.org/multipage/#dom-input-dirName + make_setter!(SetDirName, "dirname"); + // https://html.spec.whatwg.org/multipage/#dom-fe-disabled make_bool_getter!(Disabled, "disabled"); diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 457c1f0d55c..1ecafaf3bf3 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -432,6 +432,25 @@ impl Node { .upcast::() .dispatch(self.upcast::(), false); } + + pub fn parent_directionality(&self) -> String { + println!("Node#parent_directionality"); + match self.GetParentNode() { + Some(parent) => { + if parent.is::() { + return "ltr".to_owned(); + } + + println!("Node#parent_directionality Some(Parent)"); + return if let Some(parent_html) = parent.downcast::() { + parent_html.directionality() + } else { + parent.parent_directionality() + }; + }, + None => "ltr".to_owned(), + } + } } pub struct QuerySelectorIterator { diff --git a/components/script/dom/webidls/HTMLTextAreaElement.webidl b/components/script/dom/webidls/HTMLTextAreaElement.webidl index 99cf18e0c10..b09200f1dc5 100644 --- a/components/script/dom/webidls/HTMLTextAreaElement.webidl +++ b/components/script/dom/webidls/HTMLTextAreaElement.webidl @@ -13,8 +13,8 @@ interface HTMLTextAreaElement : HTMLElement { // attribute boolean autofocus; [CEReactions, SetterThrows] attribute unsigned long cols; - // [CEReactions] - // attribute DOMString dirName; + [CEReactions] + attribute DOMString dirName; [CEReactions] attribute boolean disabled; readonly attribute HTMLFormElement? form; diff --git a/tests/wpt/web-platform-tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl-inherited.html b/tests/wpt/web-platform-tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl-inherited.html new file mode 100644 index 00000000000..1e6967d914a --- /dev/null +++ b/tests/wpt/web-platform-tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl-inherited.html @@ -0,0 +1,38 @@ + + +Submitting element directionality: the dirname attribute + + + + +
+
+
+

+

+
+
+ + diff --git a/tests/wpt/web-platform-tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl.html b/tests/wpt/web-platform-tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl.html index 92bf2c3c92b..6368a26fafd 100644 --- a/tests/wpt/web-platform-tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl.html +++ b/tests/wpt/web-platform-tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl.html @@ -7,7 +7,7 @@
-

+