mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Rearrange directionality algorithm functions
This commit is contained in:
parent
cb34e5c887
commit
7d6d1c09cb
9 changed files with 141 additions and 95 deletions
|
@ -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::<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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<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 {
|
||||
|
|
|
@ -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();
|
||||
|
@ -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),
|
||||
});
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue