mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
merge from master
This commit is contained in:
commit
6e774ea6eb
1044 changed files with 46059 additions and 1506 deletions
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue