diff options
author | Patrick Shaughnessy <pshaughn@comcast.net> | 2020-01-21 11:06:31 -0500 |
---|---|---|
committer | Patrick Shaughnessy <pshaughn@comcast.net> | 2020-02-13 11:21:46 -0500 |
commit | f29e22f131291ed1bcd581cb9be6807c66c1534e (patch) | |
tree | cdc19a2442457a09caef9b661c97a3bb2d823364 | |
parent | 43c558fa597901f30f6994e2d99858f2954fdce2 (diff) | |
download | servo-f29e22f131291ed1bcd581cb9be6807c66c1534e.tar.gz servo-f29e22f131291ed1bcd581cb9be6807c66c1534e.zip |
Names should now be consistently atoms
32 files changed, 270 insertions, 652 deletions
diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt index 65ca743ed90..8054d28f584 100644 --- a/components/atoms/static_atoms.txt +++ b/components/atoms/static_atoms.txt @@ -84,6 +84,7 @@ radio range ratechange readystatechange +referrer reftest-wait rejectionhandled removetrack diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 98e7663bbf1..84a63d16238 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -823,6 +823,7 @@ impl Document { } fn get_anchor_by_name(&self, name: &str) -> Option<DomRoot<Element>> { + // TODO faster name lookups (see #25548) let check_anchor = |node: &HTMLAnchorElement| { let elem = node.upcast::<Element>(); elem.get_attribute(&ns!(), &local_name!("name")) @@ -4091,9 +4092,7 @@ impl DocumentMethods for Document { if element.namespace() != &ns!(html) { return false; } - element - .get_attribute(&ns!(), &local_name!("name")) - .map_or(false, |attr| &**attr.value() == &*name) + element.get_name().map_or(false, |atom| *atom == *name) }) } @@ -4303,6 +4302,7 @@ impl DocumentMethods for Document { } // https://html.spec.whatwg.org/multipage/#dom-document-nameditem-filter fn filter_by_name(name: &Atom, node: &Node) -> bool { + // TODO faster name lookups (see #25548) let html_elem_type = match node.type_id() { NodeTypeId::Element(ElementTypeId::HTMLElement(type_)) => type_, _ => return false, diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index c26e492d544..b977a2f3b28 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -1401,11 +1401,28 @@ impl Element { // https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name pub fn get_attribute_by_name(&self, name: DOMString) -> Option<DomRoot<Attr>> { let name = &self.parsed_name(name); - self.attrs + let maybe_attribute = self + .attrs .borrow() .iter() .find(|a| a.name() == name) - .map(|js| DomRoot::from_ref(&**js)) + .map(|js| DomRoot::from_ref(&**js)); + + fn id_and_name_must_be_atoms(name: &LocalName, maybe_attr: &Option<DomRoot<Attr>>) -> bool { + if *name == local_name!("id") || *name == local_name!("name") { + match maybe_attr { + None => true, + Some(ref attr) => match *attr.value() { + AttrValue::Atom(_) => true, + _ => false, + }, + } + } else { + true + } + } + debug_assert!(id_and_name_must_be_atoms(name, &maybe_attribute)); + maybe_attribute } pub fn set_attribute_from_parser( @@ -1800,6 +1817,14 @@ impl Element { let other = other.upcast::<Element>(); self.root_element() == other.root_element() } + + pub fn get_id(&self) -> Option<Atom> { + self.id_attribute.borrow().clone() + } + + pub fn get_name(&self) -> Option<Atom> { + self.rare_data().as_ref()?.name_attribute.clone() + } } impl ElementMethods for Element { @@ -1836,6 +1861,8 @@ impl ElementMethods for Element { } // https://dom.spec.whatwg.org/#dom-element-id + // This always returns a string; if you'd rather see None + // on a null id, call get_id fn Id(&self) -> DOMString { self.get_string_attribute(&local_name!("id")) } @@ -2783,6 +2810,20 @@ impl VirtualMethods for Element { } } }, + &local_name!("name") => { + // Keep the name in rare data for fast access + self.ensure_rare_data().name_attribute = + mutation.new_value(attr).and_then(|value| { + let value = value.as_atom(); + if value != &atom!("") { + Some(value.clone()) + } else { + None + } + }); + // TODO: notify the document about the name change + // once it has a name_map (#25548) + }, _ => { // FIXME(emilio): This is pretty dubious, and should be done in // the relevant super-classes. @@ -2801,6 +2842,7 @@ impl VirtualMethods for Element { fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { match name { &local_name!("id") => AttrValue::from_atomic(value.into()), + &local_name!("name") => AttrValue::from_atomic(value.into()), &local_name!("class") => AttrValue::from_serialized_tokenlist(value.into()), _ => self .super_type() diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index f90764d8a0a..47aad647f41 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -152,7 +152,7 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement { make_getter!(Name, "name"); // https://html.spec.whatwg.org/multipage/#dom-a-name - make_setter!(SetName, "name"); + make_atomic_setter!(SetName, "name"); // https://html.spec.whatwg.org/multipage/#dom-a-rev make_getter!(Rev, "rev"); diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs index 49541a2d4a0..d088e286838 100755 --- a/components/script/dom/htmlbuttonelement.rs +++ b/components/script/dom/htmlbuttonelement.rs @@ -142,7 +142,7 @@ impl HTMLButtonElementMethods for HTMLButtonElement { make_getter!(Name, "name"); // https://html.spec.whatwg.org/multipage/#dom-fe-name - make_setter!(SetName, "name"); + make_atomic_setter!(SetName, "name"); // https://html.spec.whatwg.org/multipage/#dom-button-value make_getter!(Value, "value"); diff --git a/components/script/dom/htmlcollection.rs b/components/script/dom/htmlcollection.rs index 6ad41be4652..7196e144add 100644 --- a/components/script/dom/htmlcollection.rs +++ b/components/script/dom/htmlcollection.rs @@ -366,11 +366,12 @@ impl HTMLCollectionMethods for HTMLCollection { return None; } + let key = Atom::from(key); + // Step 2. self.elements_iter().find(|elem| { - elem.get_string_attribute(&local_name!("id")) == key || - (elem.namespace() == &ns!(html) && - elem.get_string_attribute(&local_name!("name")) == key) + elem.get_id().map_or(false, |id| id == key) || + (elem.namespace() == &ns!(html) && elem.get_name().map_or(false, |id| id == key)) }) } @@ -392,17 +393,20 @@ impl HTMLCollectionMethods for HTMLCollection { // Step 2 for elem in self.elements_iter() { // Step 2.1 - let id_attr = elem.get_string_attribute(&local_name!("id")); - if !id_attr.is_empty() && !result.contains(&id_attr) { - result.push(id_attr) + if let Some(id_atom) = elem.get_id() { + let id_str = DOMString::from(&*id_atom); + if !result.contains(&id_str) { + result.push(id_str); + } } // Step 2.2 - let name_attr = elem.get_string_attribute(&local_name!("name")); - if !name_attr.is_empty() && - !result.contains(&name_attr) && - *elem.namespace() == ns!(html) - { - result.push(name_attr) + if *elem.namespace() == ns!(html) { + if let Some(name_atom) = elem.get_name() { + let name_str = DOMString::from(&*name_atom); + if !result.contains(&name_str) { + result.push(name_str) + } + } } } diff --git a/components/script/dom/htmlfieldsetelement.rs b/components/script/dom/htmlfieldsetelement.rs index 4f97f7e66c7..a95d8a8120a 100644 --- a/components/script/dom/htmlfieldsetelement.rs +++ b/components/script/dom/htmlfieldsetelement.rs @@ -7,6 +7,7 @@ use crate::dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding; use crate::dom::bindings::codegen::Bindings::HTMLFieldSetElementBinding::HTMLFieldSetElementMethods; use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId}; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; +use crate::dom::bindings::str::DOMString; use crate::dom::document::Document; use crate::dom::element::{AttributeMutation, Element}; use crate::dom::htmlcollection::{CollectionFilter, HTMLCollection}; @@ -88,6 +89,12 @@ impl HTMLFieldSetElementMethods for HTMLFieldSetElement { // https://html.spec.whatwg.org/multipage/#dom-fieldset-disabled make_bool_setter!(SetDisabled, "disabled"); + // https://html.spec.whatwg.org/multipage/#dom-fe-name + make_atomic_setter!(SetName, "name"); + + // https://html.spec.whatwg.org/multipage/#dom-fe-name + make_getter!(Name, "name"); + // https://html.spec.whatwg.org/multipage/#dom-fae-form fn GetForm(&self) -> Option<DomRoot<HTMLFormElement>> { self.form_owner() diff --git a/components/script/dom/htmlformcontrolscollection.rs b/components/script/dom/htmlformcontrolscollection.rs index 410244c52c1..59d6b923616 100644 --- a/components/script/dom/htmlformcontrolscollection.rs +++ b/components/script/dom/htmlformcontrolscollection.rs @@ -18,6 +18,7 @@ use crate::dom::node::Node; use crate::dom::radionodelist::RadioNodeList; use crate::dom::window::Window; use dom_struct::dom_struct; +use servo_atoms::Atom; #[dom_struct] pub struct HTMLFormControlsCollection { @@ -67,9 +68,11 @@ impl HTMLFormControlsCollectionMethods for HTMLFormControlsCollection { return None; } + let name = Atom::from(name); + let mut filter_map = self.collection.elements_iter().filter_map(|elem| { - if elem.get_string_attribute(&local_name!("name")) == name || - elem.get_string_attribute(&local_name!("id")) == name + if elem.get_name().map_or(false, |n| n == name) || + elem.get_id().map_or(false, |i| i == name) { Some(elem) } else { @@ -90,7 +93,7 @@ impl HTMLFormControlsCollectionMethods for HTMLFormControlsCollection { // specifically HTMLFormElement::Elements(), // and the collection filter excludes image inputs. Some(RadioNodeListOrElement::RadioNodeList( - RadioNodeList::new_controls_except_image_inputs(window, &*self.form, name), + RadioNodeList::new_controls_except_image_inputs(window, &*self.form, &name), )) } // Step 3 diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index bf59dc0280b..adbb790a181 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -62,10 +62,10 @@ use mime::{self, Mime}; use net_traits::http_percent_encode; use net_traits::request::Referrer; use script_traits::{HistoryEntryReplacement, LoadData, LoadOrigin}; +use servo_atoms::Atom; use servo_rand::random; use std::borrow::ToOwned; use std::cell::Cell; -use style::attr::AttrValue; use style::str::split_html_space_chars; use crate::dom::bindings::codegen::UnionTypes::RadioNodeListOrElement; @@ -86,7 +86,7 @@ pub struct HTMLFormElement { elements: DomOnceCell<HTMLFormControlsCollection>, generation_id: Cell<GenerationId>, controls: DomRefCell<Vec<Dom<Element>>>, - past_names_map: DomRefCell<HashMap<DOMString, (Dom<Element>, Tm)>>, + past_names_map: DomRefCell<HashMap<Atom, (Dom<Element>, Tm)>>, } impl HTMLFormElement { @@ -119,7 +119,7 @@ impl HTMLFormElement { ) } - fn filter_for_radio_list(mode: RadioListMode, child: &Element, name: &DOMString) -> bool { + fn filter_for_radio_list(mode: RadioListMode, child: &Element, name: &Atom) -> bool { if let Some(child) = child.downcast::<Element>() { match mode { RadioListMode::ControlsExceptImageInputs => { @@ -127,10 +127,8 @@ impl HTMLFormElement { .downcast::<HTMLElement>() .map_or(false, |c| c.is_listed_element()) { - if (child.has_attribute(&local_name!("id")) && - child.get_string_attribute(&local_name!("id")) == *name) || - (child.has_attribute(&local_name!("name")) && - child.get_string_attribute(&local_name!("name")) == *name) + if child.get_id().map_or(false, |i| i == *name) || + child.get_name().map_or(false, |n| n == *name) { if let Some(inp) = child.downcast::<HTMLInputElement>() { // input, only return it if it's not image-button state @@ -144,16 +142,9 @@ impl HTMLFormElement { return false; }, RadioListMode::Images => { - if child.is::<HTMLImageElement>() { - if (child.has_attribute(&local_name!("id")) && - child.get_string_attribute(&local_name!("id")) == *name) || - (child.has_attribute(&local_name!("name")) && - child.get_string_attribute(&local_name!("name")) == *name) - { - return true; - } - } - return false; + return child.is::<HTMLImageElement>() && + (child.get_id().map_or(false, |i| i == *name) || + child.get_name().map_or(false, |n| n == *name)); }, } } @@ -164,7 +155,7 @@ impl HTMLFormElement { &self, index: u32, mode: RadioListMode, - name: &DOMString, + name: &Atom, ) -> Option<DomRoot<Node>> { self.controls .borrow() @@ -174,7 +165,7 @@ impl HTMLFormElement { .and_then(|n| Some(DomRoot::from_ref(n.upcast::<Node>()))) } - pub fn count_for_radio_list(&self, mode: RadioListMode, name: &DOMString) -> u32 { + pub fn count_for_radio_list(&self, mode: RadioListMode, name: &Atom) -> u32 { self.controls .borrow() .iter() @@ -333,14 +324,15 @@ impl HTMLFormElementMethods for HTMLFormElement { fn NamedGetter(&self, name: DOMString) -> Option<RadioNodeListOrElement> { let window = window_from_node(self); + let name = Atom::from(name); + // Step 1 - let mut candidates = - RadioNodeList::new_controls_except_image_inputs(&window, self, name.clone()); + let mut candidates = RadioNodeList::new_controls_except_image_inputs(&window, self, &name); let mut candidates_length = candidates.Length(); // Step 2 if candidates_length == 0 { - candidates = RadioNodeList::new_images(&window, self, name.clone()); + candidates = RadioNodeList::new_images(&window, self, &name); candidates_length = candidates.Length(); } @@ -399,12 +391,12 @@ impl HTMLFormElementMethods for HTMLFormElement { } struct SourcedName { - name: DOMString, + name: Atom, element: DomRoot<Element>, source: SourcedNameSource, } - let mut sourcedNamesVec: Vec<SourcedName> = Vec::new(); + let mut sourced_names_vec: Vec<SourcedName> = Vec::new(); let controls = self.controls.borrow(); @@ -414,21 +406,21 @@ impl HTMLFormElementMethods for HTMLFormElement { .downcast::<HTMLElement>() .map_or(false, |c| c.is_listed_element()) { - if child.has_attribute(&local_name!("id")) { + if let Some(id_atom) = child.get_id() { let entry = SourcedName { - name: child.get_string_attribute(&local_name!("id")), + name: id_atom, element: DomRoot::from_ref(&*child), source: SourcedNameSource::Id, }; - sourcedNamesVec.push(entry); + sourced_names_vec.push(entry); } - if child.has_attribute(&local_name!("name")) { + if let Some(name_atom) = child.get_name() { let entry = SourcedName { - name: child.get_string_attribute(&local_name!("name")), + name: name_atom, element: DomRoot::from_ref(&*child), source: SourcedNameSource::Name, }; - sourcedNamesVec.push(entry); + sourced_names_vec.push(entry); } } } @@ -436,21 +428,21 @@ impl HTMLFormElementMethods for HTMLFormElement { // Step 3 for child in controls.iter() { if child.is::<HTMLImageElement>() { - if child.has_attribute(&local_name!("id")) { + if let Some(id_atom) = child.get_id() { let entry = SourcedName { - name: child.get_string_attribute(&local_name!("id")), + name: id_atom, element: DomRoot::from_ref(&*child), source: SourcedNameSource::Id, }; - sourcedNamesVec.push(entry); + sourced_names_vec.push(entry); } - if child.has_attribute(&local_name!("name")) { + if let Some(name_atom) = child.get_name() { let entry = SourcedName { - name: child.get_string_attribute(&local_name!("name")), + name: name_atom, element: DomRoot::from_ref(&*child), source: SourcedNameSource::Name, }; - sourcedNamesVec.push(entry); + sourced_names_vec.push(entry); } } } @@ -463,7 +455,7 @@ impl HTMLFormElementMethods for HTMLFormElement { element: DomRoot::from_ref(&*val.0), source: SourcedNameSource::Past(now() - val.1), // calculate difference now()-val.1 to find age }; - sourcedNamesVec.push(entry); + sourced_names_vec.push(entry); } // Step 5 @@ -477,7 +469,7 @@ impl HTMLFormElementMethods for HTMLFormElement { // (this can be checked by bitwise operations) then b would follow a in tree order and // Ordering::Less should be returned in the closure else Ordering::Greater - sourcedNamesVec.sort_by(|a, b| { + sourced_names_vec.sort_by(|a, b| { if a.element .upcast::<Node>() .CompareDocumentPosition(b.element.upcast::<Node>()) == @@ -503,21 +495,21 @@ impl HTMLFormElementMethods for HTMLFormElement { }); // Step 6 - sourcedNamesVec.retain(|sn| !sn.name.to_string().is_empty()); + sourced_names_vec.retain(|sn| !sn.name.to_string().is_empty()); // Step 7-8 - let mut namesVec: Vec<DOMString> = Vec::new(); - for elem in sourcedNamesVec.iter() { - if namesVec + let mut names_vec: Vec<DOMString> = Vec::new(); + for elem in sourced_names_vec.iter() { + if names_vec .iter() - .find(|name| name.to_string() == elem.name.to_string()) + .find(|name| &**name == &*elem.name) .is_none() { - namesVec.push(elem.name.clone()); + names_vec.push(DOMString::from(&*elem.name)); } } - return namesVec; + return names_vec; } } @@ -1519,16 +1511,6 @@ impl VirtualMethods for HTMLFormElement { Some(self.upcast::<HTMLElement>() as &dyn VirtualMethods) } - fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { - match name { - &local_name!("name") => AttrValue::from_atomic(value.into()), - _ => self - .super_type() - .unwrap() - .parse_plain_attribute(name, value), - } - } - fn unbind_from_tree(&self, context: &UnbindContext) { self.super_type().unwrap().unbind_from_tree(context); diff --git a/components/script/dom/htmlheadelement.rs b/components/script/dom/htmlheadelement.rs index 07054971ffa..9bf288639bc 100644 --- a/components/script/dom/htmlheadelement.rs +++ b/components/script/dom/htmlheadelement.rs @@ -58,7 +58,7 @@ impl HTMLHeadElement { .traverse_preorder(ShadowIncluding::No) .filter_map(DomRoot::downcast::<Element>) .filter(|elem| elem.is::<HTMLMetaElement>()) - .filter(|elem| elem.get_string_attribute(&local_name!("name")) == "referrer") + .filter(|elem| elem.get_name() == Some(atom!("referrer"))) .filter(|elem| { elem.get_attribute(&ns!(), &local_name!("content")) .is_some() diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index b70663a6949..f5d408ad963 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -81,7 +81,6 @@ pub struct HTMLIFrameElement { sandbox_allowance: Cell<Option<SandboxAllowance>>, load_blocker: DomRefCell<Option<LoadBlocker>>, visibility: Cell<bool>, - name: DomRefCell<DOMString>, } impl HTMLIFrameElement { @@ -265,7 +264,11 @@ impl HTMLIFrameElement { // when the iframe attributes are first processed. if mode == ProcessingMode::FirstTime { if let Some(window) = self.GetContentWindow() { - window.set_name(self.name.borrow().clone()) + window.set_name( + self.upcast::<Element>() + .get_name() + .map_or(DOMString::from(""), |n| DOMString::from(&*n)), + ); } } @@ -389,7 +392,6 @@ impl HTMLIFrameElement { sandbox_allowance: Cell::new(None), load_blocker: DomRefCell::new(None), visibility: Cell::new(true), - name: DomRefCell::new(DOMString::new()), } } @@ -569,21 +571,14 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement { make_setter!(SetFrameBorder, "frameborder"); // https://html.spec.whatwg.org/multipage/#dom-iframe-name - fn SetName(&self, name: DOMString) { - *self.name.borrow_mut() = name.clone(); - if let Some(window) = self.GetContentWindow() { - window.set_name(name) - } - } + // A child browsing context checks the name of its iframe only at the time + // it is created; subsequent name sets have no special effect. + make_atomic_setter!(SetName, "name"); // https://html.spec.whatwg.org/multipage/#dom-iframe-name - fn Name(&self) -> DOMString { - if let Some(window) = self.GetContentWindow() { - window.get_name() - } else { - self.name.borrow().clone() - } - } + // This is specified as reflecting the name content attribute of the + // element, not the name of the child browsing context. + make_getter!(Name, "name"); } impl VirtualMethods for HTMLIFrameElement { @@ -642,11 +637,6 @@ impl VirtualMethods for HTMLIFrameElement { self.process_the_iframe_attributes(ProcessingMode::NotFirstTime); } }, - &local_name!("name") => { - let new_value = mutation.new_value(attr); - let value = new_value.as_ref().map_or("", |v| &v); - self.SetName(DOMString::from(value.to_owned())); - }, _ => {}, } } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 1cfecef1728..a18eedebfb8 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -1313,8 +1313,8 @@ impl HTMLImageElement { .filter_map(DomRoot::downcast::<HTMLMapElement>) .find(|n| { n.upcast::<Element>() - .get_string_attribute(&local_name!("name")) == - last + .get_name() + .map_or(false, |n| *n == *last) }); useMapElements.map(|mapElem| mapElem.get_area_elements()) @@ -1649,7 +1649,6 @@ impl VirtualMethods for HTMLImageElement { fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { match name { - &local_name!("name") => AttrValue::from_atomic(value.into()), &local_name!("width") | &local_name!("height") => { AttrValue::from_dimension(value.into()) }, diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 88b2e688d65..a8a34a7357e 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -1466,10 +1466,13 @@ impl HTMLInputElement { // https://html.spec.whatwg.org/multipage/#radio-button-group fn radio_group_name(&self) -> Option<Atom> { - self.upcast::<Element>() - .get_attribute(&ns!(), &local_name!("name")) - .map(|name| name.value().as_atom().clone()) - .filter(|name| name != &atom!("")) + self.upcast::<Element>().get_name().and_then(|name| { + if name == atom!("") { + None + } else { + Some(name) + } + }) } fn update_checked_state(&self, checked: bool, dirty: bool) { @@ -2158,7 +2161,6 @@ impl VirtualMethods for HTMLInputElement { fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { match name { &local_name!("accept") => AttrValue::from_comma_separated_tokenlist(value.into()), - &local_name!("name") => AttrValue::from_atomic(value.into()), &local_name!("size") => AttrValue::from_limited_u32(value.into(), DEFAULT_INPUT_SIZE), &local_name!("type") => AttrValue::from_atomic(value.into()), &local_name!("maxlength") => { diff --git a/components/script/dom/htmlmetaelement.rs b/components/script/dom/htmlmetaelement.rs index 11b5706516d..3f1876c2923 100644 --- a/components/script/dom/htmlmetaelement.rs +++ b/components/script/dom/htmlmetaelement.rs @@ -26,7 +26,6 @@ use parking_lot::RwLock; use servo_arc::Arc; use servo_config::pref; use std::sync::atomic::AtomicBool; -use style::attr::AttrValue; use style::media_queries::MediaList; use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::{CssRule, CssRules, Origin, Stylesheet, StylesheetContents, ViewportRule}; @@ -86,8 +85,8 @@ impl HTMLMetaElement { fn process_attributes(&self) { let element = self.upcast::<Element>(); - if let Some(ref name) = element.get_attribute(&ns!(), &local_name!("name")) { - let name = name.value().to_ascii_lowercase(); + if let Some(ref name) = element.get_name() { + let name = name.to_ascii_lowercase(); let name = name.trim_matches(HTML_SPACE_CHARACTERS); if name == "viewport" { @@ -137,8 +136,8 @@ impl HTMLMetaElement { fn process_referrer_attribute(&self) { let element = self.upcast::<Element>(); - if let Some(ref name) = element.get_attribute(&ns!(), &local_name!("name")) { - let name = name.value().to_ascii_lowercase(); + if let Some(ref name) = element.get_name() { + let name = name.to_ascii_lowercase(); let name = name.trim_matches(HTML_SPACE_CHARACTERS); if name == "referrer" { @@ -186,16 +185,6 @@ impl VirtualMethods for HTMLMetaElement { } } - fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { - match name { - &local_name!("name") => AttrValue::from_atomic(value.into()), - _ => self - .super_type() - .unwrap() - .parse_plain_attribute(name, value), - } - } - fn attribute_mutated(&self, attr: &Attr, mutation: AttributeMutation) { if let Some(s) = self.super_type() { s.attribute_mutated(attr, mutation); diff --git a/components/script/dom/htmloutputelement.rs b/components/script/dom/htmloutputelement.rs index 548c81bb1b4..12d2e415ae1 100644 --- a/components/script/dom/htmloutputelement.rs +++ b/components/script/dom/htmloutputelement.rs @@ -114,6 +114,12 @@ impl HTMLOutputElementMethods for HTMLOutputElement { fn Type(&self) -> DOMString { return DOMString::from("output"); } + + // https://html.spec.whatwg.org/multipage/#dom-fe-name + make_atomic_setter!(SetName, "name"); + + // https://html.spec.whatwg.org/multipage/#dom-fe-name + make_getter!(Name, "name"); } impl VirtualMethods for HTMLOutputElement { diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs index bef4bfff8b4..78a26ca4311 100755 --- a/components/script/dom/htmlselectelement.rs +++ b/components/script/dom/htmlselectelement.rs @@ -234,7 +234,7 @@ impl HTMLSelectElementMethods for HTMLSelectElement { make_getter!(Name, "name"); // https://html.spec.whatwg.org/multipage/#dom-fe-name - make_setter!(SetName, "name"); + make_atomic_setter!(SetName, "name"); // https://html.spec.whatwg.org/multipage/#dom-select-size make_uint_getter!(Size, "size", DEFAULT_SELECT_SIZE); diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs index eb8fcab3873..9fd316e3a18 100755 --- a/components/script/dom/htmltextareaelement.rs +++ b/components/script/dom/htmltextareaelement.rs @@ -220,7 +220,7 @@ impl HTMLTextAreaElementMethods for HTMLTextAreaElement { make_getter!(Name, "name"); // https://html.spec.whatwg.org/multipage/#attr-fe-name - make_setter!(SetName, "name"); + make_atomic_setter!(SetName, "name"); // https://html.spec.whatwg.org/multipage/#dom-textarea-placeholder make_getter!(Placeholder, "placeholder"); diff --git a/components/script/dom/nodelist.rs b/components/script/dom/nodelist.rs index 1fdcef4b340..8c4f6d39358 100644 --- a/components/script/dom/nodelist.rs +++ b/components/script/dom/nodelist.rs @@ -7,12 +7,12 @@ use crate::dom::bindings::codegen::Bindings::NodeListBinding; use crate::dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; -use crate::dom::bindings::str::DOMString; use crate::dom::htmlelement::HTMLElement; use crate::dom::htmlformelement::HTMLFormElement; use crate::dom::node::{ChildrenMutation, Node}; use crate::dom::window::Window; use dom_struct::dom_struct; +use servo_atoms::Atom; use std::cell::Cell; #[derive(JSTraceable, MallocSizeOf)] @@ -381,11 +381,11 @@ pub enum RadioListMode { pub struct RadioList { form: Dom<HTMLFormElement>, mode: RadioListMode, - name: DOMString, + name: Atom, } impl RadioList { - pub fn new(form: &HTMLFormElement, mode: RadioListMode, name: DOMString) -> RadioList { + pub fn new(form: &HTMLFormElement, mode: RadioListMode, name: Atom) -> RadioList { RadioList { form: Dom::from_ref(form), mode: mode, diff --git a/components/script/dom/radionodelist.rs b/components/script/dom/radionodelist.rs index 6882aefff35..56069375b27 100644 --- a/components/script/dom/radionodelist.rs +++ b/components/script/dom/radionodelist.rs @@ -16,6 +16,7 @@ use crate::dom::node::Node; use crate::dom::nodelist::{NodeList, NodeListType, RadioList, RadioListMode}; use crate::dom::window::Window; use dom_struct::dom_struct; +use servo_atoms::Atom; #[dom_struct] pub struct RadioNodeList { @@ -42,14 +43,14 @@ impl RadioNodeList { pub fn new_controls_except_image_inputs( window: &Window, form: &HTMLFormElement, - name: DOMString, + name: &Atom, ) -> DomRoot<RadioNodeList> { RadioNodeList::new( window, NodeListType::Radio(RadioList::new( form, RadioListMode::ControlsExceptImageInputs, - name, + name.clone(), )), ) } @@ -57,11 +58,11 @@ impl RadioNodeList { pub fn new_images( window: &Window, form: &HTMLFormElement, - name: DOMString, + name: &Atom, ) -> DomRoot<RadioNodeList> { RadioNodeList::new( window, - NodeListType::Radio(RadioList::new(form, RadioListMode::Images, name)), + NodeListType::Radio(RadioList::new(form, RadioListMode::Images, name.clone())), ) } diff --git a/components/script/dom/raredata.rs b/components/script/dom/raredata.rs index e32f218ce89..198b6bfe720 100644 --- a/components/script/dom/raredata.rs +++ b/components/script/dom/raredata.rs @@ -9,6 +9,7 @@ use crate::dom::customelementregistry::{ use crate::dom::mutationobserver::RegisteredObserver; use crate::dom::node::UniqueId; use crate::dom::shadowroot::ShadowRoot; +use servo_atoms::Atom; use std::rc::Rc; //XXX(ferjm) Ideally merge NodeRareData and ElementRareData so they share @@ -42,4 +43,7 @@ pub struct ElementRareData { pub custom_element_definition: Option<Rc<CustomElementDefinition>>, /// <https://dom.spec.whatwg.org/#concept-element-custom-element-state> pub custom_element_state: CustomElementState, + /// The "name" content attribute; not used as frequently as id, but used + /// in named getter loops so it's worth looking up quickly when present + pub name_attribute: Option<Atom>, } diff --git a/components/script/dom/webidls/HTMLFieldSetElement.webidl b/components/script/dom/webidls/HTMLFieldSetElement.webidl index c439806c30a..d0a6f14a77a 100644 --- a/components/script/dom/webidls/HTMLFieldSetElement.webidl +++ b/components/script/dom/webidls/HTMLFieldSetElement.webidl @@ -10,8 +10,8 @@ interface HTMLFieldSetElement : HTMLElement { [CEReactions] attribute boolean disabled; readonly attribute HTMLFormElement? form; - // [CEReactions] - // attribute DOMString name; + [CEReactions] + attribute DOMString name; //readonly attribute DOMString type; diff --git a/components/script/dom/webidls/HTMLOutputElement.webidl b/components/script/dom/webidls/HTMLOutputElement.webidl index b956d593d8b..28d853a0bbf 100644 --- a/components/script/dom/webidls/HTMLOutputElement.webidl +++ b/components/script/dom/webidls/HTMLOutputElement.webidl @@ -9,8 +9,8 @@ interface HTMLOutputElement : HTMLElement { // [SameObject, PutForwards=value] readonly attribute DOMTokenList htmlFor; readonly attribute HTMLFormElement? form; - // [CEReactions] - // attribute DOMString name; + [CEReactions] + attribute DOMString name; [Pure] readonly attribute DOMString type; [CEReactions] diff --git a/components/script/dom/webidls/HTMLTextAreaElement.webidl b/components/script/dom/webidls/HTMLTextAreaElement.webidl index d14eacfd99d..99cf18e0c10 100644 --- a/components/script/dom/webidls/HTMLTextAreaElement.webidl +++ b/components/script/dom/webidls/HTMLTextAreaElement.webidl @@ -24,6 +24,7 @@ interface HTMLTextAreaElement : HTMLElement { attribute long maxLength; [CEReactions, SetterThrows] attribute long minLength; + [CEReactions] attribute DOMString name; [CEReactions] attribute DOMString placeholder; diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 24afc54a133..c910e956e7e 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -81,7 +81,8 @@ pub struct WindowProxy { /// In the case that this is a top-level window, this is our id. top_level_browsing_context_id: TopLevelBrowsingContextId, - /// The name of the browsing context + /// The name of the browsing context (sometimes, but not always, + /// equal to the name of a container element) name: DomRefCell<DOMString>, /// The pipeline id of the currently active document. /// May be None, when the currently active document is in another script thread. diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 8f37ab58752..ccd331d592d 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -364131,6 +364131,12 @@ {} ] ], + "html/dom/elements/name-content-attribute-and-property.html": [ + [ + "html/dom/elements/name-content-attribute-and-property.html", + {} + ] + ], "html/dom/elements/the-innertext-idl-attribute/dynamic-getter.html": [ [ "html/dom/elements/the-innertext-idl-attribute/dynamic-getter.html", @@ -682833,6 +682839,10 @@ "d781172bbadcc51c4b203200f1a0adfe50ae4246", "manual" ], + "html/dom/elements/name-content-attribute-and-property.html": [ + "bcfbd29c33c1e8e68c6f712ad7e2f3ded8cc6686", + "testharness" + ], "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001a.html": [ "16a308a2f7792a142ed69505f33d111831a063f9", "reftest" diff --git a/tests/wpt/metadata/custom-elements/reactions/HTMLFieldSetElement.html.ini b/tests/wpt/metadata/custom-elements/reactions/HTMLFieldSetElement.html.ini deleted file mode 100644 index dd0110b37ad..00000000000 --- a/tests/wpt/metadata/custom-elements/reactions/HTMLFieldSetElement.html.ini +++ /dev/null @@ -1,7 +0,0 @@ -[HTMLFieldSetElement.html] - [name on HTMLFieldSetElement must enqueue an attributeChanged reaction when adding a new attribute] - expected: FAIL - - [name on HTMLFieldSetElement must enqueue an attributeChanged reaction when replacing an existing attribute] - expected: FAIL - diff --git a/tests/wpt/metadata/html/browsers/windows/nested-browsing-contexts/name-attribute.window.js.ini b/tests/wpt/metadata/html/browsers/windows/nested-browsing-contexts/name-attribute.window.js.ini index 636c298b2a1..8ef635dd40c 100644 --- a/tests/wpt/metadata/html/browsers/windows/nested-browsing-contexts/name-attribute.window.js.ini +++ b/tests/wpt/metadata/html/browsers/windows/nested-browsing-contexts/name-attribute.window.js.ini @@ -9,39 +9,21 @@ [same-origin <frame name=>] expected: TIMEOUT - [cross-origin <iframe name=initialvalue>] - expected: FAIL - [cross-origin <embed name=initialvalue>] expected: TIMEOUT - [same-origin <iframe name=>] - expected: FAIL - [same-origin <embed>] expected: TIMEOUT - [cross-origin <iframe>] - expected: FAIL - [cross-origin <frame name=initialvalue>] expected: TIMEOUT - [cross-origin <iframe name=>] - expected: FAIL - [same-origin <object name=initialvalue>] expected: TIMEOUT [cross-origin <object name=initialvalue>] expected: TIMEOUT - [same-origin <iframe>] - expected: FAIL - - [same-origin <iframe name=initialvalue>] - expected: FAIL - [same-origin <object name=>] expected: TIMEOUT diff --git a/tests/wpt/metadata/html/dom/elements/name-content-attribute-and-property.html.ini b/tests/wpt/metadata/html/dom/elements/name-content-attribute-and-property.html.ini new file mode 100644 index 00000000000..13f6fd09fe8 --- /dev/null +++ b/tests/wpt/metadata/html/dom/elements/name-content-attribute-and-property.html.ini @@ -0,0 +1,18 @@ +[name-content-attribute-and-property.html] + [embed element\'s name property reflects its content attribute] + expected: FAIL + + [frame element\'s name property reflects its content attribute] + expected: FAIL + + [map element\'s name property reflects its content attribute] + expected: FAIL + + [object element\'s name property reflects its content attribute] + expected: FAIL + + [param element\'s name property reflects its content attribute] + expected: FAIL + + [slot element\'s name property reflects its content attribute] + expected: FAIL diff --git a/tests/wpt/metadata/html/dom/idlharness.https.html.ini b/tests/wpt/metadata/html/dom/idlharness.https.html.ini index 1c094dd479f..b63f2e983c4 100644 --- a/tests/wpt/metadata/html/dom/idlharness.https.html.ini +++ b/tests/wpt/metadata/html/dom/idlharness.https.html.ini @@ -2241,9 +2241,6 @@ [HTMLInputElement interface: createInput("image") must inherit property "align" with the proper type] expected: FAIL - [HTMLOutputElement interface: attribute name] - expected: FAIL - [HTMLInputElement interface: createInput("url") must inherit property "reportValidity()" with the proper type] expected: FAIL @@ -3009,9 +3006,6 @@ [HTMLImageElement interface: document.createElement("img") must inherit property "referrerPolicy" with the proper type] expected: FAIL - [HTMLOutputElement interface: document.createElement("output") must inherit property "name" with the proper type] - expected: FAIL - [HTMLElement interface: document.createElement("noscript") must inherit property "dir" with the proper type] expected: FAIL @@ -3417,9 +3411,6 @@ [HTMLInputElement interface: calling setCustomValidity(DOMString) on createInput("range") with too few arguments must throw TypeError] expected: FAIL - [HTMLFieldSetElement interface: attribute name] - expected: FAIL - [HTMLInputElement interface: createInput("time") must inherit property "reportValidity()" with the proper type] expected: FAIL @@ -4466,4 +4457,3 @@ [HTMLElement interface: document.createElement("noscript") must inherit property "onwebkittransitionend" with the proper type] expected: FAIL - diff --git a/tests/wpt/metadata/html/dom/reflection-forms.html.ini b/tests/wpt/metadata/html/dom/reflection-forms.html.ini index e24e0d9c919..f1e823f2c7d 100644 --- a/tests/wpt/metadata/html/dom/reflection-forms.html.ini +++ b/tests/wpt/metadata/html/dom/reflection-forms.html.ini @@ -12,9 +12,6 @@ [form.dir: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get] expected: FAIL - [form.dir: setAttribute() to undefined followed by IDL get] - expected: FAIL - [form.dir: setAttribute() to 7 followed by IDL get] expected: FAIL @@ -1188,135 +1185,6 @@ [fieldset.tabIndex: IDL set to -2147483648 followed by getAttribute()] expected: FAIL - [fieldset.name: typeof IDL attribute] - expected: FAIL - - [fieldset.name: IDL get with DOM attribute unset] - expected: FAIL - - [fieldset.name: setAttribute() to "" followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to undefined followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to 7 followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to 1.5 followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to true followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to false followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to object "[object Object\]" followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to NaN followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to Infinity followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to -Infinity followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to "\\0" followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to null followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to object "test-toString" followed by IDL get] - expected: FAIL - - [fieldset.name: setAttribute() to object "test-valueOf" followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to "" followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to undefined followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to undefined followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to 7 followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to 7 followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to 1.5 followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to 1.5 followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to true followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to true followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to false followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to false followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to object "[object Object\]" followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to object "[object Object\]" followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to NaN followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to NaN followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to Infinity followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to Infinity followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to -Infinity followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to -Infinity followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to "\\0" followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to null followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to null followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to object "test-toString" followed by getAttribute()] - expected: FAIL - - [fieldset.name: IDL set to object "test-toString" followed by IDL get] - expected: FAIL - - [fieldset.name: IDL set to object "test-valueOf" followed by IDL get] - expected: FAIL - [fieldset.itemScope: typeof IDL attribute] expected: FAIL @@ -12261,135 +12129,6 @@ [output.tabIndex: IDL set to -2147483648 followed by getAttribute()] expected: FAIL - [output.name: typeof IDL attribute] - expected: FAIL - - [output.name: IDL get with DOM attribute unset] - expected: FAIL - - [output.name: setAttribute() to "" followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to undefined followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to 7 followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to 1.5 followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to true followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to false followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to object "[object Object\]" followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to NaN followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to Infinity followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to -Infinity followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to "\\0" followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to null followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to object "test-toString" followed by IDL get] - expected: FAIL - - [output.name: setAttribute() to object "test-valueOf" followed by IDL get] - expected: FAIL - - [output.name: IDL set to "" followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to undefined followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to undefined followed by IDL get] - expected: FAIL - - [output.name: IDL set to 7 followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to 7 followed by IDL get] - expected: FAIL - - [output.name: IDL set to 1.5 followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to 1.5 followed by IDL get] - expected: FAIL - - [output.name: IDL set to true followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to true followed by IDL get] - expected: FAIL - - [output.name: IDL set to false followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to false followed by IDL get] - expected: FAIL - - [output.name: IDL set to object "[object Object\]" followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to object "[object Object\]" followed by IDL get] - expected: FAIL - - [output.name: IDL set to NaN followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to NaN followed by IDL get] - expected: FAIL - - [output.name: IDL set to Infinity followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to Infinity followed by IDL get] - expected: FAIL - - [output.name: IDL set to -Infinity followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to -Infinity followed by IDL get] - expected: FAIL - - [output.name: IDL set to "\\0" followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to null followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to null followed by IDL get] - expected: FAIL - - [output.name: IDL set to object "test-toString" followed by getAttribute()] - expected: FAIL - - [output.name: IDL set to object "test-toString" followed by IDL get] - expected: FAIL - - [output.name: IDL set to object "test-valueOf" followed by IDL get] - expected: FAIL - [output.itemScope: typeof IDL attribute] expected: FAIL @@ -16842,96 +16581,6 @@ [fieldset.tabIndex: IDL set to -2147483648] expected: FAIL - [fieldset.name: setAttribute() to ""] - expected: FAIL - - [fieldset.name: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [fieldset.name: setAttribute() to undefined] - expected: FAIL - - [fieldset.name: setAttribute() to 7] - expected: FAIL - - [fieldset.name: setAttribute() to 1.5] - expected: FAIL - - [fieldset.name: setAttribute() to true] - expected: FAIL - - [fieldset.name: setAttribute() to false] - expected: FAIL - - [fieldset.name: setAttribute() to object "[object Object\]"] - expected: FAIL - - [fieldset.name: setAttribute() to NaN] - expected: FAIL - - [fieldset.name: setAttribute() to Infinity] - expected: FAIL - - [fieldset.name: setAttribute() to -Infinity] - expected: FAIL - - [fieldset.name: setAttribute() to "\\0"] - expected: FAIL - - [fieldset.name: setAttribute() to null] - expected: FAIL - - [fieldset.name: setAttribute() to object "test-toString"] - expected: FAIL - - [fieldset.name: setAttribute() to object "test-valueOf"] - expected: FAIL - - [fieldset.name: IDL set to ""] - expected: FAIL - - [fieldset.name: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [fieldset.name: IDL set to undefined] - expected: FAIL - - [fieldset.name: IDL set to 7] - expected: FAIL - - [fieldset.name: IDL set to 1.5] - expected: FAIL - - [fieldset.name: IDL set to true] - expected: FAIL - - [fieldset.name: IDL set to false] - expected: FAIL - - [fieldset.name: IDL set to object "[object Object\]"] - expected: FAIL - - [fieldset.name: IDL set to NaN] - expected: FAIL - - [fieldset.name: IDL set to Infinity] - expected: FAIL - - [fieldset.name: IDL set to -Infinity] - expected: FAIL - - [fieldset.name: IDL set to "\\0"] - expected: FAIL - - [fieldset.name: IDL set to null] - expected: FAIL - - [fieldset.name: IDL set to object "test-toString"] - expected: FAIL - - [fieldset.name: IDL set to object "test-valueOf"] - expected: FAIL - [legend.dir: setAttribute() to ""] expected: FAIL @@ -22830,96 +22479,6 @@ [output.tabIndex: IDL set to -2147483648] expected: FAIL - [output.name: setAttribute() to ""] - expected: FAIL - - [output.name: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [output.name: setAttribute() to undefined] - expected: FAIL - - [output.name: setAttribute() to 7] - expected: FAIL - - [output.name: setAttribute() to 1.5] - expected: FAIL - - [output.name: setAttribute() to true] - expected: FAIL - - [output.name: setAttribute() to false] - expected: FAIL - - [output.name: setAttribute() to object "[object Object\]"] - expected: FAIL - - [output.name: setAttribute() to NaN] - expected: FAIL - - [output.name: setAttribute() to Infinity] - expected: FAIL - - [output.name: setAttribute() to -Infinity] - expected: FAIL - - [output.name: setAttribute() to "\\0"] - expected: FAIL - - [output.name: setAttribute() to null] - expected: FAIL - - [output.name: setAttribute() to object "test-toString"] - expected: FAIL - - [output.name: setAttribute() to object "test-valueOf"] - expected: FAIL - - [output.name: IDL set to ""] - expected: FAIL - - [output.name: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "] - expected: FAIL - - [output.name: IDL set to undefined] - expected: FAIL - - [output.name: IDL set to 7] - expected: FAIL - - [output.name: IDL set to 1.5] - expected: FAIL - - [output.name: IDL set to true] - expected: FAIL - - [output.name: IDL set to false] - expected: FAIL - - [output.name: IDL set to object "[object Object\]"] - expected: FAIL - - [output.name: IDL set to NaN] - expected: FAIL - - [output.name: IDL set to Infinity] - expected: FAIL - - [output.name: IDL set to -Infinity] - expected: FAIL - - [output.name: IDL set to "\\0"] - expected: FAIL - - [output.name: IDL set to null] - expected: FAIL - - [output.name: IDL set to object "test-toString"] - expected: FAIL - - [output.name: IDL set to object "test-valueOf"] - expected: FAIL - [progress.dir: setAttribute() to ""] expected: FAIL @@ -24135,9 +23694,6 @@ [button.autofocus: IDL set to "5%"] expected: FAIL - [fieldset.name: setAttribute() to "5%"] - expected: FAIL - [button.accessKey: IDL set to "5%"] expected: FAIL @@ -24153,9 +23709,6 @@ [form.accessKey: setAttribute() to "5%"] expected: FAIL - [fieldset.name: IDL set to "5%"] - expected: FAIL - [textarea.autofocus: setAttribute() to "5%"] expected: FAIL @@ -24231,8 +23784,6 @@ [option.accessKey: IDL set to "5%"] expected: FAIL - [output.name: IDL set to "5%"] - expected: FAIL [select.accessKey: setAttribute() to "5%"] expected: FAIL @@ -24249,9 +23800,6 @@ [textarea.autofocus: IDL set to "5%"] expected: FAIL - [output.name: setAttribute() to "5%"] - expected: FAIL - [meter.accessKey: setAttribute() to "5%"] expected: FAIL @@ -24513,9 +24061,6 @@ [select.autocomplete: IDL set to "+100"] expected: FAIL - [fieldset.name: IDL set to ".5"] - expected: FAIL - [optgroup.dir: setAttribute() to ".5"] expected: FAIL @@ -24567,9 +24112,6 @@ [form.dir: IDL set to ".5"] expected: FAIL - [output.name: IDL set to "+100"] - expected: FAIL - [textarea.accessKey: setAttribute() to ".5"] expected: FAIL @@ -24594,9 +24136,6 @@ [input.accessKey: IDL set to "+100"] expected: FAIL - [fieldset.name: IDL set to "+100"] - expected: FAIL - [optgroup.dir: setAttribute() to "+100"] expected: FAIL @@ -24672,9 +24211,6 @@ [button.dir: IDL set to ".5"] expected: FAIL - [output.name: setAttribute() to ".5"] - expected: FAIL - [form.accessKey: setAttribute() to ".5"] expected: FAIL @@ -24687,9 +24223,6 @@ [textarea.autocomplete: IDL set to "+100"] expected: FAIL - [output.name: IDL set to ".5"] - expected: FAIL - [button.dir: IDL set to "+100"] expected: FAIL @@ -24702,9 +24235,6 @@ [textarea.dir: setAttribute() to "+100"] expected: FAIL - [output.name: setAttribute() to "+100"] - expected: FAIL - [progress.accessKey: IDL set to ".5"] expected: FAIL @@ -24816,9 +24346,6 @@ [label.dir: IDL set to "+100"] expected: FAIL - [fieldset.name: setAttribute() to "+100"] - expected: FAIL - [legend.align: setAttribute() to ".5"] expected: FAIL @@ -24837,9 +24364,6 @@ [label.dir: setAttribute() to ".5"] expected: FAIL - [fieldset.name: setAttribute() to ".5"] - expected: FAIL - [meter.accessKey: setAttribute() to "+100"] expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-nameditem-01.html.ini b/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-nameditem-01.html.ini deleted file mode 100644 index f90f0a7ada5..00000000000 --- a/tests/wpt/metadata/html/semantics/forms/the-form-element/form-elements-nameditem-01.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[form-elements-nameditem-01.html] - type: testharness - [elements collection should include fieldsets] - expected: FAIL - diff --git a/tests/wpt/web-platform-tests/html/dom/elements/name-content-attribute-and-property.html b/tests/wpt/web-platform-tests/html/dom/elements/name-content-attribute-and-property.html new file mode 100644 index 00000000000..bcfbd29c33c --- /dev/null +++ b/tests/wpt/web-platform-tests/html/dom/elements/name-content-attribute-and-property.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<title>Only certain HTML elements reflect the name content attribute as a property</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> + function doesReflect(tagName) { + var element = document.createElement(tagName); + element.setAttribute("name", "foo"); + assert_equals(element.getAttribute("name"), "foo", "setAttribute should change content attribute"); + element.name = "bar"; + assert_equals(element.getAttribute("name"), "bar", "assignment to .name should change content attribute"); + } + + function doesNotReflect(tagName) { + var element = document.createElement(tagName); + element.setAttribute("name", "foo"); + assert_equals(element.getAttribute("name"), "foo", "setAttribute should change content attribute"); + element.name = "bar"; + assert_equals(element.getAttribute("name"), "foo", "assignment to .name should not change content attribute"); + } + + var nonReflectingTagNames = [ + "abbr", "acronym", "address", "area", "article", "aside", "audio", + "b", "base", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body","br", + "canvas", "caption", "center", "cite", "code", "col", "colgroup", + "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", + "em", + "figcaption", "figure", "font", "footer", "frameset", + "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", + "i", "ins", "isindex", + "kbd", + "label", "legend", "li", "link", "listing", + "main", "mark", "marquee", "meter", "multicol", + "nav", "nextid", "nobr", "noframes", "noscript", + "option", + "p", "picture", "plaintext", "pre", "progress", + "q", + "rp", "rt", "ruby", + "s", "samp", "script", "section", "small", "source", "spacer", + "span", "strike", "strong", "style", "sub", "summary", "sup", + "table", "tbody", "td", "template", "tfoot", + "th", "thead", "time", "title", "tr", "tt", "track", + "u", "ul", + "var", "video", + "wbr", + "xmp", + "unknown" + ]; + + var reflectingTagNames = [ + "a", "button", "embed", + "fieldset", "form", "frame", + "iframe", "img", "input", + "map", "meta", + "object", "output", + "param", + "select", "slot", + "textarea", + ]; + + reflectingTagNames.forEach(function(tagName) { + test(function() { + doesReflect(tagName) + }, tagName + " element's name property reflects its content attribute"); + }); + + nonReflectingTagNames.forEach(function(tagName) { + test(function() { + doesNotReflect(tagName) + }, tagName + " element's name property does not reflect its content attribute"); + }); +</script> + |