Auto merge of #5840 - Ms2ger:attrvalue-slice, r=SimonSapin

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/5840)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-04-25 08:59:26 -05:00
commit b22a6c8095
16 changed files with 52 additions and 43 deletions

View file

@ -23,6 +23,7 @@ use string_cache::{Atom, Namespace};
use std::borrow::ToOwned; use std::borrow::ToOwned;
use std::cell::Ref; use std::cell::Ref;
use std::mem; use std::mem;
use std::ops::Deref;
pub enum AttrSettingType { pub enum AttrSettingType {
FirstSetAttr, FirstSetAttr,
@ -70,10 +71,19 @@ impl AttrValue {
_ => None _ => None
} }
} }
pub fn atom<'a>(&'a self) -> Option<&'a Atom> {
match *self {
AttrValue::Atom(ref value) => Some(value),
_ => None
}
}
} }
impl Str for AttrValue { impl Deref for AttrValue {
fn as_slice<'a>(&'a self) -> &'a str { type Target = str;
fn deref<'a>(&'a self) -> &'a str {
match *self { match *self {
AttrValue::String(ref value) | AttrValue::String(ref value) |
AttrValue::TokenList(ref value, _) | AttrValue::TokenList(ref value, _) |
@ -144,7 +154,7 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {
// https://dom.spec.whatwg.org/#dom-attr-value // https://dom.spec.whatwg.org/#dom-attr-value
fn Value(self) -> DOMString { fn Value(self) -> DOMString {
self.value().as_slice().to_owned() (**self.value()).to_owned()
} }
// https://dom.spec.whatwg.org/#dom-attr-value // https://dom.spec.whatwg.org/#dom-attr-value
@ -292,7 +302,7 @@ impl AttrHelpersForLayout for Attr {
unsafe fn value_ref_forever(&self) -> &'static str { unsafe fn value_ref_forever(&self) -> &'static str {
// This transmute is used to cheat the lifetime restriction. // This transmute is used to cheat the lifetime restriction.
let value = mem::transmute::<&AttrValue, &AttrValue>(self.value.borrow_for_layout()); let value = mem::transmute::<&AttrValue, &AttrValue>(self.value.borrow_for_layout());
value.as_slice() &**value
} }
#[inline] #[inline]

View file

@ -377,7 +377,7 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)
let attr = attr.r(); let attr = attr.r();
let value = attr.value(); let value = attr.value();
value.as_slice() == fragid.as_slice() &**value == &*fragid
}) })
}; };
let doc_node: JSRef<Node> = NodeCast::from_ref(self); let doc_node: JSRef<Node> = NodeCast::from_ref(self);
@ -1324,7 +1324,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)
let attr = attr.r(); let attr = attr.r();
let value = attr.value(); let value = attr.value();
value.as_slice() == name.as_slice() &**value == &*name
}) })
}) })
} }

View file

@ -1365,7 +1365,7 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
let doc = document_from_node(*self).root(); let doc = document_from_node(*self).root();
let base_url = doc.r().url(); let base_url = doc.r().url();
let value = attr.value(); let value = attr.value();
let style = Some(parse_style_attribute(value.as_slice(), &base_url)); let style = Some(parse_style_attribute(&value, &base_url));
*self.style_attribute.borrow_mut() = style; *self.style_attribute.borrow_mut() = style;
if node.is_in_doc() { if node.is_in_doc() {
@ -1384,8 +1384,8 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
let value = attr.value(); let value = attr.value();
if node.is_in_doc() { if node.is_in_doc() {
let doc = document_from_node(*self).root(); let doc = document_from_node(*self).root();
if !value.as_slice().is_empty() { if !value.is_empty() {
let value = Atom::from_slice(value.as_slice()); let value = value.atom().unwrap().clone();
doc.r().register_named_element(*self, value); doc.r().register_named_element(*self, value);
} }
doc.r().content_changed(node, NodeDamage::NodeStyleDamaged); doc.r().content_changed(node, NodeDamage::NodeStyleDamaged);
@ -1422,8 +1422,8 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
let value = attr.value(); let value = attr.value();
if node.is_in_doc() { if node.is_in_doc() {
let doc = document_from_node(*self).root(); let doc = document_from_node(*self).root();
if !value.as_slice().is_empty() { if !value.is_empty() {
let value = Atom::from_slice(value.as_slice()); let value = value.atom().unwrap().clone();
doc.r().unregister_named_element(*self, value); doc.r().unregister_named_element(*self, value);
} }
doc.r().content_changed(node, NodeDamage::NodeStyleDamaged); doc.r().content_changed(node, NodeDamage::NodeStyleDamaged);
@ -1496,8 +1496,8 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> {
// This transmute is used to cheat the lifetime restriction. // This transmute is used to cheat the lifetime restriction.
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)
let attr = attr.r(); let attr = attr.r();
let value = attr.value(); let value: &str = &**attr.value();
unsafe { mem::transmute(value.as_slice()) } unsafe { mem::transmute(value) }
}) })
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]
@ -1505,9 +1505,9 @@ impl<'a> style::node::TElement<'a> for JSRef<'a, Element> {
self.get_attributes(local_name).into_iter().map(|attr| attr.root()).map(|attr| { self.get_attributes(local_name).into_iter().map(|attr| attr.root()).map(|attr| {
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)
let attr = attr.r(); let attr = attr.r();
let value = attr.value(); let value: &str = &**attr.value();
// This transmute is used to cheat the lifetime restriction. // This transmute is used to cheat the lifetime restriction.
unsafe { mem::transmute(value.as_slice()) } unsafe { mem::transmute(value) }
}).collect() }).collect()
} }
fn get_link(self) -> Option<&'a str> { fn get_link(self) -> Option<&'a str> {

View file

@ -108,12 +108,12 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLBodyElement> {
}; };
evtarget.set_event_handler_uncompiled(cx, url, reflector, evtarget.set_event_handler_uncompiled(cx, url, reflector,
&name[2..], &name[2..],
attr.value().as_slice().to_owned()); (**attr.value()).to_owned());
} }
match attr.local_name() { match attr.local_name() {
&atom!("bgcolor") => { &atom!("bgcolor") => {
self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()) self.background_color.set(str::parse_legacy_color(&attr.value()).ok())
} }
_ => {} _ => {}
} }

View file

@ -226,11 +226,11 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> {
let value = attr.value(); let value = attr.value();
let recreate = match attr.local_name() { let recreate = match attr.local_name() {
&atom!("width") => { &atom!("width") => {
self.width.set(parse_unsigned_integer(value.as_slice().chars()).unwrap_or(DEFAULT_WIDTH)); self.width.set(parse_unsigned_integer(value.chars()).unwrap_or(DEFAULT_WIDTH));
true true
} }
&atom!("height") => { &atom!("height") => {
self.height.set(parse_unsigned_integer(value.as_slice().chars()).unwrap_or(DEFAULT_HEIGHT)); self.height.set(parse_unsigned_integer(value.chars()).unwrap_or(DEFAULT_HEIGHT));
true true
} }
_ => false, _ => false,

View file

@ -203,7 +203,7 @@ impl<'a> HTMLElementCustomAttributeHelpers for JSRef<'a, HTMLElement> {
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)
let attr = attr.r(); let attr = attr.r();
let value = attr.value(); let value = attr.value();
value.as_slice().to_owned() (**value).to_owned()
}) })
} }
@ -234,7 +234,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLElement> {
let evtarget: JSRef<EventTarget> = EventTargetCast::from_ref(*self); let evtarget: JSRef<EventTarget> = EventTargetCast::from_ref(*self);
evtarget.set_event_handler_uncompiled(cx, url, reflector, evtarget.set_event_handler_uncompiled(cx, url, reflector,
&name[2..], &name[2..],
attr.value().as_slice().to_owned()); (**attr.value()).to_owned());
} }
} }
} }

View file

@ -85,12 +85,12 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
let element: JSRef<Element> = ElementCast::from_ref(self); let element: JSRef<Element> = ElementCast::from_ref(self);
element.get_attribute(&ns!(""), &atom!("src")).root().and_then(|src| { element.get_attribute(&ns!(""), &atom!("src")).root().and_then(|src| {
let url = src.r().value(); let url = src.r().value();
if url.as_slice().is_empty() { if url.is_empty() {
None None
} else { } else {
let window = window_from_node(self).root(); let window = window_from_node(self).root();
UrlParser::new().base_url(&window.r().get_url()) UrlParser::new().base_url(&window.r().get_url())
.parse(url.as_slice()).ok() .parse(&url).ok()
} }
}) })
} }

View file

@ -284,7 +284,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> {
&atom!("src") => { &atom!("src") => {
let window = window_from_node(*self).root(); let window = window_from_node(*self).root();
let url = window.r().get_url(); let url = window.r().get_url();
self.update_image(Some((attr.value().as_slice().to_owned(), &url))); self.update_image(Some(((**attr.value()).to_owned(), &url)));
}, },
_ => () _ => ()
} }

View file

@ -479,7 +479,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
} }
&atom!("type") => { &atom!("type") => {
let value = attr.value(); let value = attr.value();
self.input_type.set(match value.as_slice() { self.input_type.set(match &**value {
"button" => InputType::InputButton, "button" => InputType::InputButton,
"submit" => InputType::InputSubmit, "submit" => InputType::InputSubmit,
"reset" => InputType::InputReset, "reset" => InputType::InputReset,
@ -497,18 +497,18 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
} }
&atom!("value") => { &atom!("value") => {
if !self.value_changed.get() { if !self.value_changed.get() {
self.textinput.borrow_mut().set_content(attr.value().as_slice().to_owned()); self.textinput.borrow_mut().set_content((**attr.value()).to_owned());
} }
} }
&atom!("name") => { &atom!("name") => {
if self.input_type.get() == InputType::InputRadio { if self.input_type.get() == InputType::InputRadio {
let value = attr.value(); let value = attr.value();
self.radio_group_updated(Some(value.as_slice())); self.radio_group_updated(Some(&value));
} }
} }
_ if attr.local_name() == &Atom::from_slice("placeholder") => { _ if attr.local_name() == &Atom::from_slice("placeholder") => {
let value = attr.value(); let value = attr.value();
let stripped = value.as_slice().chars() let stripped = value.chars()
.filter(|&c| c != '\n' && c != '\r') .filter(|&c| c != '\n' && c != '\r')
.collect::<String>(); .collect::<String>();
*self.placeholder.borrow_mut() = stripped; *self.placeholder.borrow_mut() = stripped;

View file

@ -63,7 +63,7 @@ fn get_attr(element: JSRef<Element>, local_name: &Atom) -> Option<String> {
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)
let e = e.r(); let e = e.r();
let value = e.value(); let value = e.value();
value.as_slice().to_owned() (**value).to_owned()
}) })
} }
@ -99,7 +99,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLLinkElement> {
match (rel, attr.local_name()) { match (rel, attr.local_name()) {
(ref rel, &atom!("href")) | (ref rel, &atom!("media")) => { (ref rel, &atom!("href")) | (ref rel, &atom!("media")) => {
if is_stylesheet(rel) { if is_stylesheet(rel) {
self.handle_stylesheet_url(attr.value().as_slice()); self.handle_stylesheet_url(&attr.value());
} }
} }
(_, _) => () (_, _) => ()

View file

@ -93,12 +93,12 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableCellElement> {
match attr.local_name() { match attr.local_name() {
&atom!("bgcolor") => { &atom!("bgcolor") => {
self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()) self.background_color.set(str::parse_legacy_color(&attr.value()).ok())
} }
&atom!("colspan") => { &atom!("colspan") => {
self.colspan.set(str::parse_unsigned_integer(attr.value().as_slice().chars())); self.colspan.set(str::parse_unsigned_integer(attr.value().chars()));
} }
&atom!("width") => self.width.set(str::parse_length(attr.value().as_slice())), &atom!("width") => self.width.set(str::parse_length(&attr.value())),
_ => () _ => ()
} }
} }

View file

@ -130,18 +130,17 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableElement> {
match attr.local_name() { match attr.local_name() {
&atom!("bgcolor") => { &atom!("bgcolor") => {
self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()) self.background_color.set(str::parse_legacy_color(&attr.value()).ok())
} }
&atom!("border") => { &atom!("border") => {
// According to HTML5 § 14.3.9, invalid values map to 1px. // According to HTML5 § 14.3.9, invalid values map to 1px.
self.border.set(Some(str::parse_unsigned_integer(attr.value() self.border.set(Some(str::parse_unsigned_integer(attr.value()
.as_slice()
.chars()).unwrap_or(1))) .chars()).unwrap_or(1)))
} }
&atom!("cellspacing") => { &atom!("cellspacing") => {
self.cellspacing.set(str::parse_unsigned_integer(attr.value().as_slice().chars())) self.cellspacing.set(str::parse_unsigned_integer(attr.value().chars()))
} }
&atom!("width") => self.width.set(str::parse_length(attr.value().as_slice())), &atom!("width") => self.width.set(str::parse_length(&attr.value())),
_ => () _ => ()
} }
} }

View file

@ -74,7 +74,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableRowElement> {
match attr.local_name() { match attr.local_name() {
&atom!("bgcolor") => { &atom!("bgcolor") => {
self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()); self.background_color.set(str::parse_legacy_color(&attr.value()).ok());
}, },
_ => () _ => ()
} }

View file

@ -72,7 +72,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTableSectionElement> {
match attr.local_name() { match attr.local_name() {
&atom!("bgcolor") => { &atom!("bgcolor") => {
self.background_color.set(str::parse_legacy_color(attr.value().as_slice()).ok()); self.background_color.set(str::parse_legacy_color(&attr.value()).ok());
}, },
_ => () _ => ()
} }

View file

@ -2254,7 +2254,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
other_element.attrs().iter().map(|attr| attr.root()).any(|other_attr| { other_element.attrs().iter().map(|attr| attr.root()).any(|other_attr| {
(*attr.r().namespace() == *other_attr.r().namespace()) && (*attr.r().namespace() == *other_attr.r().namespace()) &&
(attr.r().local_name() == other_attr.r().local_name()) && (attr.r().local_name() == other_attr.r().local_name()) &&
(attr.r().value().as_slice() == other_attr.r().value().as_slice()) (**attr.r().value() == **other_attr.r().value())
}) })
}) })
} }
@ -2520,7 +2520,7 @@ impl<'a> style::node::TNode<'a> for JSRef<'a, Node> {
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)
let attr = attr.r(); let attr = attr.r();
let value = attr.value(); let value = attr.value();
test(value.as_slice()) test(&value)
}) })
}, },
NamespaceConstraint::Any => { NamespaceConstraint::Any => {
@ -2530,7 +2530,7 @@ impl<'a> style::node::TNode<'a> for JSRef<'a, Node> {
// FIXME(https://github.com/rust-lang/rust/issues/23338) // FIXME(https://github.com/rust-lang/rust/issues/23338)
let attr = attr.r(); let attr = attr.r();
let value = attr.value(); let value = attr.value();
test(value.as_slice()) test(&value)
}) })
} }
} }

View file

@ -215,7 +215,7 @@ impl<'a> Serializable for JSRef<'a, Node> {
(qname, value) (qname, value)
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
let attr_refs = attrs.iter().map(|&(ref qname, ref value)| { let attr_refs = attrs.iter().map(|&(ref qname, ref value)| {
let ar: AttrRef = (&qname, value.as_slice()); let ar: AttrRef = (&qname, &**value);
ar ar
}); });
try!(serializer.start_elem(name.clone(), attr_refs)); try!(serializer.start_elem(name.clone(), attr_refs));