Skip to content

Commit

Permalink
Rearrange directionality algorithm functions
Browse files Browse the repository at this point in the history
  • Loading branch information
NeverHappened committed Feb 24, 2020
1 parent cb34e5c commit 7d6d1c0
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 95 deletions.
62 changes: 4 additions & 58 deletions components/script/dom/element.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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::<HTMLElement>() {
let htmlElement = self.downcast::<HTMLElement>().unwrap();
self.html_element_directionality(&htmlElement.Dir())
if let Some(html_element) = self.downcast::<HTMLElement>() {
html_element.directionality()
} 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(),
node.parent_directionality()
}
}
}
Expand Down
38 changes: 36 additions & 2 deletions components/script/dom/htmlelement.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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::<HTMLInputElement>().and_then(|input| input.auto_directionality()) {
return directionality;
}

if let Some(area) = self.downcast::<HTMLTextAreaElement>() {
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>();
node.parent_directionality()
}
}

impl VirtualMethods for HTMLElement {
Expand Down
24 changes: 24 additions & 0 deletions components/script/dom/htmlformelement.rs
Expand Up @@ -951,6 +951,18 @@ impl HTMLFormElement {
HTMLElementTypeId::HTMLInputElement => {
let input = child.downcast::<HTMLInputElement>().unwrap();
data_set.append(&mut input.form_datums(submitter, encoding));

let input_html_element = child.downcast::<HTMLElement>().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::<HTMLButtonElement>().unwrap();
Expand All @@ -976,6 +988,18 @@ impl HTMLFormElement {
value: FormDatumValue::String(textarea.Value()),
});
}

let area_html_element = child.downcast::<HTMLElement>().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),
});
}
},
_ => (),
}
Expand Down
34 changes: 8 additions & 26 deletions components/script/dom/htmlinputelement.rs
Expand Up @@ -328,22 +328,18 @@ impl HTMLInputElement {
)
}

pub fn directionality(&self, element_direction: &str) -> String {
pub fn auto_directionality(&self) -> Option<String> {
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 {
Expand Down Expand Up @@ -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
Expand Down
15 changes: 9 additions & 6 deletions components/script/dom/htmltextareaelement.rs
Expand Up @@ -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) {
Expand Down Expand Up @@ -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");

Expand Down
19 changes: 19 additions & 0 deletions components/script/dom/node.rs
Expand Up @@ -432,6 +432,25 @@ impl Node {
.upcast::<Event>()
.dispatch(self.upcast::<EventTarget>(), false);
}

pub fn parent_directionality(&self) -> String {
println!("Node#parent_directionality");
match self.GetParentNode() {
Some(parent) => {
if parent.is::<Document>() {
return "ltr".to_owned();
}

println!("Node#parent_directionality Some(Parent)");
return if let Some(parent_html) = parent.downcast::<Element>() {
parent_html.directionality()
} else {
parent.parent_directionality()
};
},
None => "ltr".to_owned(),
}
}
}

pub struct QuerySelectorIterator {
Expand Down
4 changes: 2 additions & 2 deletions components/script/dom/webidls/HTMLTextAreaElement.webidl
Expand Up @@ -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;
Expand Down
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Submitting element directionality: the dirname attribute</title>
<link rel="author" title="Kolupaev Dmitry" href="mailto:dmitry.klpv@gmail.com">
<link rel=help href="https://html.spec.whatwg.org/multipage/#submitting-element-directionality:-the-dirname-attribute">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<div dir="rtl">
<form action="dirname-ltr-iframe.html" method=get target="iframe">
<p><label>Comment: <input type=text name="comment" dirname="comment.dir" required/></label></p>
<p><button type=submit>Post Comment</button></p>
</form>
</div>
<iframe name="iframe"></iframe>
<script>
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(document.querySelector("iframe").contentWindow.location.search);
return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

var t = async_test("submit element directionality");
document.querySelector("input").value = "foobar";
document.querySelector("button").click();

var iframe = document.querySelector("iframe");
iframe.onload = t.step_func(function() {
// The initial about:blank load event can be fired before the form navigation occurs.
// See https://github.com/whatwg/html/issues/490 for more information.
if(iframe.contentWindow.location.href == "about:blank") { return; }

assert_equals(getParameterByName("comment.dir"), "rtl");

t.done();
});
</script>
Expand Up @@ -7,7 +7,7 @@
<script src="/resources/testharnessreport.js"></script>
<div id="log"></div>
<form action="dirname-ltr-iframe.html" method=get target="iframe">
<p><label>Comment: <input type=text name="comment" dirname="comment.dir" required/></label></p>
<p><label>Comment: <input type=text name="comment" dir="auto" dirname="comment.dir" required/></label></p>
<p><button type=submit>Post Comment</button></p>
</form>
<iframe name="iframe"></iframe>
Expand Down

0 comments on commit 7d6d1c0

Please sign in to comment.