Make Element.set_attr require an AbstractNode so we can always downcast.

This commit is contained in:
Josh Matthews 2013-09-12 14:36:06 -07:00
parent 72b6978b24
commit a410651fba
6 changed files with 42 additions and 19 deletions

View file

@ -171,7 +171,7 @@ DOMInterfaces = {
'Element': { 'Element': {
'nativeType': 'AbstractNode<ScriptView>', 'nativeType': 'AbstractNode<ScriptView>',
'pointerType': '', 'pointerType': '',
'needsAbstract': ['getClientRects', 'getBoundingClientRect'] 'needsAbstract': ['getClientRects', 'getBoundingClientRect', 'setAttribute']
}, },
'Event': { 'Event': {
@ -588,7 +588,7 @@ addHTMLElement('HTMLHeadElement')
addHTMLElement('HTMLHeadingElement') addHTMLElement('HTMLHeadingElement')
addHTMLElement('HTMLHtmlElement') addHTMLElement('HTMLHtmlElement')
addHTMLElement('HTMLHRElement') addHTMLElement('HTMLHRElement')
addHTMLElement('HTMLIFrameElement') addHTMLElement('HTMLIFrameElement', needsAbstract=['sandbox'])
addHTMLElement('HTMLImageElement', needsAbstract=['width', 'height']) addHTMLElement('HTMLImageElement', needsAbstract=['width', 'height'])
addHTMLElement('HTMLInputElement') addHTMLElement('HTMLInputElement')
addHTMLElement('HTMLLabelElement') addHTMLElement('HTMLLabelElement')

View file

@ -3140,8 +3140,8 @@ class CGSetterCall(CGPerSignatureCall):
A class to generate a native object setter call for a particular IDL A class to generate a native object setter call for a particular IDL
setter. setter.
""" """
def __init__(self, argType, nativeMethodName, descriptor, attr): def __init__(self, argsPre, argType, nativeMethodName, descriptor, attr):
CGPerSignatureCall.__init__(self, None, [], CGPerSignatureCall.__init__(self, None, argsPre,
[FakeArgument(argType, attr)], [FakeArgument(argType, attr)],
nativeMethodName, False, descriptor, attr, nativeMethodName, False, descriptor, attr,
setter=True) setter=True)
@ -3357,9 +3357,16 @@ class CGSpecializedSetter(CGAbstractExternMethod):
def definition_body(self): def definition_body(self):
name = self.attr.identifier.name name = self.attr.identifier.name
nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name)) nativeName = "Set" + MakeNativeName(self.descriptor.binaryNames.get(name, name))
return CGWrapper(CGIndenter(CGSetterCall(self.attr.type, nativeName, argsPre = []
extraPre = ''
if name in self.descriptor.needsAbstract:
abstractName = re.sub(r'<\w+>', '', self.descriptor.nativeType)
extraPre = ' let abstract_this = %s::from_box(this);\n' % abstractName
argsPre = ['abstract_this']
return CGWrapper(CGIndenter(CGSetterCall(argsPre, self.attr.type, nativeName,
self.descriptor, self.attr)), self.descriptor, self.attr)),
pre=" let obj = (*obj.unnamed);\n" + pre=extraPre +
" let obj = (*obj.unnamed);\n" +
" let this = &mut (*this).payload;\n").define() " let this = &mut (*this).payload;\n").define()
def infallibleForMember(member, type, descriptorProvider): def infallibleForMember(member, type, descriptorProvider):

View file

@ -139,7 +139,10 @@ impl<'self> Element {
return None; return None;
} }
pub fn set_attr(&mut self, raw_name: &DOMString, raw_value: &DOMString) { pub fn set_attr(&mut self,
abstract_self: AbstractNode<ScriptView>,
raw_name: &DOMString,
raw_value: &DOMString) {
let name = raw_name.to_str(); let name = raw_name.to_str();
let value_cell = Cell::new(raw_value.to_str()); let value_cell = Cell::new(raw_value.to_str());
let mut found = false; let mut found = false;
@ -163,8 +166,8 @@ impl<'self> Element {
//XXXjdm We really need something like a vtable so we can call AfterSetAttr. //XXXjdm We really need something like a vtable so we can call AfterSetAttr.
// This hardcoding is awful. // This hardcoding is awful.
if self.parent.abstract.unwrap().is_iframe_element() { if abstract_self.is_iframe_element() {
do self.parent.abstract.unwrap().with_mut_iframe_element |iframe| { do abstract_self.with_mut_iframe_element |iframe| {
iframe.AfterSetAttr(raw_name, raw_value); iframe.AfterSetAttr(raw_name, raw_value);
} }
} }
@ -208,8 +211,12 @@ impl Element {
null_string null_string
} }
pub fn SetAttribute(&mut self, name: &DOMString, value: &DOMString, _rv: &mut ErrorResult) { pub fn SetAttribute(&mut self,
self.set_attr(name, value); abstract_self: AbstractNode<ScriptView>,
name: &DOMString,
value: &DOMString,
_rv: &mut ErrorResult) {
self.set_attr(abstract_self, name, value);
} }
pub fn SetAttributeNS(&self, _namespace: &DOMString, _localname: &DOMString, _value: &DOMString, _rv: &mut ErrorResult) { pub fn SetAttributeNS(&self, _namespace: &DOMString, _localname: &DOMString, _value: &DOMString, _rv: &mut ErrorResult) {

View file

@ -5,6 +5,7 @@
use dom::bindings::utils::{DOMString, null_string, ErrorResult, str}; use dom::bindings::utils::{DOMString, null_string, ErrorResult, str};
use dom::document::AbstractDocument; use dom::document::AbstractDocument;
use dom::htmlelement::HTMLElement; use dom::htmlelement::HTMLElement;
use dom::node::{AbstractNode, ScriptView};
use dom::windowproxy::WindowProxy; use dom::windowproxy::WindowProxy;
use geom::size::Size2D; use geom::size::Size2D;
use geom::rect::Rect; use geom::rect::Rect;
@ -79,13 +80,13 @@ impl HTMLIFrameElement {
pub fn SetName(&mut self, _name: &DOMString, _rv: &mut ErrorResult) { pub fn SetName(&mut self, _name: &DOMString, _rv: &mut ErrorResult) {
} }
pub fn Sandbox(&self) -> DOMString { pub fn Sandbox(&self, _abstract_self: AbstractNode<ScriptView>) -> DOMString {
self.parent.parent.GetAttribute(&str(~"sandbox")) self.parent.parent.GetAttribute(&str(~"sandbox"))
} }
pub fn SetSandbox(&mut self, sandbox: &DOMString) { pub fn SetSandbox(&mut self, abstract_self: AbstractNode<ScriptView>, sandbox: &DOMString) {
let mut rv = Ok(()); let mut rv = Ok(());
self.parent.parent.SetAttribute(&str(~"sandbox"), sandbox, &mut rv); self.parent.parent.SetAttribute(abstract_self, &str(~"sandbox"), sandbox, &mut rv);
} }
pub fn AfterSetAttr(&mut self, name: &DOMString, value: &DOMString) { pub fn AfterSetAttr(&mut self, name: &DOMString, value: &DOMString) {

View file

@ -79,9 +79,13 @@ impl HTMLImageElement {
} }
} }
pub fn SetWidth(&mut self, width: u32, _rv: &mut ErrorResult) { pub fn SetWidth(&mut self,
abstract_self: AbstractNode<ScriptView>,
width: u32,
_rv: &mut ErrorResult) {
let node = &mut self.parent.parent; let node = &mut self.parent.parent;
node.set_attr(&str(~"width"), node.set_attr(abstract_self,
&str(~"width"),
&str(width.to_str())); &str(width.to_str()));
} }
@ -114,9 +118,13 @@ impl HTMLImageElement {
} }
} }
pub fn SetHeight(&mut self, height: u32, _rv: &mut ErrorResult) { pub fn SetHeight(&mut self,
abstract_self: AbstractNode<ScriptView>,
height: u32,
_rv: &mut ErrorResult) {
let node = &mut self.parent.parent; let node = &mut self.parent.parent;
node.set_attr(&str(~"height"), node.set_attr(abstract_self,
&str(~"height"),
&str(height.to_str())); &str(height.to_str()));
} }

View file

@ -375,7 +375,7 @@ pub fn parse_html(cx: *JSContext,
debug!("-- attach attrs"); debug!("-- attach attrs");
do node.as_mut_element |element| { do node.as_mut_element |element| {
for attr in tag.attributes.iter() { for attr in tag.attributes.iter() {
element.set_attr(&str(attr.name.clone()), &str(attr.value.clone())); element.set_attr(node, &str(attr.name.clone()), &str(attr.value.clone()));
} }
} }