aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlelement.rs
diff options
context:
space:
mode:
authorrohan.prinja <rohan.prinja@samsung.com>2015-11-03 19:01:23 +0900
committerrohan.prinja <rohan.prinja@samsung.com>2015-11-03 19:01:23 +0900
commit6e774ea6eb6d719b98f924ab5bd0629d92fb27d0 (patch)
treefa48b89bb313a2e9514124b556bbcff5ed526a0f /components/script/dom/htmlelement.rs
parent7032a5d1dee9bb2ba0bee45f1fda984dadfa0609 (diff)
parent4f51710ed387baa1ad0a6e4cdb0fc5eee44093d5 (diff)
downloadservo-6e774ea6eb6d719b98f924ab5bd0629d92fb27d0.tar.gz
servo-6e774ea6eb6d719b98f924ab5bd0629d92fb27d0.zip
merge from master
Diffstat (limited to 'components/script/dom/htmlelement.rs')
-rw-r--r--components/script/dom/htmlelement.rs99
1 files changed, 95 insertions, 4 deletions
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index 8836d3aae69..43c319678c9 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -4,6 +4,7 @@
use dom::attr::Attr;
use dom::attr::AttrValue;
+use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::HTMLElementBinding;
use dom::bindings::codegen::Bindings::HTMLElementBinding::HTMLElementMethods;
@@ -12,21 +13,25 @@ use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::error::{Error, ErrorResult};
use dom::bindings::inheritance::Castable;
use dom::bindings::inheritance::{ElementTypeId, HTMLElementTypeId, NodeTypeId};
-use dom::bindings::js::{JS, MutNullableHeap, Root};
+use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
use dom::bindings::reflector::Reflectable;
use dom::cssstyledeclaration::{CSSModificationAccess, CSSStyleDeclaration};
use dom::document::Document;
use dom::domstringmap::DOMStringMap;
-use dom::element::{AttributeMutation, Element, EventState};
+use dom::element::{AttributeMutation, Element};
use dom::eventtarget::EventTarget;
use dom::htmlbodyelement::HTMLBodyElement;
use dom::htmlframesetelement::HTMLFrameSetElement;
use dom::htmlhtmlelement::HTMLHtmlElement;
use dom::htmlinputelement::HTMLInputElement;
+use dom::htmllabelelement::HTMLLabelElement;
use dom::node::{Node, SEQUENTIALLY_FOCUSABLE};
use dom::node::{document_from_node, window_from_node};
+use dom::nodelist::NodeList;
use dom::virtualmethods::VirtualMethods;
use msg::constellation_msg::FocusType;
+use selectors::states::*;
+use std::ascii::AsciiExt;
use std::borrow::ToOwned;
use std::default::Default;
use std::intrinsics;
@@ -50,10 +55,10 @@ impl PartialEq for HTMLElement {
impl HTMLElement {
pub fn new_inherited(tag_name: DOMString, prefix: Option<DOMString>,
document: &Document) -> HTMLElement {
- HTMLElement::new_inherited_with_state(EventState::empty(), tag_name, prefix, document)
+ HTMLElement::new_inherited_with_state(ElementState::empty(), tag_name, prefix, document)
}
- pub fn new_inherited_with_state(state: EventState, tag_name: DOMString,
+ pub fn new_inherited_with_state(state: ElementState, tag_name: DOMString,
prefix: Option<DOMString>, document: &Document)
-> HTMLElement {
HTMLElement {
@@ -275,6 +280,45 @@ fn to_snake_case(name: DOMString) -> DOMString {
attr_name
}
+
+// https://html.spec.whatwg.org/multipage/#attr-data-*
+// if this attribute is in snake case with a data- prefix,
+// this function returns a name converted to camel case
+// without the data prefix.
+
+fn to_camel_case(name: &str) -> Option<DOMString> {
+ if !name.starts_with("data-") {
+ return None;
+ }
+ let name = &name[5..];
+ let has_uppercase = name.chars().any(|curr_char| {
+ curr_char.is_ascii() && curr_char.is_uppercase()
+ });
+ if has_uppercase {
+ return None;
+ }
+ let mut result = "".to_owned();
+ let mut name_chars = name.chars();
+ while let Some(curr_char) = name_chars.next() {
+ //check for hyphen followed by character
+ if curr_char == '\x2d' {
+ if let Some(next_char) = name_chars.next() {
+ if next_char.is_ascii() && next_char.is_lowercase() {
+ result.push(next_char.to_ascii_uppercase());
+ } else {
+ result.push(curr_char);
+ result.push(next_char);
+ }
+ } else {
+ result.push(curr_char);
+ }
+ } else {
+ result.push(curr_char);
+ }
+ }
+ Some(result)
+}
+
impl HTMLElement {
pub fn set_custom_attr(&self, name: DOMString, value: DOMString) -> ErrorResult {
if name.chars()
@@ -316,6 +360,53 @@ impl HTMLElement {
_ => false,
}
}
+
+ pub fn supported_prop_names_custom_attr(&self) -> Vec<DOMString> {
+ let element = self.upcast::<Element>();
+ element.attrs().iter().filter_map(|attr| {
+ let raw_name = attr.local_name();
+ to_camel_case(&raw_name)
+ }).collect()
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-lfe-labels
+ pub fn labels(&self) -> Root<NodeList> {
+ debug_assert!(self.is_labelable_element());
+
+ let element = self.upcast::<Element>();
+ let window = window_from_node(element);
+
+ // Traverse ancestors for implicitly associated <label> elements
+ // https://html.spec.whatwg.org/multipage/#the-label-element:attr-label-for-4
+ let ancestors =
+ self.upcast::<Node>()
+ .ancestors()
+ .filter_map(Root::downcast::<HTMLElement>)
+ // If we reach a labelable element, we have a guarantee no ancestors above it
+ // will be a label for this HTMLElement
+ .take_while(|elem| !elem.is_labelable_element())
+ .filter_map(Root::downcast::<HTMLLabelElement>)
+ .filter(|elem| !elem.upcast::<Element>().has_attribute(&atom!("for")))
+ .filter(|elem| elem.first_labelable_descendant().r() == Some(self))
+ .map(Root::upcast::<Node>);
+
+ let id = element.Id();
+ let id = match &id as &str {
+ "" => return NodeList::new_simple_list(window.r(), ancestors),
+ id => id,
+ };
+
+ // Traverse entire tree for <label> elements with `for` attribute matching `id`
+ let root_element = element.get_root_element();
+ let root_node = root_element.upcast::<Node>();
+ let children = root_node.traverse_preorder()
+ .filter_map(Root::downcast::<Element>)
+ .filter(|elem| elem.is::<HTMLLabelElement>())
+ .filter(|elem| elem.get_string_attribute(&atom!("for")) == id)
+ .map(Root::upcast::<Node>);
+
+ NodeList::new_simple_list(window.r(), children.chain(ancestors))
+ }
}
impl VirtualMethods for HTMLElement {