aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/document.rs6
-rw-r--r--components/script/dom/element.rs46
-rw-r--r--components/script/dom/htmlanchorelement.rs2
-rwxr-xr-xcomponents/script/dom/htmlbuttonelement.rs2
-rw-r--r--components/script/dom/htmlcollection.rs28
-rw-r--r--components/script/dom/htmlfieldsetelement.rs7
-rw-r--r--components/script/dom/htmlformcontrolscollection.rs9
-rw-r--r--components/script/dom/htmlformelement.rs92
-rw-r--r--components/script/dom/htmlheadelement.rs2
-rw-r--r--components/script/dom/htmliframeelement.rs32
-rw-r--r--components/script/dom/htmlimageelement.rs5
-rwxr-xr-xcomponents/script/dom/htmlinputelement.rs12
-rw-r--r--components/script/dom/htmlmetaelement.rs19
-rw-r--r--components/script/dom/htmloutputelement.rs6
-rwxr-xr-xcomponents/script/dom/htmlselectelement.rs2
-rwxr-xr-xcomponents/script/dom/htmltextareaelement.rs2
-rw-r--r--components/script/dom/nodelist.rs6
-rw-r--r--components/script/dom/radionodelist.rs9
-rw-r--r--components/script/dom/raredata.rs4
-rw-r--r--components/script/dom/webidls/HTMLFieldSetElement.webidl4
-rw-r--r--components/script/dom/webidls/HTMLOutputElement.webidl4
-rw-r--r--components/script/dom/webidls/HTMLTextAreaElement.webidl1
-rw-r--r--components/script/dom/windowproxy.rs3
23 files changed, 167 insertions, 136 deletions
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.