mirror of
https://github.com/servo/servo.git
synced 2025-06-10 01:23:13 +00:00
commit
da668f53d9
11 changed files with 269 additions and 47 deletions
|
@ -6,13 +6,13 @@ use dom::bindings::codegen::Bindings::AttrBinding;
|
|||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||
use dom::bindings::js::{JS, JSRef, Temporary};
|
||||
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
|
||||
use dom::element::Element;
|
||||
use dom::element::{Element, AttributeHandlers};
|
||||
use dom::node::Node;
|
||||
use dom::window::Window;
|
||||
use dom::virtualmethods::vtable_for;
|
||||
use servo_util::namespace;
|
||||
use servo_util::namespace::Namespace;
|
||||
use servo_util::str::DOMString;
|
||||
use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS};
|
||||
use std::cell::Cell;
|
||||
|
||||
pub enum AttrSettingType {
|
||||
|
@ -20,11 +20,45 @@ pub enum AttrSettingType {
|
|||
ReplacedAttr,
|
||||
}
|
||||
|
||||
#[deriving(Eq, Clone, Encodable)]
|
||||
pub enum AttrValue {
|
||||
StringAttrValue(DOMString),
|
||||
TokenListAttrValue(DOMString, Vec<(uint, uint)>),
|
||||
UIntAttrValue(DOMString, u32),
|
||||
}
|
||||
|
||||
impl AttrValue {
|
||||
pub fn from_tokenlist(list: DOMString) -> AttrValue {
|
||||
let mut indexes = vec![];
|
||||
let mut last_index: uint = 0;
|
||||
for (index, ch) in list.as_slice().char_indices() {
|
||||
if HTML_SPACE_CHARACTERS.iter().any(|&space| space == ch) {
|
||||
indexes.push((last_index, index));
|
||||
last_index = index + 1;
|
||||
}
|
||||
}
|
||||
return TokenListAttrValue(list, indexes);
|
||||
}
|
||||
|
||||
pub fn from_u32(string: DOMString, default: u32) -> AttrValue {
|
||||
let result: u32 = from_str(string.as_slice()).unwrap_or(default);
|
||||
UIntAttrValue(string, result)
|
||||
}
|
||||
|
||||
pub fn as_slice<'a>(&'a self) -> &'a str {
|
||||
match *self {
|
||||
StringAttrValue(ref value) |
|
||||
TokenListAttrValue(ref value, _) |
|
||||
UIntAttrValue(ref value, _) => value.as_slice(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Encodable)]
|
||||
pub struct Attr {
|
||||
pub reflector_: Reflector,
|
||||
pub local_name: DOMString,
|
||||
pub value: DOMString,
|
||||
value: AttrValue,
|
||||
pub name: DOMString,
|
||||
pub namespace: Namespace,
|
||||
pub prefix: Option<DOMString>,
|
||||
|
@ -44,7 +78,7 @@ impl Reflectable for Attr {
|
|||
}
|
||||
|
||||
impl Attr {
|
||||
fn new_inherited(local_name: DOMString, value: DOMString,
|
||||
fn new_inherited(local_name: DOMString, value: AttrValue,
|
||||
name: DOMString, namespace: Namespace,
|
||||
prefix: Option<DOMString>, owner: &JSRef<Element>) -> Attr {
|
||||
Attr {
|
||||
|
@ -58,14 +92,14 @@ impl Attr {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn new(window: &JSRef<Window>, local_name: DOMString, value: DOMString,
|
||||
pub fn new(window: &JSRef<Window>, local_name: DOMString, value: AttrValue,
|
||||
name: DOMString, namespace: Namespace,
|
||||
prefix: Option<DOMString>, owner: &JSRef<Element>) -> Temporary<Attr> {
|
||||
let attr = Attr::new_inherited(local_name, value, name, namespace, prefix, owner);
|
||||
reflect_dom_object(box attr, window, AttrBinding::Wrap)
|
||||
}
|
||||
|
||||
pub fn set_value(&mut self, set_type: AttrSettingType, value: DOMString) {
|
||||
pub fn set_value(&mut self, set_type: AttrSettingType, value: AttrValue) {
|
||||
let owner = self.owner.get().root();
|
||||
let node: &JSRef<Node> = NodeCast::from_ref(&*owner);
|
||||
let namespace_is_null = self.namespace == namespace::Null;
|
||||
|
@ -73,7 +107,7 @@ impl Attr {
|
|||
match set_type {
|
||||
ReplacedAttr => {
|
||||
if namespace_is_null {
|
||||
vtable_for(node).before_remove_attr(self.local_name.clone(), self.value.clone());
|
||||
vtable_for(node).before_remove_attr(self.local_name.clone(), self.value.as_slice().to_string());
|
||||
}
|
||||
}
|
||||
FirstSetAttr => {}
|
||||
|
@ -82,10 +116,14 @@ impl Attr {
|
|||
self.value = value;
|
||||
|
||||
if namespace_is_null {
|
||||
vtable_for(node).after_set_attr(self.local_name.clone(), self.value.clone());
|
||||
vtable_for(node).after_set_attr(self.local_name.clone(), self.value.as_slice().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value<'a>(&'a self) -> &'a AttrValue {
|
||||
&self.value
|
||||
}
|
||||
|
||||
pub fn value_ref<'a>(&'a self) -> &'a str {
|
||||
self.value.as_slice()
|
||||
}
|
||||
|
@ -106,10 +144,13 @@ impl<'a> AttrMethods for JSRef<'a, Attr> {
|
|||
}
|
||||
|
||||
fn Value(&self) -> DOMString {
|
||||
self.value.clone()
|
||||
self.value.as_slice().to_string()
|
||||
}
|
||||
|
||||
fn SetValue(&mut self, value: DOMString) {
|
||||
let owner = self.owner.get().root();
|
||||
let value = owner.deref().parse_attribute(
|
||||
&self.namespace, self.deref().local_name.as_slice(), value);
|
||||
self.set_value(ReplacedAttr, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ DOMInterfaces = {
|
|||
'DOMException': {},
|
||||
'DOMImplementation': {},
|
||||
'DOMParser': {},
|
||||
'DOMTokenList': {},
|
||||
'Element': {},
|
||||
'Event': {},
|
||||
'EventHandler': {},
|
||||
|
|
103
src/components/script/dom/domtokenlist.rs
Normal file
103
src/components/script/dom/domtokenlist.rs
Normal file
|
@ -0,0 +1,103 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom::attr::{Attr, TokenListAttrValue};
|
||||
use dom::bindings::codegen::Bindings::DOMTokenListBinding;
|
||||
use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable};
|
||||
use dom::bindings::utils::{Reflector, Reflectable, reflect_dom_object};
|
||||
use dom::element::{Element, AttributeHandlers};
|
||||
use dom::node::window_from_node;
|
||||
|
||||
use servo_util::namespace::Null;
|
||||
use servo_util::str::DOMString;
|
||||
|
||||
#[deriving(Encodable)]
|
||||
pub struct DOMTokenList {
|
||||
reflector_: Reflector,
|
||||
element: JS<Element>,
|
||||
local_name: &'static str,
|
||||
}
|
||||
|
||||
impl DOMTokenList {
|
||||
pub fn new_inherited(element: &JSRef<Element>,
|
||||
local_name: &'static str) -> DOMTokenList {
|
||||
DOMTokenList {
|
||||
reflector_: Reflector::new(),
|
||||
element: JS::from_rooted(element.clone()),
|
||||
local_name: local_name,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(element: &JSRef<Element>,
|
||||
local_name: &'static str) -> Temporary<DOMTokenList> {
|
||||
let window = window_from_node(element).root();
|
||||
reflect_dom_object(box DOMTokenList::new_inherited(element, local_name),
|
||||
&*window, DOMTokenListBinding::Wrap)
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflectable for DOMTokenList {
|
||||
fn reflector<'a>(&'a self) -> &'a Reflector {
|
||||
&self.reflector_
|
||||
}
|
||||
|
||||
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
|
||||
&mut self.reflector_
|
||||
}
|
||||
}
|
||||
|
||||
trait PrivateDOMTokenListHelpers {
|
||||
fn attribute(&self) -> Option<Temporary<Attr>>;
|
||||
}
|
||||
|
||||
impl<'a> PrivateDOMTokenListHelpers for JSRef<'a, DOMTokenList> {
|
||||
fn attribute(&self) -> Option<Temporary<Attr>> {
|
||||
let element = self.element.root();
|
||||
element.deref().get_attribute(Null, self.local_name)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DOMTokenListMethods {
|
||||
fn Length(&self) -> u32;
|
||||
fn Item(&self, index: u32) -> Option<DOMString>;
|
||||
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<DOMString>;
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#domtokenlist
|
||||
impl<'a> DOMTokenListMethods for JSRef<'a, DOMTokenList> {
|
||||
// http://dom.spec.whatwg.org/#dom-domtokenlist-length
|
||||
fn Length(&self) -> u32 {
|
||||
let attribute = self.attribute().root();
|
||||
match attribute {
|
||||
Some(attribute) => {
|
||||
match *attribute.deref().value() {
|
||||
TokenListAttrValue(_, ref indexes) => indexes.len() as u32,
|
||||
_ => fail!("Expected a TokenListAttrValue"),
|
||||
}
|
||||
}
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-domtokenlist-item
|
||||
fn Item(&self, index: u32) -> Option<DOMString> {
|
||||
let attribute = self.attribute().root();
|
||||
attribute.and_then(|attribute| {
|
||||
match *attribute.deref().value() {
|
||||
TokenListAttrValue(ref value, ref indexes) => {
|
||||
indexes.as_slice().get(index as uint).map(|&(start, end)| {
|
||||
value.as_slice().slice(start, end).to_string()
|
||||
})
|
||||
},
|
||||
_ => fail!("Expected a TokenListAttrValue"),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<DOMString> {
|
||||
let item = self.Item(index);
|
||||
*found = item.is_some();
|
||||
item
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
//! Element nodes.
|
||||
|
||||
use dom::attr::{Attr, ReplacedAttr, FirstSetAttr, AttrMethods};
|
||||
use dom::attr::{AttrValue, StringAttrValue, UIntAttrValue};
|
||||
use dom::attrlist::AttrList;
|
||||
use dom::bindings::codegen::Bindings::ElementBinding;
|
||||
use dom::bindings::codegen::InheritTypes::{ElementDerived, NodeCast};
|
||||
|
@ -17,6 +18,7 @@ use dom::bindings::utils::{QName, Name, InvalidXMLName, xml_name_type};
|
|||
use dom::clientrect::ClientRect;
|
||||
use dom::clientrectlist::ClientRectList;
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::domtokenlist::DOMTokenList;
|
||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||
use dom::htmlcollection::HTMLCollection;
|
||||
use dom::htmlserializer::serialize;
|
||||
|
@ -43,7 +45,8 @@ pub struct Element {
|
|||
pub prefix: Option<DOMString>,
|
||||
pub attrs: RefCell<Vec<JS<Attr>>>,
|
||||
pub style_attribute: Traceable<RefCell<Option<style::PropertyDeclarationBlock>>>,
|
||||
pub attr_list: Cell<Option<JS<AttrList>>>
|
||||
pub attr_list: Cell<Option<JS<AttrList>>>,
|
||||
class_list: Cell<Option<JS<DOMTokenList>>>,
|
||||
}
|
||||
|
||||
impl ElementDerived for EventTarget {
|
||||
|
@ -151,6 +154,7 @@ impl Element {
|
|||
prefix: prefix,
|
||||
attrs: RefCell::new(vec!()),
|
||||
attr_list: Cell::new(None),
|
||||
class_list: Cell::new(None),
|
||||
style_attribute: Traceable::new(RefCell::new(None)),
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +180,7 @@ impl RawLayoutElementHelpers for Element {
|
|||
name == (*attr).local_name.as_slice() && (*attr).namespace == *namespace
|
||||
}).map(|attr| {
|
||||
let attr = attr.unsafe_get();
|
||||
mem::transmute((*attr).value.as_slice())
|
||||
mem::transmute((*attr).value_ref())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -223,11 +227,12 @@ pub trait AttributeHandlers {
|
|||
fn set_attribute_from_parser(&self, local_name: DOMString,
|
||||
value: DOMString, namespace: Namespace,
|
||||
prefix: Option<DOMString>);
|
||||
fn set_attribute(&self, namespace: Namespace, name: DOMString,
|
||||
value: DOMString) -> ErrorResult;
|
||||
fn do_set_attribute(&self, local_name: DOMString, value: DOMString,
|
||||
fn set_attribute(&self, name: &str, value: AttrValue);
|
||||
fn do_set_attribute(&self, local_name: DOMString, value: AttrValue,
|
||||
name: DOMString, namespace: Namespace,
|
||||
prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool);
|
||||
fn parse_attribute(&self, namespace: &Namespace, local_name: &str,
|
||||
value: DOMString) -> AttrValue;
|
||||
|
||||
fn remove_attribute(&self, namespace: Namespace, name: DOMString) -> ErrorResult;
|
||||
fn notify_attribute_changed(&self, local_name: DOMString);
|
||||
|
@ -238,6 +243,8 @@ pub trait AttributeHandlers {
|
|||
fn set_url_attribute(&self, name: &str, value: DOMString);
|
||||
fn get_string_attribute(&self, name: &str) -> DOMString;
|
||||
fn set_string_attribute(&self, name: &str, value: DOMString);
|
||||
fn set_tokenlist_attribute(&self, name: &str, value: DOMString);
|
||||
fn get_uint_attribute(&self, name: &str) -> u32;
|
||||
fn set_uint_attribute(&self, name: &str, value: u32);
|
||||
}
|
||||
|
||||
|
@ -264,37 +271,23 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
|||
None => local_name.clone(),
|
||||
Some(ref prefix) => format!("{:s}:{:s}", *prefix, local_name),
|
||||
};
|
||||
let value = self.parse_attribute(&namespace, local_name.as_slice(), value);
|
||||
self.do_set_attribute(local_name, value, name, namespace, prefix, |_| false)
|
||||
}
|
||||
|
||||
fn set_attribute(&self, namespace: Namespace, name: DOMString,
|
||||
value: DOMString) -> ErrorResult {
|
||||
let (prefix, local_name) = get_attribute_parts(name.clone());
|
||||
match prefix {
|
||||
Some(ref prefix_str) => {
|
||||
if namespace == namespace::Null ||
|
||||
("xml" == prefix_str.as_slice() && namespace != namespace::XML) ||
|
||||
("xmlns" == prefix_str.as_slice() && namespace != namespace::XMLNS) {
|
||||
return Err(NamespaceError);
|
||||
}
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
fn set_attribute(&self, name: &str, value: AttrValue) {
|
||||
assert!(name == name.to_ascii_lower().as_slice());
|
||||
assert!(!name.contains(":"));
|
||||
|
||||
let node: &JSRef<Node> = NodeCast::from_ref(self);
|
||||
node.wait_until_safe_to_modify_dom();
|
||||
|
||||
let position: |&JSRef<Attr>| -> bool =
|
||||
if self.html_element_in_html_document() {
|
||||
|attr| attr.deref().local_name.as_slice().eq_ignore_ascii_case(local_name.as_slice())
|
||||
} else {
|
||||
|attr| attr.deref().local_name == local_name
|
||||
};
|
||||
self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, position);
|
||||
Ok(())
|
||||
self.do_set_attribute(name.to_string(), value, name.to_string(),
|
||||
namespace::Null, None,
|
||||
|attr| attr.deref().local_name.as_slice() == name);
|
||||
}
|
||||
|
||||
fn do_set_attribute(&self, local_name: DOMString, value: DOMString,
|
||||
fn do_set_attribute(&self, local_name: DOMString, value: AttrValue,
|
||||
name: DOMString, namespace: Namespace,
|
||||
prefix: Option<DOMString>, cb: |&JSRef<Attr>| -> bool) {
|
||||
let idx = self.deref().attrs.borrow().iter()
|
||||
|
@ -314,6 +307,16 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
|||
self.deref().attrs.borrow().get(idx).root().set_value(set_type, value);
|
||||
}
|
||||
|
||||
fn parse_attribute(&self, namespace: &Namespace, local_name: &str,
|
||||
value: DOMString) -> AttrValue {
|
||||
if *namespace == namespace::Null {
|
||||
vtable_for(NodeCast::from_ref(self))
|
||||
.parse_plain_attribute(local_name, value)
|
||||
} else {
|
||||
StringAttrValue(value)
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_attribute(&self, namespace: Namespace, name: DOMString) -> ErrorResult {
|
||||
let (_, local_name) = get_attribute_parts(name.clone());
|
||||
|
||||
|
@ -379,12 +382,30 @@ impl<'a> AttributeHandlers for JSRef<'a, Element> {
|
|||
}
|
||||
fn set_string_attribute(&self, name: &str, value: DOMString) {
|
||||
assert!(name == name.to_ascii_lower().as_slice());
|
||||
assert!(self.set_attribute(Null, name.to_string(), value).is_ok());
|
||||
self.set_attribute(name, StringAttrValue(value));
|
||||
}
|
||||
|
||||
fn set_tokenlist_attribute(&self, name: &str, value: DOMString) {
|
||||
assert!(name == name.to_ascii_lower().as_slice());
|
||||
self.set_attribute(name, AttrValue::from_tokenlist(value));
|
||||
}
|
||||
|
||||
fn get_uint_attribute(&self, name: &str) -> u32 {
|
||||
assert!(name == name.to_ascii_lower().as_slice());
|
||||
let attribute = self.get_attribute(Null, name).root();
|
||||
match attribute {
|
||||
Some(attribute) => {
|
||||
match *attribute.deref().value() {
|
||||
UIntAttrValue(_, value) => value,
|
||||
_ => fail!("Expected a UIntAttrValue"),
|
||||
}
|
||||
}
|
||||
None => 0,
|
||||
}
|
||||
}
|
||||
fn set_uint_attribute(&self, name: &str, value: u32) {
|
||||
assert!(name == name.to_ascii_lower().as_slice());
|
||||
assert!(self.set_attribute(Null, name.to_string(), value.to_str()).is_ok());
|
||||
self.set_attribute(name, UIntAttrValue(value.to_str(), value));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -413,6 +434,7 @@ pub trait ElementMethods {
|
|||
fn SetId(&self, id: DOMString);
|
||||
fn ClassName(&self) -> DOMString;
|
||||
fn SetClassName(&self, class: DOMString);
|
||||
fn ClassList(&self) -> Temporary<DOMTokenList>;
|
||||
fn Attributes(&self) -> Temporary<AttrList>;
|
||||
fn GetAttribute(&self, name: DOMString) -> Option<DOMString>;
|
||||
fn GetAttributeNS(&self, namespace: Option<DOMString>, local_name: DOMString) -> Option<DOMString>;
|
||||
|
@ -480,7 +502,19 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
|
||||
// http://dom.spec.whatwg.org/#dom-element-classname
|
||||
fn SetClassName(&self, class: DOMString) {
|
||||
self.set_string_attribute("class", class);
|
||||
self.set_tokenlist_attribute("class", class);
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-element-classlist
|
||||
fn ClassList(&self) -> Temporary<DOMTokenList> {
|
||||
match self.class_list.get() {
|
||||
Some(class_list) => Temporary::new(class_list),
|
||||
None => {
|
||||
let class_list = DOMTokenList::new(self, "class").root();
|
||||
self.class_list.assign(Some(class_list.deref().clone()));
|
||||
Temporary::from_rooted(&*class_list)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// http://dom.spec.whatwg.org/#dom-element-attributes
|
||||
|
@ -543,6 +577,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
};
|
||||
|
||||
// Step 3-5.
|
||||
let value = self.parse_attribute(&namespace::Null, name.as_slice(), value);
|
||||
self.do_set_attribute(name.clone(), value, name.clone(), namespace::Null, None, |attr| {
|
||||
attr.deref().name == name
|
||||
});
|
||||
|
@ -604,6 +639,7 @@ impl<'a> ElementMethods for JSRef<'a, Element> {
|
|||
}
|
||||
|
||||
// Step 9.
|
||||
let value = self.parse_attribute(&namespace, local_name.as_slice(), value);
|
||||
self.do_set_attribute(local_name.clone(), value, name, namespace.clone(), prefix, |attr| {
|
||||
attr.deref().local_name == local_name &&
|
||||
attr.deref().namespace == namespace
|
||||
|
@ -795,6 +831,13 @@ impl<'a> VirtualMethods for JSRef<'a, Element> {
|
|||
self.notify_attribute_changed(name);
|
||||
}
|
||||
|
||||
fn parse_plain_attribute(&self, name: &str, value: DOMString) -> AttrValue {
|
||||
match name {
|
||||
"class" => AttrValue::from_tokenlist(value),
|
||||
_ => self.super_type().unwrap().parse_plain_attribute(name, value),
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_to_tree(&self) {
|
||||
match self.super_type() {
|
||||
Some(ref s) => s.bind_to_tree(),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom::attr::AttrValue;
|
||||
use dom::bindings::codegen::Bindings::HTMLImageElementBinding;
|
||||
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast, HTMLElementCast, HTMLImageElementDerived};
|
||||
use dom::bindings::js::{JS, JSRef, Temporary};
|
||||
|
@ -199,7 +200,7 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> {
|
|||
|
||||
fn Hspace(&self) -> u32 {
|
||||
let element: &JSRef<Element> = ElementCast::from_ref(self);
|
||||
from_str::<u32>(element.get_string_attribute("hspace").as_slice()).unwrap()
|
||||
element.get_uint_attribute("hspace")
|
||||
}
|
||||
|
||||
fn SetHspace(&self, hspace: u32) {
|
||||
|
@ -209,7 +210,7 @@ impl<'a> HTMLImageElementMethods for JSRef<'a, HTMLImageElement> {
|
|||
|
||||
fn Vspace(&self) -> u32 {
|
||||
let element: &JSRef<Element> = ElementCast::from_ref(self);
|
||||
from_str::<u32>(element.get_string_attribute("vspace").as_slice()).unwrap()
|
||||
element.get_uint_attribute("vspace")
|
||||
}
|
||||
|
||||
fn SetVspace(&self, vspace: u32) {
|
||||
|
@ -267,4 +268,11 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> {
|
|||
self.update_image(None, None);
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_plain_attribute(&self, name: &str, value: DOMString) -> AttrValue {
|
||||
match name {
|
||||
"width" | "height" | "hspace" | "vspace" => AttrValue::from_u32(value, 0),
|
||||
_ => self.super_type().unwrap().parse_plain_attribute(name, value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ fn serialize_attr(attr: &JSRef<Attr>, html: &mut String) {
|
|||
html.push_str(attr.deref().name.as_slice());
|
||||
};
|
||||
html.push_str("=\"");
|
||||
escape(attr.deref().value.as_slice(), true, html);
|
||||
escape(attr.deref().value_ref(), true, html);
|
||||
html.push_char('"');
|
||||
}
|
||||
|
||||
|
|
|
@ -1327,7 +1327,7 @@ impl Node {
|
|||
for attr in node_elem.deref().attrs.borrow().iter().map(|attr| attr.root()) {
|
||||
copy_elem.deref().attrs.borrow_mut().push_unrooted(
|
||||
&Attr::new(&*window,
|
||||
attr.deref().local_name.clone(), attr.deref().value.clone(),
|
||||
attr.deref().local_name.clone(), attr.deref().value().clone(),
|
||||
attr.deref().name.clone(), attr.deref().namespace.clone(),
|
||||
attr.deref().prefix.clone(), copy_elem));
|
||||
}
|
||||
|
@ -1815,7 +1815,7 @@ impl<'a> NodeMethods for JSRef<'a, Node> {
|
|||
other_element.attrs.borrow().iter().map(|attr| attr.root()).any(|other_attr| {
|
||||
(attr.namespace == other_attr.namespace) &&
|
||||
(attr.local_name == other_attr.local_name) &&
|
||||
(attr.value == other_attr.value)
|
||||
(attr.deref().value_ref() == other_attr.deref().value_ref())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom::attr::{AttrValue, StringAttrValue};
|
||||
use dom::bindings::codegen::InheritTypes::ElementCast;
|
||||
use dom::bindings::codegen::InheritTypes::HTMLAnchorElementCast;
|
||||
use dom::bindings::codegen::InheritTypes::HTMLBodyElementCast;
|
||||
|
@ -50,6 +51,15 @@ pub trait VirtualMethods {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the right AttrValue variant for the attribute with name `name`
|
||||
/// on this element.
|
||||
fn parse_plain_attribute(&self, name: &str, value: DOMString) -> AttrValue {
|
||||
match self.super_type() {
|
||||
Some(ref s) => s.parse_plain_attribute(name, value),
|
||||
_ => StringAttrValue(value),
|
||||
}
|
||||
}
|
||||
|
||||
/// Called when a Node is appended to a tree that is part of a Document.
|
||||
fn bind_to_tree(&self) {
|
||||
match self.super_type() {
|
||||
|
|
15
src/components/script/dom/webidls/DOMTokenList.webidl
Normal file
15
src/components/script/dom/webidls/DOMTokenList.webidl
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// http://dom.spec.whatwg.org/#domtokenlist
|
||||
interface DOMTokenList {
|
||||
readonly attribute unsigned long length;
|
||||
getter DOMString? item(unsigned long index);
|
||||
//boolean contains(DOMString token);
|
||||
//void add(DOMString... tokens);
|
||||
//void remove(DOMString... tokens);
|
||||
//boolean toggle(DOMString token, optional boolean force);
|
||||
//stringifier;
|
||||
};
|
|
@ -28,8 +28,8 @@ interface Element : Node {
|
|||
attribute DOMString id;
|
||||
[Pure]
|
||||
attribute DOMString className;
|
||||
/*[Constant]
|
||||
readonly attribute DOMTokenList? classList;*/
|
||||
[Constant]
|
||||
readonly attribute DOMTokenList classList;
|
||||
|
||||
[Constant]
|
||||
readonly attribute AttrList attributes;
|
||||
|
|
|
@ -78,6 +78,7 @@ pub mod dom {
|
|||
pub mod domexception;
|
||||
pub mod domimplementation;
|
||||
pub mod domparser;
|
||||
pub mod domtokenlist;
|
||||
pub mod element;
|
||||
pub mod event;
|
||||
pub mod eventdispatcher;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue