diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index e08e47f85fe..19901c43796 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -23,6 +23,7 @@ use dom::bindings::codegen::InheritTypes::{HTMLAreaElementDerived, HTMLEmbedElem use dom::bindings::codegen::InheritTypes::{HTMLFormElementDerived, HTMLImageElementDerived}; use dom::bindings::codegen::InheritTypes::{HTMLScriptElementDerived, HTMLTitleElementDerived}; use dom::bindings::codegen::UnionTypes::NodeOrString; +use dom::bindings::conversions::ToJSValConvertible; use dom::bindings::error::{ErrorResult, Fallible}; use dom::bindings::error::Error::{NotSupported, InvalidCharacter, Security}; use dom::bindings::error::Error::HierarchyRequest; @@ -84,7 +85,7 @@ use html5ever::tree_builder::{QuirksMode, NoQuirks, LimitedQuirks, Quirks}; use layout_interface::{LayoutChan, Msg}; use string_cache::{Atom, QualName}; use url::Url; -use js::jsapi::JSRuntime; +use js::jsapi::{JSContext, JSObject, JSRuntime}; use num::ToPrimitive; use std::iter::FromIterator; @@ -94,6 +95,7 @@ use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::ascii::AsciiExt; use std::cell::{Cell, Ref, RefMut, RefCell}; use std::default::Default; +use std::ptr; use std::sync::mpsc::{Receiver, channel}; use time; @@ -1661,6 +1663,94 @@ impl<'a> DocumentMethods for JSRef<'a, Document> { self.set_body_attribute(&atom!("bgcolor"), value) } + // https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter + fn NamedGetter(self, cx: *mut JSContext, name: DOMString, found: &mut bool) + -> *mut JSObject { + #[jstraceable] + struct NamedElementFilter { + name: Atom, + } + impl CollectionFilter for NamedElementFilter { + fn filter(&self, elem: JSRef, _root: JSRef) -> bool { + filter_by_name(&self.name, NodeCast::from_ref(elem)) + } + } + // https://html.spec.whatwg.org/#dom-document-nameditem-filter + fn filter_by_name(name: &Atom, node: JSRef) -> bool { + let html_elem_type = match node.type_id() { + NodeTypeId::Element(ElementTypeId::HTMLElement(type_)) => type_, + _ => return false, + }; + let elem = match ElementCast::to_ref(node) { + Some(elem) => elem, + None => return false, + }; + match html_elem_type { + HTMLElementTypeId::HTMLAppletElement => { + match elem.get_attribute(&ns!(""), &atom!("name")).root() { + Some(ref attr) if attr.r().value().atom() == Some(name) => true, + _ => { + match elem.get_attribute(&ns!(""), &atom!("id")).root() { + Some(ref attr) => attr.r().value().atom() == Some(name), + None => false, + } + }, + } + }, + HTMLElementTypeId::HTMLFormElement => { + match elem.get_attribute(&ns!(""), &atom!("name")).root() { + Some(ref attr) => attr.r().value().atom() == Some(name), + None => false, + } + }, + HTMLElementTypeId::HTMLImageElement => { + match elem.get_attribute(&ns!(""), &atom!("name")).root() { + Some(ref attr) => { + if attr.r().value().atom() == Some(name) { + true + } else { + match elem.get_attribute(&ns!(""), &atom!("id")).root() { + Some(ref attr) => attr.r().value().atom() == Some(name), + None => false, + } + } + }, + None => false, + } + }, + // TODO: Handle ,